summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-02-28 18:30:10 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-03-02 14:41:18 +0100
commit1e546d46fba261a3e3b6c4ea43f4a7e16aa64c5b (patch)
tree566838781d0413a56a4331876692dcc2b7594ce1
parentf3226b945964b18e5cba9df7f7cc1347229ed9a8 (diff)
downloadmullvadvpn-1e546d46fba261a3e3b6c4ea43f4a7e16aa64c5b.tar.xz
mullvadvpn-1e546d46fba261a3e3b6c4ea43f4a7e16aa64c5b.zip
Move the openvpn functions to the top
-rw-r--r--talpid_openvpn_plugin/src/ffi/consts.rs1
-rw-r--r--talpid_openvpn_plugin/src/ffi/mod.rs148
-rw-r--r--talpid_openvpn_plugin/src/ffi/structs.rs49
-rw-r--r--talpid_openvpn_plugin/src/lib.rs101
-rw-r--r--talpid_openvpn_plugin/src/processing.rs29
5 files changed, 168 insertions, 160 deletions
diff --git a/talpid_openvpn_plugin/src/ffi/consts.rs b/talpid_openvpn_plugin/src/ffi/consts.rs
index 81fe134b9e..34f6f6c44b 100644
--- a/talpid_openvpn_plugin/src/ffi/consts.rs
+++ b/talpid_openvpn_plugin/src/ffi/consts.rs
@@ -44,6 +44,7 @@ impl OpenVpnPluginEvent {
// Accept (success) or decline (error) an operation, such as incoming client connection attempt.
pub const OPENVPN_PLUGIN_FUNC_SUCCESS: c_int = 0;
pub const OPENVPN_PLUGIN_FUNC_ERROR: c_int = 1;
+#[allow(dead_code)]
pub const OPENVPN_PLUGIN_FUNC_DEFERRED: c_int = 2;
diff --git a/talpid_openvpn_plugin/src/ffi/mod.rs b/talpid_openvpn_plugin/src/ffi/mod.rs
index 17d904c38b..fe046cde67 100644
--- a/talpid_openvpn_plugin/src/ffi/mod.rs
+++ b/talpid_openvpn_plugin/src/ffi/mod.rs
@@ -2,155 +2,21 @@
// the original declarations of these structs and functions along with documentation for them:
// https://github.com/OpenVPN/openvpn/blob/master/include/openvpn-plugin.h.in
-use std::os::raw::{c_char, c_int, c_uint, c_void};
+use std::os::raw::c_int;
+mod consts;
+pub use self::consts::*;
-#[allow(dead_code)]
-pub mod consts;
-use self::consts::*;
+mod structs;
+pub use self::structs::*;
-mod parse;
+pub mod parse;
-error_chain!{
- errors {
- HandlerInitFailed {
- description("Unable to initialize EventProcessor")
- }
- InvalidEventType {
- description("Invalid event type constant")
- }
- ParseEnvFailed {
- description("Unable to parse environment variables from OpenVPN")
- }
- }
-}
-
-/// All the OpenVPN events this plugin will register for listening to. Edit this variable to change
-/// events.
-pub static INTERESTING_EVENTS: &'static [OpenVpnPluginEvent] = &[OpenVpnPluginEvent::Up,
- OpenVpnPluginEvent::RoutePredown];
-
-
-/// Struct sent to `openvpn_plugin_open_v3` containing input values.
-#[repr(C)]
-pub struct openvpn_plugin_args_open_in {
- type_mask: c_int,
- argv: *const *const c_char,
- envp: *const *const c_char,
- callbacks: *const c_void,
- ssl_api: ovpnSSLAPI,
- ovpn_version: *const c_char,
- ovpn_version_major: c_uint,
- ovpn_version_minor: c_uint,
- ovpn_version_patch: *const c_char,
-}
-
-#[allow(dead_code)]
-#[repr(C)]
-enum ovpnSSLAPI {
- SSLAPI_NONE,
- SSLAPI_OPENSSL,
- SSLAPI_MBEDTLS,
-}
-
-/// Struct used for returning values from `openvpn_plugin_open_v3` to OpenVPN.
-#[repr(C)]
-pub struct openvpn_plugin_args_open_return {
- type_mask: c_int,
- handle: *const c_void,
- return_list: *const c_void,
-}
-
-/// Struct sent to `openvpn_plugin_func_v3` containing input values.
-#[repr(C)]
-pub struct openvpn_plugin_args_func_in {
- event_type: c_int,
- argv: *const *const c_char,
- envp: *const *const c_char,
- handle: *const c_void,
- per_client_context: *const c_void,
- current_cert_depth: c_int,
- current_cert: *const c_void,
-}
-
-/// Struct used for returning values from `openvpn_plugin_func_v3` to OpenVPN.
-#[repr(C)]
-pub struct openvpn_plugin_args_func_return {
- return_list: *const c_void,
-}
-
-
-/// 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 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,
- _args: *const openvpn_plugin_args_open_in,
- 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;
- }
- 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) {
- 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
-/// `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 {
- // TODO(linus): Add logging of errors
- match openvpn_plugin_func_v3_internal(args) {
- Ok(_) => OPENVPN_PLUGIN_FUNC_SUCCESS,
- Err(_) => 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)?;
- 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(())
-}
/// Translates a collection of `OpenVpnPluginEvent` instances into a bitmask in the format OpenVPN
/// expects it.
-fn events_to_bitmask(events: &[OpenVpnPluginEvent]) -> c_int {
+pub fn events_to_bitmask(events: &[OpenVpnPluginEvent]) -> c_int {
let mut bitmask: c_int = 0;
for event in events {
bitmask |= 1 << (*event as i32);
diff --git a/talpid_openvpn_plugin/src/ffi/structs.rs b/talpid_openvpn_plugin/src/ffi/structs.rs
new file mode 100644
index 0000000000..325f312974
--- /dev/null
+++ b/talpid_openvpn_plugin/src/ffi/structs.rs
@@ -0,0 +1,49 @@
+use std::os::raw::{c_char, c_int, c_uint, c_void};
+
+/// Struct sent to `openvpn_plugin_open_v3` containing input values.
+#[repr(C)]
+pub struct openvpn_plugin_args_open_in {
+ type_mask: c_int,
+ argv: *const *const c_char,
+ envp: *const *const c_char,
+ callbacks: *const c_void,
+ ssl_api: ovpnSSLAPI,
+ ovpn_version: *const c_char,
+ ovpn_version_major: c_uint,
+ ovpn_version_minor: c_uint,
+ ovpn_version_patch: *const c_char,
+}
+
+#[allow(dead_code)]
+#[repr(C)]
+enum ovpnSSLAPI {
+ SSLAPI_NONE,
+ SSLAPI_OPENSSL,
+ SSLAPI_MBEDTLS,
+}
+
+/// Struct used for returning values from `openvpn_plugin_open_v3` to OpenVPN.
+#[repr(C)]
+pub struct openvpn_plugin_args_open_return {
+ pub type_mask: c_int,
+ pub handle: *const c_void,
+ return_list: *const c_void,
+}
+
+/// Struct sent to `openvpn_plugin_func_v3` containing input values.
+#[repr(C)]
+pub struct openvpn_plugin_args_func_in {
+ pub event_type: c_int,
+ argv: *const *const c_char,
+ pub envp: *const *const c_char,
+ pub handle: *const c_void,
+ per_client_context: *const c_void,
+ current_cert_depth: c_int,
+ current_cert: *const c_void,
+}
+
+/// Struct used for returning values from `openvpn_plugin_func_v3` to OpenVPN.
+#[repr(C)]
+pub struct openvpn_plugin_args_func_return {
+ return_list: *const c_void,
+}
diff --git a/talpid_openvpn_plugin/src/lib.rs b/talpid_openvpn_plugin/src/lib.rs
index 49e4ce031c..cff9430d61 100644
--- a/talpid_openvpn_plugin/src/lib.rs
+++ b/talpid_openvpn_plugin/src/lib.rs
@@ -8,38 +8,101 @@ extern crate error_chain;
#[macro_use]
extern crate assert_matches;
-use std::collections::HashMap;
-
+use std::os::raw::{c_int, c_void};
mod ffi;
+mod processing;
-/// 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::OpenVpnPluginEvent;
+use processing::EventProcessor;
-use ffi::consts::OpenVpnPluginEvent;
+error_chain!{
+ errors {
+ InitHandleFailed {
+ description("Unable to initialize event processor")
+ }
+ InvalidEventType {
+ description("Invalid event type constant")
+ }
+ ParseEnvFailed {
+ description("Unable to parse environment variables from OpenVPN")
+ }
+ }
+}
-error_chain!{}
+/// All the OpenVPN events this plugin will register for listening to. Edit this variable to change
+/// events.
+pub static INTERESTING_EVENTS: &'static [OpenVpnPluginEvent] = &[OpenVpnPluginEvent::Up,
+ OpenVpnPluginEvent::RoutePredown];
-/// Struct processing OpenVPN events and notifies listeners over IPC
-struct EventProcessor;
-impl EventProcessor {
- pub fn new() -> Result<EventProcessor> {
- Ok(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 ffi::openvpn_plugin_args_open_in,
+ retptr: *mut ffi::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(_) => ffi::OPENVPN_PLUGIN_FUNC_SUCCESS,
+ Err(_) => ffi::OPENVPN_PLUGIN_FUNC_ERROR,
}
+}
- 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);
+fn openvpn_plugin_open_v3_internal(retptr: *mut ffi::openvpn_plugin_args_open_return)
+ -> Result<()> {
+ let handle = Box::new(EventProcessor::new().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;
}
+ 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) {
+ 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) };
}
-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!");
+
+/// 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 ffi::openvpn_plugin_args_func_in,
+ _retptr: *const ffi::openvpn_plugin_args_func_return)
+ -> c_int {
+ // TODO(linus): Add logging of errors
+ match openvpn_plugin_func_v3_internal(args) {
+ Ok(_) => ffi::OPENVPN_PLUGIN_FUNC_SUCCESS,
+ Err(_) => ffi::OPENVPN_PLUGIN_FUNC_ERROR,
}
}
+
+fn openvpn_plugin_func_v3_internal(args: *const ffi::openvpn_plugin_args_func_in) -> Result<()> {
+ let event_type = unsafe { (*args).event_type };
+ let event = OpenVpnPluginEvent::from_int(event_type).chain_err(|| ErrorKind::InvalidEventType)?;
+ let env = unsafe { ffi::parse::env((*args).envp) }.chain_err(|| ErrorKind::ParseEnvFailed)?;
+ println!("openvpn_plugin_func_v3({:?})", event);
+
+ 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/processing.rs b/talpid_openvpn_plugin/src/processing.rs
new file mode 100644
index 0000000000..405e279896
--- /dev/null
+++ b/talpid_openvpn_plugin/src/processing.rs
@@ -0,0 +1,29 @@
+
+
+use ffi::OpenVpnPluginEvent;
+use std::collections::HashMap;
+
+
+error_chain!{}
+
+
+/// Struct processing OpenVPN events and notifies listeners over IPC
+pub 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!");
+ }
+}