diff options
Diffstat (limited to 'talpid-openvpn-plugin/src/processing.rs')
| -rw-r--r-- | talpid-openvpn-plugin/src/processing.rs | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/talpid-openvpn-plugin/src/processing.rs b/talpid-openvpn-plugin/src/processing.rs index 99533945ed..66d009b44f 100644 --- a/talpid-openvpn-plugin/src/processing.rs +++ b/talpid-openvpn-plugin/src/processing.rs @@ -1,42 +1,55 @@ use openvpn_plugin; use std::collections::HashMap; -use std::sync::Mutex; -use talpid_ipc::WsIpcClient; + +extern crate futures; + +use jsonrpc_client_core::{Future, Result as ClientResult, Transport}; +use jsonrpc_client_ipc::IpcTransport; +use tokio_core::reactor::Core; use super::Arguments; error_chain! { errors { - AuthDenied { - description("Failed to authenticate with Talpid IPC server") - } IpcSendingError { description("Failed while sending an event over the IPC channel") } + + Shutdown { + description("Connection is shut down") + } + } } /// Struct processing OpenVPN events and notifies listeners over IPC pub struct EventProcessor { - ipc_client: Mutex<WsIpcClient>, + ipc_client: EventProxy, + client_stop: ::std::sync::mpsc::Receiver<ClientResult<()>>, + core: Core, } impl EventProcessor { - pub fn new(arguments: &Arguments) -> Result<EventProcessor> { + pub fn new(arguments: Arguments) -> Result<EventProcessor> { trace!("Creating EventProcessor"); - let mut ipc_client = WsIpcClient::connect(&arguments.server_id) - .chain_err(|| "Unable to create IPC client")?; + let core = Core::new().chain_err(|| "Unable to initialize Tokio Core")?; + let handle = core.handle(); + let (client, client_handle) = IpcTransport::new(&arguments.ipc_socket_path, &handle) + .chain_err(|| "Unable to create IPC transport")? + .into_client(); - trace!("Authenticating EventProcessor"); - match ipc_client.call("authenticate", &[&arguments.credentials]) { - Ok(true) => trace!("Credentials accepted"), - Ok(false) => bail!(ErrorKind::AuthDenied), - Err(error) => bail!(Error::with_chain(error, ErrorKind::AuthDenied)), - } + let (tx, client_stop) = ::std::sync::mpsc::channel(); + + let client_future = client.then(move |result| tx.send(result)).map_err(|_| ()); + handle.spawn(client_future); + + let ipc_client = EventProxy::new(client_handle); Ok(EventProcessor { - ipc_client: Mutex::new(ipc_client), + ipc_client, + client_stop, + core, }) } @@ -46,11 +59,25 @@ impl EventProcessor { env: HashMap<String, String>, ) -> Result<()> { trace!("Processing \"{:?}\" event", event); - self.ipc_client - .lock() - .expect("a thread panicked while using the RPC client in the OpenVPN plugin") - .call("openvpn_event", &(event, env)) - .map(|_: Option<()>| ()) - .chain_err(|| ErrorKind::IpcSendingError) + let call_future = self + .ipc_client + .openvpn_event(event, env) + .map_err(|e| Error::with_chain(e, ErrorKind::IpcSendingError)); + self.core.run(call_future)?; + self.check_client_status() + } + + fn check_client_status(&mut self) -> Result<()> { + use std::sync::mpsc::TryRecvError::*; + match self.client_stop.try_recv() { + Err(Empty) => Ok(()), + Err(Disconnected) => Err(ErrorKind::Shutdown.into()), + Ok(Ok(_)) => Err(ErrorKind::Shutdown.into()), + Ok(Err(e)) => Err(Error::with_chain(e, ErrorKind::IpcSendingError)), + } } } + +jsonrpc_client!(pub struct EventProxy { + pub fn openvpn_event(&mut self, event: openvpn_plugin::types::OpenVpnPluginEvent, env: HashMap<String, String>) -> Future<()>; +}); |
