summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--talpid_openvpn_plugin/Cargo.toml3
-rw-r--r--talpid_openvpn_plugin/src/ffi/structs.rs2
-rw-r--r--talpid_openvpn_plugin/src/lib.rs32
-rw-r--r--talpid_openvpn_plugin/src/processing.rs30
5 files changed, 52 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 63d6b95fa8..ab64cc5d51 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,6 +6,7 @@ dependencies = [
"env_logger 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "talpid_ipc 0.1.0",
]
[[package]]
diff --git a/talpid_openvpn_plugin/Cargo.toml b/talpid_openvpn_plugin/Cargo.toml
index 79c0f387cb..ca870cb1cb 100644
--- a/talpid_openvpn_plugin/Cargo.toml
+++ b/talpid_openvpn_plugin/Cargo.toml
@@ -12,5 +12,8 @@ error-chain = "0.8"
log = "0.3"
env_logger = "0.4"
+[dependencies.talpid_ipc]
+path = "../talpid_ipc"
+
[dev-dependencies]
assert_matches = "1.0"
diff --git a/talpid_openvpn_plugin/src/ffi/structs.rs b/talpid_openvpn_plugin/src/ffi/structs.rs
index ba5bc2b343..b80f7ae2a2 100644
--- a/talpid_openvpn_plugin/src/ffi/structs.rs
+++ b/talpid_openvpn_plugin/src/ffi/structs.rs
@@ -4,7 +4,7 @@ use std::os::raw::{c_char, c_int, c_uint, c_void};
#[repr(C)]
pub struct openvpn_plugin_args_open_in {
type_mask: c_int,
- argv: *const *const c_char,
+ pub argv: *const *const c_char,
envp: *const *const c_char,
callbacks: *const c_void,
ssl_api: ovpnSSLAPI,
diff --git a/talpid_openvpn_plugin/src/lib.rs b/talpid_openvpn_plugin/src/lib.rs
index 4eb2a0f336..9a9aea8c6c 100644
--- a/talpid_openvpn_plugin/src/lib.rs
+++ b/talpid_openvpn_plugin/src/lib.rs
@@ -9,6 +9,8 @@ extern crate env_logger;
#[macro_use]
extern crate assert_matches;
+extern crate talpid_ipc;
+
use std::os::raw::{c_int, c_void};
mod ffi;
@@ -29,6 +31,12 @@ error_chain!{
ParseEnvFailed {
description("Unable to parse environment variables from OpenVPN")
}
+ ParseArgsFailed {
+ description("Unable to parse arguments from OpenVPN")
+ }
+ EventProcessingFailed {
+ description("Failed to process the event")
+ }
}
}
@@ -45,13 +53,13 @@ pub static INTERESTING_EVENTS: &'static [OpenVpnPluginEvent] = &[OpenVpnPluginEv
/// plugin.
#[no_mangle]
pub extern "C" fn openvpn_plugin_open_v3(_version: c_int,
- _args: *const ffi::openvpn_plugin_args_open_in,
+ args: *const ffi::openvpn_plugin_args_open_in,
retptr: *mut ffi::openvpn_plugin_args_open_return)
-> c_int {
if init_logger().is_err() {
return ffi::OPENVPN_PLUGIN_FUNC_ERROR;
}
- match openvpn_plugin_open_v3_internal(retptr) {
+ match openvpn_plugin_open_v3_internal(args, retptr) {
Ok(_) => ffi::OPENVPN_PLUGIN_FUNC_SUCCESS,
Err(e) => {
log_error("Unable to initialize plugin", &e);
@@ -60,19 +68,31 @@ pub extern "C" fn openvpn_plugin_open_v3(_version: c_int,
}
}
-fn openvpn_plugin_open_v3_internal(retptr: *mut ffi::openvpn_plugin_args_open_return)
+fn openvpn_plugin_open_v3_internal(args: *const ffi::openvpn_plugin_args_open_in,
+ retptr: *mut ffi::openvpn_plugin_args_open_return)
-> Result<()> {
debug!("Initializing plugin");
- let handle = Box::new(EventProcessor::new().chain_err(|| ErrorKind::InitHandleFailed)?);
+ let core_server_id = parse_args(args)?;
+ let processor = EventProcessor::new(core_server_id).chain_err(|| ErrorKind::InitHandleFailed)?;
unsafe {
(*retptr).type_mask = ffi::events_to_bitmask(INTERESTING_EVENTS);
// Converting the handle into a raw pointer will make it escape Rust deallocation. See
// `openvpn_plugin_close_v1` for deallocation.
- (*retptr).handle = Box::into_raw(handle) as *const c_void;
+ (*retptr).handle = Box::into_raw(Box::new(processor)) as *const c_void;
}
Ok(())
}
+fn parse_args(args: *const ffi::openvpn_plugin_args_open_in) -> Result<talpid_ipc::IpcServerId> {
+ let mut args_iter = unsafe { ffi::parse::string_array((*args).argv) }
+ .chain_err(|| ErrorKind::ParseArgsFailed)?
+ .into_iter();
+ let _plugin_path = args_iter.next();
+ let core_server_id = args_iter.next()
+ .ok_or(ErrorKind::Msg("No core server id given as first argument".to_owned()))?;
+ Ok(core_server_id)
+}
+
/// Called by OpenVPN just before the plugin is unloaded. Should correctly close the plugin and
/// deallocate any `handle` initialized by the plugin in `openvpn_plugin_open_v3`
@@ -108,7 +128,7 @@ fn openvpn_plugin_func_v3_internal(args: *const ffi::openvpn_plugin_args_func_in
let env = unsafe { ffi::parse::env((*args).envp) }.chain_err(|| ErrorKind::ParseEnvFailed)?;
let mut handle = unsafe { Box::from_raw((*args).handle as *mut EventProcessor) };
- handle.process_event(event, env);
+ handle.process_event(event, env).chain_err(|| ErrorKind::EventProcessingFailed)?;
// Convert the handle back to a raw pointer to not deallocate it when we return.
Box::into_raw(handle);
diff --git a/talpid_openvpn_plugin/src/processing.rs b/talpid_openvpn_plugin/src/processing.rs
index 337030744e..586d0574ec 100644
--- a/talpid_openvpn_plugin/src/processing.rs
+++ b/talpid_openvpn_plugin/src/processing.rs
@@ -1,24 +1,36 @@
-
-
use ffi::OpenVpnPluginEvent;
+
use std::collections::HashMap;
+use talpid_ipc::{IpcClient, IpcServerId};
-error_chain!{}
+error_chain! {
+ errors {
+ IpcSendingError {
+ description("Failed while sending an event over the IPC channel")
+ }
+ }
+}
/// Struct processing OpenVPN events and notifies listeners over IPC
-pub struct EventProcessor;
+pub struct EventProcessor {
+ ipc_client: IpcClient<HashMap<String, String>>,
+}
impl EventProcessor {
- pub fn new() -> Result<EventProcessor> {
+ pub fn new(server_id: IpcServerId) -> Result<EventProcessor> {
debug!("Creating EventProcessor");
- Ok(EventProcessor)
+ let ipc_client = IpcClient::new(server_id);
+ Ok(EventProcessor { ipc_client: ipc_client })
}
- pub fn process_event(&mut self, event: OpenVpnPluginEvent, _env: HashMap<String, String>) {
- // TODO(linus): This is where we should send events to core.
- trace!("Hello from EventProcessor: {:?}", event);
+ pub fn process_event(&mut self,
+ event: OpenVpnPluginEvent,
+ env: HashMap<String, String>)
+ -> Result<()> {
+ trace!("Processing \"{:?}\" event", event);
+ self.ipc_client.send(&env).chain_err(|| ErrorKind::IpcSendingError)
}
}