summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-03-02 11:06:14 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-03-02 11:06:14 +0100
commit459196bb22c11ca2943546743f2e0c02d8ee5e05 (patch)
treecd899d310420e5132b4e90efaa6b0134412b166e
parent0fdc6ef08987eb237aba81aee589b35fd8efbb2b (diff)
parent9585f99eff441650ae1144ac18a368df38fa5e70 (diff)
downloadmullvadvpn-459196bb22c11ca2943546743f2e0c02d8ee5e05.tar.xz
mullvadvpn-459196bb22c11ca2943546743f2e0c02d8ee5e05.zip
Merge branch 'plugin-handle'
-rw-r--r--talpid_openvpn_plugin/src/ffi/mod.rs33
-rw-r--r--talpid_openvpn_plugin/src/lib.rs30
2 files changed, 59 insertions, 4 deletions
diff --git a/talpid_openvpn_plugin/src/ffi/mod.rs b/talpid_openvpn_plugin/src/ffi/mod.rs
index 726bcae403..17d904c38b 100644
--- a/talpid_openvpn_plugin/src/ffi/mod.rs
+++ b/talpid_openvpn_plugin/src/ffi/mod.rs
@@ -13,6 +13,9 @@ mod parse;
error_chain!{
errors {
+ HandlerInitFailed {
+ description("Unable to initialize EventProcessor")
+ }
InvalidEventType {
description("Invalid event type constant")
}
@@ -78,8 +81,8 @@ pub struct openvpn_plugin_args_func_return {
/// Called by OpenVPN when the plugin is first loaded.
-/// Used to register which events the plugin wants to listen to (`type_mask`). Can also return an
-/// arbitrary object inside `handle` that will then be passed to all subsequent calls to the
+/// Used to register which events the plugin wants to listen to (`args.type_mask`). Can also set an
+/// arbitrary object 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,
@@ -87,17 +90,33 @@ pub extern "C" fn openvpn_plugin_open_v3(_version: c_int,
retptr: *mut openvpn_plugin_args_open_return)
-> c_int {
println!("openvpn_plugin_open_v3()");
+ // TODO(linus): Add logging of errors
+ match openvpn_plugin_open_v3_internal(retptr) {
+ Ok(_) => OPENVPN_PLUGIN_FUNC_SUCCESS,
+ Err(_) => OPENVPN_PLUGIN_FUNC_ERROR,
+ }
+}
+
+fn openvpn_plugin_open_v3_internal(retptr: *mut openvpn_plugin_args_open_return) -> Result<()> {
+ let handle = Box::new(::EventProcessor::new().chain_err(|| ErrorKind::HandlerInitFailed)?);
unsafe {
(*retptr).type_mask = 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;
}
- OPENVPN_PLUGIN_FUNC_SUCCESS
+ Ok(())
}
+
/// 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) {
+pub extern "C" fn openvpn_plugin_close_v1(handle: *const c_void) {
println!("openvpn_plugin_close_v1()");
+ // 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
@@ -118,6 +137,12 @@ fn openvpn_plugin_func_v3_internal(args: *const openvpn_plugin_args_func_in) ->
let event_type = unsafe { (*args).event_type };
let event = OpenVpnPluginEvent::from_int(event_type).chain_err(|| ErrorKind::InvalidEventType)?;
println!("openvpn_plugin_func_v3({:?})", event);
+ let env = unsafe { 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);
+ // Convert the handle back to a raw pointer to not deallocate it when we return.
+ Box::into_raw(handle);
Ok(())
}
diff --git a/talpid_openvpn_plugin/src/lib.rs b/talpid_openvpn_plugin/src/lib.rs
index d2d1ea9d74..49e4ce031c 100644
--- a/talpid_openvpn_plugin/src/lib.rs
+++ b/talpid_openvpn_plugin/src/lib.rs
@@ -8,8 +8,38 @@ extern crate error_chain;
#[macro_use]
extern crate assert_matches;
+use std::collections::HashMap;
+
+
mod ffi;
/// Publicly export the functions making up the public interface of the plugin. These are the C FFI
/// functions called by OpenVPN.
pub use ffi::{openvpn_plugin_open_v3, openvpn_plugin_close_v1, openvpn_plugin_func_v3};
+
+use ffi::consts::OpenVpnPluginEvent;
+
+
+error_chain!{}
+
+
+/// Struct processing OpenVPN events and notifies listeners over IPC
+struct EventProcessor;
+
+impl EventProcessor {
+ pub fn new() -> Result<EventProcessor> {
+ Ok(EventProcessor)
+ }
+
+ pub fn process_event(&mut self, event: OpenVpnPluginEvent, env: HashMap<String, String>) {
+ // TODO(linus): This is where we should send events to core.
+ println!("Hello from EventProcessor: {:?}", event);
+ }
+}
+
+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.
+ println!("Dropping EventProcessor!");
+ }
+}