summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-07-18 20:20:38 +0200
committerLinus Färnstrand <linus@mullvad.net>2017-07-19 14:53:24 +0200
commit5debb39be683a7b17efc0bae7066c82988576b99 (patch)
tree7eb45d5211ecfee7e8a6711d43a7bef478f0612c
parent3ed79a04900596968495303e068b9e80ef73bbbe (diff)
downloadmullvadvpn-5debb39be683a7b17efc0bae7066c82988576b99.tar.xz
mullvadvpn-5debb39be683a7b17efc0bae7066c82988576b99.zip
Update openvpn plugin to use openvpn-plugin lib
-rw-r--r--talpid-openvpn-plugin/Cargo.toml2
-rw-r--r--talpid-openvpn-plugin/src/lib.rs131
-rw-r--r--talpid-openvpn-plugin/src/processing.rs17
3 files changed, 38 insertions, 112 deletions
diff --git a/talpid-openvpn-plugin/Cargo.toml b/talpid-openvpn-plugin/Cargo.toml
index c2ae39430c..023c886567 100644
--- a/talpid-openvpn-plugin/Cargo.toml
+++ b/talpid-openvpn-plugin/Cargo.toml
@@ -12,5 +12,5 @@ error-chain = "0.10"
log = "0.3"
env_logger = "0.4"
+openvpn-plugin = { version = "0.1", features = ["serialize", "log"] }
talpid-ipc = { path = "../talpid-ipc" }
-openvpn-ffi = { path = "../openvpn-ffi" }
diff --git a/talpid-openvpn-plugin/src/lib.rs b/talpid-openvpn-plugin/src/lib.rs
index 55102d111c..3d7efda8e0 100644
--- a/talpid-openvpn-plugin/src/lib.rs
+++ b/talpid-openvpn-plugin/src/lib.rs
@@ -4,16 +4,15 @@ extern crate error_chain;
extern crate log;
extern crate env_logger;
-extern crate openvpn_ffi;
+#[macro_use]
+extern crate openvpn_plugin;
extern crate talpid_ipc;
-use std::os::raw::{c_int, c_void};
+use openvpn_plugin::types::{OpenVpnPluginEvent, SuccessType};
+use std::collections::HashMap;
+use std::ffi::CString;
mod processing;
-
-use openvpn_ffi::{OPENVPN_PLUGIN_FUNC_ERROR, OPENVPN_PLUGIN_FUNC_SUCCESS, OpenVpnPluginEvent,
- openvpn_plugin_args_func_in, openvpn_plugin_args_func_return,
- openvpn_plugin_args_open_in, openvpn_plugin_args_open_return};
use processing::EventProcessor;
@@ -43,117 +42,51 @@ error_chain!{
pub static INTERESTING_EVENTS: &'static [OpenVpnPluginEvent] =
&[OpenVpnPluginEvent::Up, OpenVpnPluginEvent::RoutePredown];
+openvpn_plugin!(
+ ::openvpn_open,
+ ::openvpn_close,
+ ::openvpn_event,
+ ::EventProcessor
+);
-/// Called by OpenVPN when the plugin is first loaded.
-/// Used to register which events the plugin wants to listen to (`args.type_mask`). Can also set an
-/// arbitrary pointer inside `args.handle` that will then be passed to all subsequent calls to the
-/// plugin.
-#[no_mangle]
-pub extern "C" fn openvpn_plugin_open_v3(_version: c_int,
- args: *const openvpn_plugin_args_open_in,
- retptr: *mut openvpn_plugin_args_open_return)
- -> c_int {
- if init_logger().is_err() {
- return OPENVPN_PLUGIN_FUNC_ERROR;
- }
- match openvpn_plugin_open_v3_internal(args, retptr) {
- Ok(_) => OPENVPN_PLUGIN_FUNC_SUCCESS,
- Err(e) => {
- log_error("Unable to initialize plugin", &e);
- OPENVPN_PLUGIN_FUNC_ERROR
- }
- }
-}
-
-fn openvpn_plugin_open_v3_internal(args: *const openvpn_plugin_args_open_in,
- retptr: *mut openvpn_plugin_args_open_return)
- -> Result<()> {
+fn openvpn_open(args: &[CString],
+ _env: &HashMap<CString, CString>)
+ -> Result<(Vec<OpenVpnPluginEvent>, EventProcessor)> {
+ env_logger::init().chain_err(|| "Failed to bootstrap logging system")?;
debug!("Initializing plugin");
+
let core_server_id = parse_args(args)?;
+ info!("Connecting back to talpid core at {}", core_server_id);
let processor = EventProcessor::new(core_server_id).chain_err(|| ErrorKind::InitHandleFailed)?;
- unsafe {
- (*retptr).type_mask = openvpn_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(Box::new(processor)) as *const c_void;
- }
- Ok(())
+
+ Ok((INTERESTING_EVENTS.to_vec(), processor))
}
-fn parse_args(args: *const openvpn_plugin_args_open_in) -> Result<talpid_ipc::IpcServerId> {
- let mut args_iter = unsafe { openvpn_ffi::parse::string_array((*args).argv) }
+fn parse_args(args: &[CString]) -> Result<talpid_ipc::IpcServerId> {
+ let mut args_iter = openvpn_plugin::ffi::parse::string_array_utf8(args)
.chain_err(|| ErrorKind::ParseArgsFailed)?
.into_iter();
let _plugin_path = args_iter.next();
- let core_server_id: String = args_iter.next()
+ let core_server_id: talpid_ipc::IpcServerId = args_iter.next()
.ok_or_else(|| 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`
-#[no_mangle]
-pub extern "C" fn openvpn_plugin_close_v1(handle: *const c_void) {
+fn openvpn_close(_handle: EventProcessor) {
debug!("Unloading plugin");
- // IMPORTANT: Bring the handle object back from a raw pointer. This will cause the handle
- // object to be properly deallocated right here.
- let _ = unsafe { Box::from_raw(handle as *mut EventProcessor) };
}
-
-/// Called by OpenVPN for each `OPENVPN_PLUGIN_*` event that it registered for in
-/// `openvpn_plugin_open_v3`
-#[no_mangle]
-pub extern "C" fn openvpn_plugin_func_v3(_version: c_int,
- args: *const openvpn_plugin_args_func_in,
- _retptr: *const openvpn_plugin_args_func_return)
- -> c_int {
- match openvpn_plugin_func_v3_internal(args) {
- Ok(_) => OPENVPN_PLUGIN_FUNC_SUCCESS,
- Err(e) => {
- log_error("Error while processing event", &e);
- OPENVPN_PLUGIN_FUNC_ERROR
- }
- }
-}
-
-fn openvpn_plugin_func_v3_internal(args: *const openvpn_plugin_args_func_in) -> Result<()> {
- let event_type = unsafe { (*args).event_type };
- let event = OpenVpnPluginEvent::from_int(event_type).chain_err(|| ErrorKind::InvalidEventType)?;
+fn openvpn_event(event: OpenVpnPluginEvent,
+ _args: &[CString],
+ env: &HashMap<CString, CString>,
+ handle: &mut EventProcessor)
+ -> Result<SuccessType> {
debug!("Received event: {:?}", event);
- let env = unsafe { openvpn_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).chain_err(|| ErrorKind::EventProcessingFailed)?;
- // Convert the handle back to a raw pointer to not deallocate it when we return.
- Box::into_raw(handle);
-
- Ok(())
-}
+ let parsed_env = openvpn_plugin::ffi::parse::env_utf8(env)
+ .chain_err(|| ErrorKind::ParseEnvFailed)?;
-
-pub fn init_logger() -> ::std::result::Result<(), ()> {
- env_logger::init().or_else(
- |e| {
- use std::io::Write;
- let mut stderr = ::std::io::stderr();
- writeln!(&mut stderr, "Unable to initialize logging: {}", e)
- .expect("Unable to write to stderr");
- Err(())
- },
- )
-}
-
-pub fn log_error(msg: &str, error: &Error) {
- error!("{}", msg);
- for e in error.iter() {
- error!("caused by: {}", e);
- }
- // When running with RUST_BACKTRACE=1, print backtrace.
- if let Some(backtrace) = error.backtrace() {
- error!("backtrace: {:?}", backtrace);
- }
+ handle.process_event(event, parsed_env).chain_err(|| ErrorKind::EventProcessingFailed)?;
+ Ok(SuccessType::Success)
}
diff --git a/talpid-openvpn-plugin/src/processing.rs b/talpid-openvpn-plugin/src/processing.rs
index e33097c633..5f3c8e4afd 100644
--- a/talpid-openvpn-plugin/src/processing.rs
+++ b/talpid-openvpn-plugin/src/processing.rs
@@ -1,5 +1,5 @@
-use openvpn_ffi;
-
+use openvpn_plugin;
+use std::collections::HashMap;
use talpid_ipc::{IpcServerId, WsIpcClient};
error_chain! {
@@ -18,14 +18,14 @@ pub struct EventProcessor {
impl EventProcessor {
pub fn new(server_id: IpcServerId) -> Result<EventProcessor> {
- debug!("Creating EventProcessor");
+ trace!("Creating EventProcessor");
let ipc_client = WsIpcClient::new(server_id).chain_err(|| "Unable to create IPC client")?;
Ok(EventProcessor { ipc_client })
}
pub fn process_event(&mut self,
- event: openvpn_ffi::OpenVpnPluginEvent,
- env: openvpn_ffi::OpenVpnEnv)
+ event: openvpn_plugin::types::OpenVpnPluginEvent,
+ env: HashMap<String, String>)
-> Result<()> {
trace!("Processing \"{:?}\" event", event);
self.ipc_client
@@ -34,10 +34,3 @@ impl EventProcessor {
.chain_err(|| ErrorKind::IpcSendingError)
}
}
-
-impl Drop for EventProcessor {
- fn drop(&mut self) {
- // TODO(linus): If we need, this is where we send some shutdown event or similar to core.
- debug!("Dropping EventProcessor");
- }
-}