summaryrefslogtreecommitdiffhomepage
path: root/talpid-openvpn-plugin/src/processing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'talpid-openvpn-plugin/src/processing.rs')
-rw-r--r--talpid-openvpn-plugin/src/processing.rs71
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<()>;
+});