summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock14
-rw-r--r--openvpn_ffi/src/lib.rs5
-rw-r--r--openvpn_ffi/src/parse.rs2
-rw-r--r--talpid_core/Cargo.toml2
-rw-r--r--talpid_core/src/lib.rs7
-rw-r--r--talpid_core/src/process/openvpn.rs3
-rw-r--r--talpid_core/src/tunnel/mod.rs2
-rw-r--r--talpid_core/src/tunnel/openvpn.rs79
8 files changed, 105 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index abbcc79fb3..e6c6467ec7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -218,7 +218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jsonrpc-core"
version = "7.0.0"
-source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#098cbc458d3f53b0ffa6a044674cf4379ec77ba2"
+source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#6d4061524f7760347dd04fb49e7471eaac26e976"
dependencies = [
"futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -230,7 +230,7 @@ dependencies = [
[[package]]
name = "jsonrpc-macros"
version = "7.0.0"
-source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#098cbc458d3f53b0ffa6a044674cf4379ec77ba2"
+source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#6d4061524f7760347dd04fb49e7471eaac26e976"
dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
"jsonrpc-pubsub 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
@@ -240,7 +240,7 @@ dependencies = [
[[package]]
name = "jsonrpc-pubsub"
version = "7.0.0"
-source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#098cbc458d3f53b0ffa6a044674cf4379ec77ba2"
+source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#6d4061524f7760347dd04fb49e7471eaac26e976"
dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -250,7 +250,7 @@ dependencies = [
[[package]]
name = "jsonrpc-server-utils"
version = "7.0.0"
-source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#098cbc458d3f53b0ffa6a044674cf4379ec77ba2"
+source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#6d4061524f7760347dd04fb49e7471eaac26e976"
dependencies = [
"globset 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
@@ -262,7 +262,7 @@ dependencies = [
[[package]]
name = "jsonrpc-ws-server"
version = "7.0.0"
-source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#098cbc458d3f53b0ffa6a044674cf4379ec77ba2"
+source = "git+https://github.com/faern/jsonrpc?branch=bind-zero#6d4061524f7760347dd04fb49e7471eaac26e976"
dependencies = [
"jsonrpc-core 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
"jsonrpc-server-utils 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
@@ -595,6 +595,8 @@ dependencies = [
"assert_matches 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jsonrpc-core 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
+ "jsonrpc-macros 7.0.0 (git+https://github.com/faern/jsonrpc?branch=bind-zero)",
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"openvpn_ffi 0.1.0",
"talpid_ipc 0.1.0",
@@ -745,7 +747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws"
version = "0.7.1"
-source = "git+https://github.com/faern/ws-rs?branch=arbitrary-handshake-responses#3a8c5ae37e0ff5aab4c0ad656a160eb0bf78f5c1"
+source = "git+https://github.com/faern/ws-rs?branch=arbitrary-handshake-responses#25fba2181064f987a748ca90d65c604ffcc86dd6"
dependencies = [
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/openvpn_ffi/src/lib.rs b/openvpn_ffi/src/lib.rs
index 00e0d58031..934eb091df 100644
--- a/openvpn_ffi/src/lib.rs
+++ b/openvpn_ffi/src/lib.rs
@@ -12,6 +12,7 @@ extern crate serde_derive;
extern crate assert_matches;
+use std::collections::HashMap;
use std::os::raw::c_int;
mod structs;
@@ -29,6 +30,10 @@ error_chain!{
}
+/// Type definition for environment variables from OpenVPN
+pub type OpenVpnEnv = HashMap<String, String>;
+
+
// Return values. Returned from the plugin to OpenVPN to indicate success or failure. Can also
// Accept (success) or decline (error) an operation, such as incoming client connection attempt.
pub const OPENVPN_PLUGIN_FUNC_SUCCESS: c_int = 0;
diff --git a/openvpn_ffi/src/parse.rs b/openvpn_ffi/src/parse.rs
index 787883fd70..6d0c42c06f 100644
--- a/openvpn_ffi/src/parse.rs
+++ b/openvpn_ffi/src/parse.rs
@@ -52,7 +52,7 @@ pub unsafe fn string_array(mut ptr: *const *const c_char) -> Result<Vec<String>>
/// # Segfaults
///
/// Uses `string_array` internally and will segfault for the same reasons as that function.
-pub unsafe fn env(envptr: *const *const c_char) -> Result<HashMap<String, String>> {
+pub unsafe fn env(envptr: *const *const c_char) -> Result<::OpenVpnEnv> {
let mut map = HashMap::new();
for string in string_array(envptr)? {
let mut iter = string.splitn(2, '=');
diff --git a/talpid_core/Cargo.toml b/talpid_core/Cargo.toml
index c098d204d9..18c998cf93 100644
--- a/talpid_core/Cargo.toml
+++ b/talpid_core/Cargo.toml
@@ -8,6 +8,8 @@ description = "Core backend functionality of the Mullvad VPN client"
duct = "0.8"
error-chain = "0.10"
log = "0.3"
+jsonrpc-core = { git = "https://github.com/faern/jsonrpc", branch = "bind-zero" }
+jsonrpc-macros = { git = "https://github.com/faern/jsonrpc", branch = "bind-zero" }
[dependencies.talpid_ipc]
path = "../talpid_ipc"
diff --git a/talpid_core/src/lib.rs b/talpid_core/src/lib.rs
index 1a10532787..8a053bffa8 100644
--- a/talpid_core/src/lib.rs
+++ b/talpid_core/src/lib.rs
@@ -13,11 +13,18 @@ extern crate log;
#[macro_use]
extern crate error_chain;
+extern crate jsonrpc_core;
+#[macro_use]
+extern crate jsonrpc_macros;
extern crate talpid_ipc;
+extern crate openvpn_ffi;
/// Working with processes.
pub mod process;
/// Network primitives.
pub mod net;
+
+/// Abstracts over different VPN tunnel technologies
+pub mod tunnel;
diff --git a/talpid_core/src/process/openvpn.rs b/talpid_core/src/process/openvpn.rs
index d565b085a8..5d40d8e42c 100644
--- a/talpid_core/src/process/openvpn.rs
+++ b/talpid_core/src/process/openvpn.rs
@@ -6,7 +6,6 @@ use duct;
use net::{RemoteAddr, ToRemoteAddrs};
-use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::fmt;
use std::io;
@@ -127,7 +126,7 @@ fn write_argument(fmt: &mut fmt::Formatter, arg: &str) -> fmt::Result {
/// Possible events from OpenVPN
pub enum OpenVpnEvent {
/// An event from the plugin loaded into OpenVPN.
- PluginEvent(talpid_ipc::Result<(openvpn_ffi::OpenVpnPluginEvent, HashMap<String, String>)>),
+ PluginEvent(talpid_ipc::Result<(openvpn_ffi::OpenVpnPluginEvent, openvpn_ffi::OpenVpnEnv)>),
/// The OpenVPN process exited. Containing the result of waiting for the process.
Shutdown(io::Result<process::ExitStatus>),
}
diff --git a/talpid_core/src/tunnel/mod.rs b/talpid_core/src/tunnel/mod.rs
new file mode 100644
index 0000000000..0b477ca1c4
--- /dev/null
+++ b/talpid_core/src/tunnel/mod.rs
@@ -0,0 +1,2 @@
+/// A module for all OpenVPN related tunnel management.
+pub mod openvpn;
diff --git a/talpid_core/src/tunnel/openvpn.rs b/talpid_core/src/tunnel/openvpn.rs
new file mode 100644
index 0000000000..35361bb1fd
--- /dev/null
+++ b/talpid_core/src/tunnel/openvpn.rs
@@ -0,0 +1,79 @@
+use jsonrpc_core::{Error, IoHandler};
+use openvpn_ffi::{OpenVpnEnv, OpenVpnPluginEvent};
+
+use talpid_ipc;
+
+/// IPC server for listening to events coming from plugin loaded into OpenVPN.
+pub struct OpenVpnEventDispatcher {
+ server: talpid_ipc::IpcServer,
+}
+
+impl OpenVpnEventDispatcher {
+ /// Construct and start the IPC server with the given event listener callback.
+ pub fn start<L>(on_event: L) -> talpid_ipc::Result<Self>
+ where L: Fn(OpenVpnPluginEvent, OpenVpnEnv) + Send + Sync + 'static
+ {
+ let rpc = OpenVpnEventApiImpl { on_event };
+ let mut io = IoHandler::new();
+ io.extend_with(rpc.to_delegate());
+ let server = talpid_ipc::IpcServer::start(io.into())?;
+ Ok(OpenVpnEventDispatcher { server })
+ }
+
+ /// Returns the local address this server is listening on.
+ pub fn address(&self) -> &str {
+ self.server.address()
+ }
+
+ /// Consumes the server and waits for it to finish.
+ pub fn wait(self) -> talpid_ipc::Result<()> {
+ self.server.wait()
+ }
+}
+
+
+mod api {
+ use super::*;
+ build_rpc_trait! {
+ pub trait OpenVpnEventApi {
+ #[rpc(name = "openvpn_event")]
+ fn openvpn_event(&self, OpenVpnPluginEvent, OpenVpnEnv) -> Result<(), Error>;
+ }
+ }
+}
+use self::api::*;
+
+struct OpenVpnEventApiImpl<L>
+ where L: Fn(OpenVpnPluginEvent, OpenVpnEnv) + Send + Sync + 'static
+{
+ on_event: L,
+}
+
+impl<L> OpenVpnEventApi for OpenVpnEventApiImpl<L>
+ where L: Fn(OpenVpnPluginEvent, OpenVpnEnv) + Send + Sync + 'static
+{
+ fn openvpn_event(&self, event: OpenVpnPluginEvent, env: OpenVpnEnv) -> Result<(), Error> {
+ debug!("OpenVPN event {:?}", event);
+ (self.on_event)(event, env);
+ Ok(())
+ }
+}
+
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ #[ignore]
+ fn openvpn_event_dispatcher_server() {
+ let server = OpenVpnEventDispatcher::start(
+ |event, env| {
+ println!("event: {:?}. env: {:?}", event, env);
+ },
+ )
+ .unwrap();
+ println!("plugin server listening on {}", server.address());
+ server.wait().unwrap();
+ }
+}