summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2019-04-05 20:50:25 +0200
committerLinus Färnstrand <linus@mullvad.net>2019-04-05 20:50:25 +0200
commite2bc2596cf130a26ab143a173b79039f01ddb1d1 (patch)
tree18cca9b3b5ebb07d8b638387740eeae1c091ab9e
parent95eaba22e7cc2f4e7fcf2717258486244e320aa3 (diff)
parente56799a487983124ce3cfcd87a275a67c91c942b (diff)
downloadmullvadvpn-e2bc2596cf130a26ab143a173b79039f01ddb1d1.tar.xz
mullvadvpn-e2bc2596cf130a26ab143a173b79039f01ddb1d1.zip
Merge branch 'eliminate-error-chain-tunnel'
-rw-r--r--Cargo.lock4
-rw-r--r--talpid-core/Cargo.toml1
-rw-r--r--talpid-core/src/dns/linux/static_resolv_conf.rs73
-rw-r--r--talpid-core/src/firewall/linux.rs2
-rw-r--r--talpid-core/src/lib.rs3
-rw-r--r--talpid-core/src/routing/android.rs11
-rw-r--r--talpid-core/src/routing/linux.rs6
-rw-r--r--talpid-core/src/routing/macos.rs6
-rw-r--r--talpid-core/src/routing/mod.rs12
-rw-r--r--talpid-core/src/tunnel/mod.rs66
-rw-r--r--talpid-core/src/tunnel/openvpn.rs156
-rw-r--r--talpid-core/src/tunnel/wireguard/mod.rs74
-rw-r--r--talpid-core/src/tunnel/wireguard/wireguard_go.rs18
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs18
-rw-r--r--talpid-openvpn-plugin/Cargo.toml3
-rw-r--r--talpid-openvpn-plugin/src/lib.rs68
-rw-r--r--talpid-openvpn-plugin/src/processing.rs55
17 files changed, 295 insertions, 281 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a447c280d1..e42c14056b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1984,7 +1984,6 @@ dependencies = [
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"duct 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2047,13 +2046,14 @@ name = "talpid-openvpn-plugin"
version = "0.1.0"
dependencies = [
"env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-client-core 0.5.0 (git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b)",
"jsonrpc-client-ipc 0.5.0 (git+https://github.com/mullvad/jsonrpc-client-rs?rev=68aac55b)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"openvpn-plugin 0.3.0 (git+https://github.com/mullvad/openvpn-plugin-rs?branch=auth-failed-event)",
"talpid-ipc 0.1.0",
+ "talpid-types 0.1.0",
"tokio 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml
index b27c509fcb..5c0e57e557 100644
--- a/talpid-core/Cargo.toml
+++ b/talpid-core/Cargo.toml
@@ -10,7 +10,6 @@ edition = "2018"
atty = "0.2"
derive_more = "0.14"
duct = "0.12"
-error-chain = "0.12"
err-derive = "0.1.5"
futures = "0.1"
jsonrpc-core = { git = "https://github.com/mullvad/jsonrpc", branch = "mullvad-fork" }
diff --git a/talpid-core/src/dns/linux/static_resolv_conf.rs b/talpid-core/src/dns/linux/static_resolv_conf.rs
index 71b6973edf..73c9aa4221 100644
--- a/talpid-core/src/dns/linux/static_resolv_conf.rs
+++ b/talpid-core/src/dns/linux/static_resolv_conf.rs
@@ -1,5 +1,4 @@
use super::RESOLV_CONF_PATH;
-use error_chain::ChainedError;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use parking_lot::Mutex;
use resolv_conf::{Config, ScopedIp};
@@ -9,27 +8,28 @@ use std::{
sync::{mpsc, Arc},
thread,
};
+use talpid_types::ErrorExt;
const RESOLV_CONF_BACKUP_PATH: &str = "/etc/resolv.conf.mullvadbackup";
-error_chain! {
- errors {
- WatchResolvConf {
- description("Failed to watch /etc/resolv.conf for changes")
- }
+pub type Result<T> = std::result::Result<T, Error>;
- WriteResolvConf {
- description("Failed to write to /etc/resolv.conf")
- }
+#[derive(err_derive::Error, Debug)]
+pub enum Error {
+ #[error(display = "Failed to watch /etc/resolv.conf for changes")]
+ WatchResolvConf(#[error(cause)] notify::Error),
- BackupResolvConf {
- description("Failed to create backup of /etc/resolv.conf")
- }
+ #[error(display = "Failed to write to {}", _0)]
+ WriteResolvConf(&'static str, #[error(cause)] io::Error),
- RestoreResolvConf {
- description("Failed to restore /etc/resolv.conf from backup")
- }
- }
+ #[error(display = "Failed to read from {}", _0)]
+ ReadResolvConf(&'static str, #[error(cause)] io::Error),
+
+ #[error(display = "resolv.conf at {} could not be parsed", _0)]
+ ParseError(&'static str, #[error(cause)] resolv_conf::ParseError),
+
+ #[error(display = "Failed to remove stale resolv.conf backup at {}", _0)]
+ RemoveBackup(&'static str, #[error(cause)] io::Error),
}
pub struct StaticResolvConf {
@@ -39,7 +39,7 @@ pub struct StaticResolvConf {
impl StaticResolvConf {
pub fn new() -> Result<Self> {
- restore_from_backup().chain_err(|| ErrorKind::RestoreResolvConf)?;
+ restore_from_backup()?;
let state = Arc::new(Mutex::new(None));
let watcher = DnsWatcher::start(state.clone())?;
@@ -54,8 +54,8 @@ impl StaticResolvConf {
let mut state = self.state.lock();
let new_state = match state.take() {
None => {
- let backup = read_config().chain_err(|| ErrorKind::BackupResolvConf)?;
- write_backup(&backup).chain_err(|| ErrorKind::BackupResolvConf)?;
+ let backup = read_config()?;
+ write_backup(&backup)?;
State {
backup,
@@ -111,11 +111,11 @@ struct DnsWatcher {
impl DnsWatcher {
fn start(state: Arc<Mutex<Option<State>>>) -> Result<Self> {
let (event_tx, event_rx) = mpsc::channel();
- let mut watcher = notify::raw_watcher(event_tx).chain_err(|| ErrorKind::WatchResolvConf)?;
+ let mut watcher = notify::raw_watcher(event_tx).map_err(Error::WatchResolvConf)?;
watcher
.watch(RESOLV_CONF_PATH, RecursiveMode::NonRecursive)
- .chain_err(|| ErrorKind::WatchResolvConf)?;
+ .map_err(Error::WatchResolvConf)?;
thread::spawn(move || Self::event_loop(event_rx, &state));
@@ -127,9 +127,12 @@ impl DnsWatcher {
let mut locked_state = state.lock();
if let Err(error) = Self::update(locked_state.as_mut()) {
- let chained_error = error
- .chain_err(|| "Failed to update DNS state after DNS settings have changed.");
- log::error!("{}", chained_error.display_chain());
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to update DNS state after DNS settings changed"
+ )
+ );
}
}
}
@@ -153,7 +156,7 @@ impl DnsWatcher {
new_config.nameservers.append(&mut state.backup.nameservers);
state.backup = new_config;
- write_backup(&state.backup).chain_err(|| "Failed to update /etc/resolv.conf backup")
+ write_backup(&state.backup)
}
} else {
Ok(())
@@ -162,22 +165,21 @@ impl DnsWatcher {
}
fn read_config() -> Result<Config> {
- let contents =
- fs::read_to_string(RESOLV_CONF_PATH).chain_err(|| "Failed to read /etc/resolv.conf")?;
- let config =
- Config::parse(&contents).chain_err(|| "Failed to parse contents of /etc/resolv.conf")?;
+ let contents = fs::read_to_string(RESOLV_CONF_PATH)
+ .map_err(|e| Error::ReadResolvConf(RESOLV_CONF_PATH, e))?;
+ let config = Config::parse(&contents).map_err(|e| Error::ParseError(RESOLV_CONF_PATH, e))?;
Ok(config)
}
fn write_config(config: &Config) -> Result<()> {
fs::write(RESOLV_CONF_PATH, config.to_string().as_bytes())
- .chain_err(|| ErrorKind::WriteResolvConf)
+ .map_err(|e| Error::WriteResolvConf(RESOLV_CONF_PATH, e))
}
fn write_backup(backup: &Config) -> Result<()> {
fs::write(RESOLV_CONF_BACKUP_PATH, backup.to_string().as_bytes())
- .chain_err(|| "Failed to write to /etc/resolv.conf backup file")
+ .map_err(|e| Error::WriteResolvConf(RESOLV_CONF_BACKUP_PATH, e))
}
fn restore_from_backup() -> Result<()> {
@@ -185,20 +187,17 @@ fn restore_from_backup() -> Result<()> {
Ok(backup) => {
log::info!("Restoring DNS state from backup");
let config = Config::parse(&backup)
- .chain_err(|| "Backup of /etc/resolv.conf could not be parsed")?;
+ .map_err(|e| Error::ParseError(RESOLV_CONF_BACKUP_PATH, e))?;
write_config(&config)?;
fs::remove_file(RESOLV_CONF_BACKUP_PATH)
- .chain_err(|| "Failed to remove stale backup of /etc/resolv.conf")
+ .map_err(|e| Error::RemoveBackup(RESOLV_CONF_BACKUP_PATH, e))
}
Err(ref error) if error.kind() == io::ErrorKind::NotFound => {
log::debug!("No DNS state backup to restore");
Ok(())
}
- Err(error) => Err(Error::with_chain(
- error,
- "Failed to read /etc/resolv.conf backup",
- )),
+ Err(error) => Err(Error::ReadResolvConf(RESOLV_CONF_BACKUP_PATH, error)),
}
}
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 5c8d9e777e..540bdff1ee 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -164,7 +164,7 @@ impl Firewall {
"Expected '{}' netfilter table to be set, but it is not",
expected_table.to_string_lossy()
);
- bail!(Error::NetfilterTableNotSetError)
+ return Err(Error::NetfilterTableNotSetError);
}
}
Ok(())
diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs
index 1499557439..3b2bac9529 100644
--- a/talpid-core/src/lib.rs
+++ b/talpid-core/src/lib.rs
@@ -11,9 +11,6 @@
//! GNU General Public License as published by the Free Software Foundation, either version 3 of
//! the License, or (at your option) any later version.
-#[macro_use]
-extern crate error_chain;
-
/// Misc FFI utilities.
#[cfg(windows)]
#[macro_use]
diff --git a/talpid-core/src/routing/android.rs b/talpid-core/src/routing/android.rs
index fa5c5c8f8e..5c562537f1 100644
--- a/talpid-core/src/routing/android.rs
+++ b/talpid-core/src/routing/android.rs
@@ -7,7 +7,10 @@ use std::{
net::{IpAddr, Ipv4Addr},
};
-error_chain! {}
+/// Stub error type for routing errors on Android.
+#[derive(Debug, err_derive::Error)]
+#[error(display = "Unknown Android routing error")]
+pub struct Error;
pub struct RouteManager;
@@ -18,15 +21,15 @@ impl super::RoutingT for RouteManager {
Ok(RouteManager)
}
- fn add_routes(&mut self, _required_routes: RequiredRoutes) -> Result<()> {
+ fn add_routes(&mut self, _required_routes: RequiredRoutes) -> Result<(), Self::Error> {
Ok(())
}
- fn delete_routes(&mut self) -> Result<()> {
+ fn delete_routes(&mut self) -> Result<(), Self::Error> {
Ok(())
}
- fn get_default_route_node(&mut self) -> Result<IpAddr> {
+ fn get_default_route_node(&mut self) -> Result<IpAddr, Self::Error> {
Ok(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)))
}
}
diff --git a/talpid-core/src/routing/linux.rs b/talpid-core/src/routing/linux.rs
index 73de509a0e..b229b192c2 100644
--- a/talpid-core/src/routing/linux.rs
+++ b/talpid-core/src/routing/linux.rs
@@ -9,20 +9,26 @@ use std::{
pub type Result<T> = std::result::Result<T, Error>;
+/// Errors that can happen in the Linux routing integration
#[derive(err_derive::Error, Debug)]
pub enum Error {
+ /// Failed to add route.
#[error(display = "Failed to add route")]
FailedToAddRoute(#[error(cause)] io::Error),
+ /// Failed to remove route.
#[error(display = "Failed to remove route")]
FailedToRemoveRoute(#[error(cause)] io::Error),
+ /// Error while running "ip route".
#[error(display = "Error while running \"ip route\"")]
FailedToRunIp(#[error(cause)] io::Error),
+ /// No default route in "ip route" output.
#[error(display = "No default route in \"ip route\" output")]
NoDefaultRoute,
+ /// Failed to parse default route as IP.
#[error(display = "Failed to parse default route as IP: {}", _0)]
ParseDefaultRoute(String, #[error(cause)] AddrParseError),
}
diff --git a/talpid-core/src/routing/macos.rs b/talpid-core/src/routing/macos.rs
index d0e9497c1c..722efbb320 100644
--- a/talpid-core/src/routing/macos.rs
+++ b/talpid-core/src/routing/macos.rs
@@ -10,20 +10,26 @@ use std::{
pub type Result<T> = std::result::Result<T, Error>;
+/// Errors that can happen in the macOS routing integration.
#[derive(err_derive::Error, Debug)]
pub enum Error {
+ /// Failed to add route.
#[error(display = "Failed to add route")]
FailedToAddRoute(#[error(cause)] io::Error),
+ /// Failed to remove route.
#[error(display = "Failed to remove route")]
FailedToRemoveRoute(#[error(cause)] io::Error),
+ /// Error while running "ip route".
#[error(display = "Error while running \"ip route\"")]
FailedToRunIp(#[error(cause)] io::Error),
+ /// No default route in "ip route" output.
#[error(display = "No default route in \"ip route\" output")]
NoDefaultRoute,
+ /// Failed to parse default route as IP.
#[error(display = "Failed to parse default route as IP: {}", _0)]
ParseDefaultRoute(String, #[error(cause)] AddrParseError),
}
diff --git a/talpid-core/src/routing/mod.rs b/talpid-core/src/routing/mod.rs
index 612c0b2396..b2e299553f 100644
--- a/talpid-core/src/routing/mod.rs
+++ b/talpid-core/src/routing/mod.rs
@@ -13,6 +13,8 @@ mod imp;
#[path = "android.rs"]
mod imp;
+pub use self::imp::Error;
+
mod subprocess;
/// A single route
@@ -53,24 +55,24 @@ pub struct RouteManager {
impl RouteManager {
/// Creates a new RouteManager.
- pub fn new() -> Result<Self, imp::Error> {
+ pub fn new() -> Result<Self, Error> {
Ok(RouteManager {
inner: imp::RouteManager::new()?,
})
}
/// Set routes in the routing table.
- pub fn add_routes(&mut self, required_routes: RequiredRoutes) -> Result<(), imp::Error> {
+ pub fn add_routes(&mut self, required_routes: RequiredRoutes) -> Result<(), Error> {
self.inner.add_routes(required_routes)
}
/// Remove previously set routes from the routing table.
- pub fn delete_routes(&mut self) -> Result<(), imp::Error> {
+ pub fn delete_routes(&mut self) -> Result<(), Error> {
self.inner.delete_routes()
}
/// Retrieves the gateway for the default route.
- pub fn get_default_route_node(&mut self) -> Result<std::net::IpAddr, imp::Error> {
+ pub fn get_default_route_node(&mut self) -> Result<std::net::IpAddr, Error> {
// use routing::RoutingT;
self.inner.get_default_route_node()
}
@@ -87,7 +89,7 @@ impl Drop for RouteManager {
/// This trait unifies platform specific implementations of route managers
pub trait RoutingT: Sized {
/// Error type of the implementation
- type Error: ::std::error::Error;
+ type Error: std::error::Error;
/// Creates a new router
fn new() -> Result<Self, Self::Error>;
diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs
index 04332908c4..987f80c872 100644
--- a/talpid-core/src/tunnel/mod.rs
+++ b/talpid-core/src/tunnel/mod.rs
@@ -19,36 +19,37 @@ pub mod wireguard;
const OPENVPN_LOG_FILENAME: &str = "openvpn.log";
const WIREGUARD_LOG_FILENAME: &str = "wireguard.log";
+/// Results from operations in the tunnel module.
+pub type Result<T> = std::result::Result<T, Error>;
-error_chain! {
- errors {
- /// Tunnel can't have IPv6 enabled because the system has disabled IPv6 support.
- EnableIpv6Error {
- description("Can't enable IPv6 on tunnel interface because IPv6 is disabled")
- }
- /// Running on an operating system which is not supported yet.
- UnsupportedPlatform {
- description("Tunnel type not supported on this operating system")
- }
- /// Failed to rotate tunnel log file
- RotateLogError {
- description("Failed to rotate tunnel log file")
- }
- /// Failure to build Wireguard configuration.
- WireguardConfigError {
- description("Failed to configure Wireguard with the given parameters")
- }
- }
+/// Errors that can occur in the [`TunnelMonitor`].
+#[derive(err_derive::Error, Debug, derive_more::From)]
+pub enum Error {
+ /// Tunnel can't have IPv6 enabled because the system has disabled IPv6 support.
+ #[error(display = "Can't enable IPv6 on tunnel interface because IPv6 is disabled")]
+ EnableIpv6Error,
- links {
- OpenVpnTunnelMonitoringError(openvpn::Error, openvpn::ErrorKind)
- /// There was an error listening for events from the OpenVPN tunnel
- ;
- WirguardTunnelMonitoringError(wireguard::Error, wireguard::ErrorKind)
- /// There was an error listening for events from the OpenVPN tunnel
- #[cfg(any(target_os = "linux", target_os = "macos"))]
- ;
- }
+ /// Running on an operating system which is not supported yet.
+ #[error(display = "Tunnel type not supported on this operating system")]
+ UnsupportedPlatform,
+
+ /// Failed to rotate tunnel log file
+ #[error(display = "Failed to rotate tunnel log file")]
+ RotateLogError(#[error(cause)] crate::logging::RotateLogError),
+
+ /// Failure to build Wireguard configuration.
+ #[cfg(any(target_os = "linux", target_os = "macos"))]
+ #[error(display = "Failed to configure Wireguard with the given parameters")]
+ WireguardConfigError(#[error(cause)] self::wireguard::config::Error),
+
+ /// There was an error listening for events from the OpenVPN tunnel
+ #[error(display = "Failed while listening for events from the OpenVPN tunnel")]
+ OpenVpnTunnelMonitoringError(#[error(cause)] openvpn::Error),
+
+ /// There was an error listening for events from the Wireguard tunnel
+ #[cfg(any(target_os = "linux", target_os = "macos"))]
+ #[error(display = "Failed while listening for events from the Wireguard tunnel")]
+ WirguardTunnelMonitoringError(#[error(cause)] wireguard::Error),
}
@@ -151,7 +152,7 @@ impl TunnelMonitor {
Self::start_wireguard_tunnel(&config, log_file, on_event)
}
#[cfg(any(windows, target_os = "android"))]
- TunnelParameters::Wireguard(_) => bail!(ErrorKind::UnsupportedPlatform),
+ TunnelParameters::Wireguard(_) => Err(Error::UnsupportedPlatform),
}
}
@@ -164,8 +165,7 @@ impl TunnelMonitor {
where
L: Fn(TunnelEvent) + Send + Sync + Clone + 'static,
{
- let config = wireguard::config::Config::from_parameters(&params)
- .chain_err(|| ErrorKind::WireguardConfigError)?;
+ let config = wireguard::config::Config::from_parameters(&params)?;
let monitor = wireguard::WireguardMonitor::start(
&config,
log.as_ref().map(|p| p.as_path()),
@@ -195,7 +195,7 @@ impl TunnelMonitor {
fn ensure_ipv6_can_be_used_if_enabled(tunnel_options: &GenericTunnelOptions) -> Result<()> {
if tunnel_options.enable_ipv6 && !is_ipv6_enabled_in_os() {
- bail!(ErrorKind::EnableIpv6Error);
+ Err(Error::EnableIpv6Error)
} else {
Ok(())
}
@@ -211,7 +211,7 @@ impl TunnelMonitor {
TunnelParameters::Wireguard(_) => WIREGUARD_LOG_FILENAME,
};
let tunnel_log = log_dir.join(filename);
- logging::rotate_log(&tunnel_log).chain_err(|| ErrorKind::RotateLogError)?;
+ logging::rotate_log(&tunnel_log)?;
Ok(Some(tunnel_log))
} else {
Ok(None)
diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs
index 8e0de74430..d8c97d468a 100644
--- a/talpid-core/src/tunnel/openvpn.rs
+++ b/talpid-core/src/tunnel/openvpn.rs
@@ -28,52 +28,70 @@ use talpid_types::net::openvpn;
#[cfg(target_os = "linux")]
use which;
-error_chain! {
- errors {
- /// Unable to start, wait for or kill the OpenVPN process.
- ChildProcessError(msg: &'static str) {
- description("Unable to start, wait for or kill the OpenVPN process")
- display("OpenVPN process error: {}", msg)
- }
- /// Unable to start or manage the IPC server listening for events from OpenVPN.
- EventDispatcherError {
- description("Unable to start or manage the event dispatcher IPC server")
- }
- #[cfg(windows)]
- /// No TAP adapter was detected
- MissingTapAdapter {
- description("No TAP adapter was detected")
- }
- #[cfg(windows)]
- /// TAP adapter seems to be disabled
- DisabledTapAdapter {
- description("The TAP adapter appears to be disabled")
- }
- /// The IP routing program was not found.
- #[cfg(target_os = "linux")]
- IpRouteNotFound {
- description("The IP routing program `ip` was not found.")
- }
- /// The OpenVPN binary was not found.
- OpenVpnNotFound(path: PathBuf) {
- description("No OpenVPN binary found")
- display("No OpenVPN binary found at {}", path.display())
- }
- /// The OpenVPN plugin was not found.
- PluginNotFound(path: PathBuf) {
- description("No OpenVPN plugin found")
- display("No OpenVPN plugin found at {}", path.display())
- }
- /// There was an error when writing authentication credentials to temporary file.
- CredentialsWriteError {
- description("Error while writing credentials to temporary file")
- }
- /// Failures related to the proxy service.
- ProxyError(msg: String) {
- description("Unable to start, wait for or kill the proxy service")
- display("Proxy error: {}", msg)
- }
- }
+
+/// Results from fallible operations on the OpenVPN tunnel.
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Errors that can happen when using the OpenVPN tunnel.
+#[derive(err_derive::Error, Debug)]
+pub enum Error {
+ /// Unable to start, wait for or kill the OpenVPN process.
+ #[error(display = "Error in OpenVPN process management: {}", _0)]
+ ChildProcessError(&'static str, #[error(cause)] io::Error),
+
+ /// Unable to start or manage the IPC server listening for events from OpenVPN.
+ #[error(display = "Unable to start or manage the event dispatcher IPC server")]
+ EventDispatcherError(#[error(cause)] talpid_ipc::Error),
+
+ /// The OpenVPN event dispatcher exited unexpectedly
+ #[error(display = "The OpenVPN event dispatcher exited unexpectedly")]
+ EventDispatcherExited,
+
+ /// No TAP adapter was detected
+ #[cfg(windows)]
+ #[error(display = "No TAP adapter was detected")]
+ MissingTapAdapter,
+
+ /// TAP adapter seems to be disabled
+ #[cfg(windows)]
+ #[error(display = "The TAP adapter appears to be disabled")]
+ DisabledTapAdapter,
+
+ /// OpenVPN process died unexpectedly
+ #[error(display = "OpenVPN process died unexpectedly")]
+ ChildProcessDied,
+
+ /// The IP routing program was not found.
+ #[cfg(target_os = "linux")]
+ #[error(display = "The IP routing program `ip` was not found")]
+ IpRouteNotFound(#[error(cause)] failure::Compat<which::Error>),
+
+ /// The OpenVPN binary was not found.
+ #[error(display = "No OpenVPN binary found at {}", _0)]
+ OpenVpnNotFound(String),
+
+ /// The OpenVPN plugin was not found.
+ #[error(display = "No OpenVPN plugin found at {}", _0)]
+ PluginNotFound(String),
+
+ /// Error while writing credentials to temporary file.
+ #[error(display = "Error while writing credentials to temporary file")]
+ CredentialsWriteError(#[error(cause)] io::Error),
+
+ /// Failures related to the proxy service.
+ #[error(display = "Unable to start the proxy service")]
+ StartProxyError(#[error(cause)] io::Error),
+
+ /// Error while monitoring proxy service
+ #[error(display = "Error while monitoring proxy service")]
+ MonitorProxyError(#[error(cause)] io::Error),
+
+ /// The proxy exited unexpectedly
+ #[error(
+ display = "The proxy exited unexpectedly providing these details: {}",
+ _0
+ )]
+ ProxyExited(String),
}
@@ -124,10 +142,10 @@ impl OpenVpnMonitor<OpenVpnCommand> {
{
let user_pass_file =
Self::create_credentials_file(&params.config.username, &params.config.password)
- .chain_err(|| ErrorKind::CredentialsWriteError)?;
+ .map_err(Error::CredentialsWriteError)?;
let proxy_auth_file = Self::create_proxy_auth_file(&params.options.proxy)
- .chain_err(|| ErrorKind::CredentialsWriteError)?;
+ .map_err(Error::CredentialsWriteError)?;
let user_pass_file_path = user_pass_file.to_path_buf();
@@ -205,13 +223,13 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
L: Fn(openvpn_plugin::EventType, HashMap<String, String>) + Send + Sync + 'static,
{
let event_dispatcher =
- event_server::start(on_event).chain_err(|| ErrorKind::EventDispatcherError)?;
+ event_server::start(on_event).map_err(Error::EventDispatcherError)?;
let child = cmd
.plugin(plugin_path, vec![event_dispatcher.path().to_owned()])
.log(log_path.as_ref().map(|p| p.as_path()))
.start()
- .chain_err(|| ErrorKind::ChildProcessError("Failed to start"))?;
+ .map_err(|e| Error::ChildProcessError("Failed to start", e))?;
Ok(OpenVpnMonitor {
child: Arc::new(child),
@@ -267,21 +285,13 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
// The proxy should never exit before openvpn.
match proxy_result {
Ok(proxy::WaitResult::ProperShutdown) => {
- return Err(ErrorKind::ProxyError("The proxy exited unexpectedly without providing additional details".into()).into());
+ return Err(Error::ProxyExited("No details".to_owned()));
}
Ok(proxy::WaitResult::UnexpectedExit(details)) => {
- return Err(ErrorKind::ProxyError(format!(
- "The proxy exited unexpectedly providing these details: {}",
- details
- ))
- .into());
+ return Err(Error::ProxyExited(details));
}
Err(err) => {
- return Err(err).chain_err(|| {
- ErrorKind::ProxyError(
- "Failed to wait for/monitor proxy service".into(),
- )
- });
+ return Err(err).map_err(Error::MonitorProxyError);
}
}
}
@@ -309,11 +319,11 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
}
WaitResult::Child(Err(e), _) => {
log::error!("OpenVPN process wait error: {}", e);
- Err(e).chain_err(|| ErrorKind::ChildProcessError("Error when waiting"))
+ Err(Error::ChildProcessError("Error when waiting", e))
}
WaitResult::EventDispatcher => {
log::error!("OpenVPN Event server exited unexpectedly");
- Err(ErrorKind::EventDispatcherError.into())
+ Err(Error::EventDispatcherExited)
}
}
}
@@ -356,16 +366,16 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
if let Some(log_path) = self.log_path.take() {
if let Ok(log) = fs::read_to_string(log_path) {
if log.contains("There are no TAP-Windows adapters on this system") {
- return ErrorKind::MissingTapAdapter.into();
+ return Error::MissingTapAdapter;
}
if log.contains("CreateFile failed on TAP device") {
- return ErrorKind::DisabledTapAdapter.into();
+ return Error::DisabledTapAdapter;
}
}
}
}
- ErrorKind::ChildProcessError("Died unexpectedly").into()
+ Error::ChildProcessDied
}
fn create_proxy_auth_file(
@@ -388,8 +398,8 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
proxy_resources: &ProxyResourceData,
) -> Result<Option<Box<dyn ProxyMonitor>>> {
if let Some(ref settings) = proxy_settings {
- let proxy_monitor = proxy::start_proxy(settings, proxy_resources)
- .chain_err(|| ErrorKind::ProxyError("Failed to start proxy service".into()))?;
+ let proxy_monitor =
+ proxy::start_proxy(settings, proxy_resources).map_err(Error::StartProxyError)?;
return Ok(Some(proxy_monitor));
}
Ok(None)
@@ -423,7 +433,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
log::trace!("Using OpenVPN plugin at {}", path.display());
Ok(path)
} else {
- bail!(ErrorKind::PluginNotFound(path));
+ Err(Error::PluginNotFound(path.display().to_string()))
}
}
@@ -443,7 +453,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
cmd.iproute_bin(
which::which("ip")
.compat()
- .chain_err(|| ErrorKind::IpRouteNotFound)?,
+ .map_err(Error::IpRouteNotFound)?,
);
cmd.remote(params.config.get_tunnel_endpoint().endpoint)
.user_pass(user_pass_file)
@@ -467,7 +477,7 @@ impl<C: OpenVpnBuilder + 'static> OpenVpnMonitor<C> {
log::trace!("Using OpenVPN at {}", path.display());
Ok(path)
} else {
- bail!(ErrorKind::OpenVpnNotFound(path));
+ Err(Error::OpenVpnNotFound(path.display().to_string()))
}
}
@@ -746,8 +756,8 @@ mod tests {
let error =
OpenVpnMonitor::new_internal(builder, |_, _| {}, "", None, TempFile::new(), None, None)
.unwrap_err();
- match error.kind() {
- ErrorKind::ChildProcessError(_) => (),
+ match error {
+ Error::ChildProcessError(..) => (),
_ => panic!("Wrong error"),
}
}
diff --git a/talpid-core/src/tunnel/wireguard/mod.rs b/talpid-core/src/tunnel/wireguard/mod.rs
index d1c0c451d9..79034f22cd 100644
--- a/talpid-core/src/tunnel/wireguard/mod.rs
+++ b/talpid-core/src/tunnel/wireguard/mod.rs
@@ -1,8 +1,9 @@
#![allow(missing_docs)]
+
use self::config::Config;
use super::{TunnelEvent, TunnelMetadata};
use crate::routing;
-use std::{path::Path, sync::mpsc};
+use std::{io, path::Path, sync::mpsc};
pub mod config;
mod ping_monitor;
@@ -13,37 +14,38 @@ pub use self::wireguard_go::WgGoTunnel;
// amount of seconds to run `ping` until it returns.
const PING_TIMEOUT: u16 = 7;
-error_chain! {
- errors {
- /// Failed to setup a tunnel device
- SetupTunnelDeviceError {
- description("Failed to create tunnel device")
- }
- /// Failed to setup wireguard tunnel
- StartWireguardError(status: i32) {
- display("Failed to start wireguard tunnel - {}", status)
- }
- /// Failed to tear down wireguard tunnel
- StopWireguardError(status: i32) {
- display("Failed to stop wireguard tunnel - {}", status)
- }
- /// Failed to set up routing
- SetupRoutingError {
- display("Failed to setup routing")
- }
- /// Failed to move or craete a log file
- PrepareLogFileError {
- display("Failed to setup a logging file")
- }
- /// Tunnel interface name contained null bytes
- InterfaceNameError {
- display("Tunnel interface name contains null bytes")
- }
- /// Pinging timed out
- PingTimeoutError {
- display("Ping timed out")
- }
- }
+pub type Result<T> = std::result::Result<T, Error>;
+
+/// Errors that can happen in the Wireguard tunnel monitor.
+#[derive(err_derive::Error, Debug)]
+pub enum Error {
+ /// Failed to setup a tunnel device.
+ #[error(display = "Failed to create tunnel device")]
+ SetupTunnelDeviceError(#[error(cause)] crate::network_interface::Error),
+
+ /// Failed to setup wireguard tunnel.
+ #[error(display = "Failed to start wireguard tunnel - {}", status)]
+ StartWireguardError { status: i32 },
+
+ /// Failed to tear down wireguard tunnel.
+ #[error(display = "Failed to stop wireguard tunnel - {}", status)]
+ StopWireguardError { status: i32 },
+
+ /// Failed to set up routing.
+ #[error(display = "Failed to setup routing")]
+ SetupRoutingError(#[error(cause)] crate::routing::Error),
+
+ /// Failed to move or craete a log file.
+ #[error(display = "Failed to setup a logging file")]
+ PrepareLogFileError(#[error(cause)] io::Error),
+
+ /// Invalid tunnel interface name.
+ #[error(display = "Invalid tunnel interface name")]
+ InterfaceNameError(#[error(cause)] std::ffi::NulError),
+
+ /// Pinging timed out.
+ #[error(display = "Ping timed out")]
+ PingTimeoutError,
}
/// Spawns and monitors a wireguard tunnel
@@ -65,7 +67,7 @@ impl WireguardMonitor {
on_event: F,
) -> Result<WireguardMonitor> {
let tunnel = Box::new(WgGoTunnel::start_tunnel(&config, log_path)?);
- let router = routing::RouteManager::new().chain_err(|| ErrorKind::SetupRoutingError)?;
+ let router = routing::RouteManager::new().map_err(Error::SetupRoutingError)?;
let event_callback = Box::new(on_event.clone());
let (close_msg_sender, close_msg_receiver) = mpsc::channel();
let mut monitor = WireguardMonitor {
@@ -111,7 +113,7 @@ impl WireguardMonitor {
pub fn wait(mut self) -> Result<()> {
let wait_result = match self.close_msg_receiver.recv() {
- Ok(CloseMsg::PingErr) => Err(ErrorKind::PingTimeoutError.into()),
+ Ok(CloseMsg::PingErr) => Err(Error::PingTimeoutError),
Ok(CloseMsg::Stop) => Ok(()),
Err(_) => Ok(()),
};
@@ -148,7 +150,7 @@ impl WireguardMonitor {
let default_node = self
.router
.get_default_route_node()
- .chain_err(|| ErrorKind::SetupRoutingError)?;
+ .map_err(Error::SetupRoutingError)?;
// route endpoints with specific routes
for peer in config.peers.iter() {
@@ -163,7 +165,7 @@ impl WireguardMonitor {
self.router
.add_routes(required_routes)
- .chain_err(|| ErrorKind::SetupRoutingError)
+ .map_err(Error::SetupRoutingError)
}
fn tunnel_metadata(&self, config: &Config) -> TunnelMetadata {
diff --git a/talpid-core/src/tunnel/wireguard/wireguard_go.rs b/talpid-core/src/tunnel/wireguard/wireguard_go.rs
index e713a4a190..059147286d 100644
--- a/talpid-core/src/tunnel/wireguard/wireguard_go.rs
+++ b/talpid-core/src/tunnel/wireguard/wireguard_go.rs
@@ -1,4 +1,4 @@
-use super::{Config, ErrorKind, Result, ResultExt, Tunnel};
+use super::{Config, Error, Result, Tunnel};
use crate::network_interface::{NetworkInterface, TunnelDevice};
use std::{ffi::CString, fs, os::unix::io::AsRawFd, path::Path};
@@ -14,25 +14,24 @@ pub struct WgGoTunnel {
impl WgGoTunnel {
pub fn start_tunnel(config: &Config, log_path: Option<&Path>) -> Result<Self> {
- let mut tunnel_device =
- TunnelDevice::new().chain_err(|| ErrorKind::SetupTunnelDeviceError)?;
+ let mut tunnel_device = TunnelDevice::new().map_err(Error::SetupTunnelDeviceError)?;
for ip in config.tunnel.addresses.iter() {
tunnel_device
.set_ip(*ip)
- .chain_err(|| ErrorKind::SetupTunnelDeviceError)?;
+ .map_err(Error::SetupTunnelDeviceError)?;
}
tunnel_device
.set_up(true)
- .chain_err(|| ErrorKind::SetupTunnelDeviceError)?;
+ .map_err(Error::SetupTunnelDeviceError)?;
let interface_name: String = tunnel_device.get_name().to_string();
let log_file = prepare_log_file(log_path)?;
let wg_config_str = config.to_userspace_format();
let iface_name =
- CString::new(interface_name.as_bytes()).chain_err(|| ErrorKind::InterfaceNameError)?;
+ CString::new(interface_name.as_bytes()).map_err(Error::InterfaceNameError)?;
let handle = unsafe {
wgTurnOnWithFd(
@@ -46,7 +45,7 @@ impl WgGoTunnel {
};
if handle < 0 {
- bail!(ErrorKind::StartWireguardError(handle));
+ return Err(Error::StartWireguardError { status: handle });
}
Ok(WgGoTunnel {
@@ -61,7 +60,7 @@ impl WgGoTunnel {
if let Some(handle) = self.handle.take() {
let status = unsafe { wgTurnOff(handle) };
if status < 0 {
- bail!(ErrorKind::StopWireguardError(status))
+ return Err(Error::StopWireguardError { status });
}
}
return Ok(());
@@ -77,8 +76,7 @@ impl Drop for WgGoTunnel {
}
fn prepare_log_file(log_path: Option<&Path>) -> Result<fs::File> {
- fs::File::create(log_path.unwrap_or("/dev/null".as_ref()))
- .chain_err(|| ErrorKind::PrepareLogFileError)
+ fs::File::create(log_path.unwrap_or("/dev/null".as_ref())).map_err(Error::PrepareLogFileError)
}
impl Tunnel for WgGoTunnel {
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index a843fa1fdd..f044c61df1 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -126,17 +126,11 @@ impl ConnectingState {
}
Err(error) => match error {
#[cfg(windows)]
- error @ tunnel::Error(
- tunnel::ErrorKind::OpenVpnTunnelMonitoringError(
- tunnel::openvpn::ErrorKind::DisabledTapAdapter,
- ),
- _,
+ error @ tunnel::Error::OpenVpnTunnelMonitoringError(
+ tunnel::openvpn::Error::DisabledTapAdapter,
)
- | error @ tunnel::Error(
- tunnel::ErrorKind::OpenVpnTunnelMonitoringError(
- tunnel::openvpn::ErrorKind::MissingTapAdapter,
- ),
- _,
+ | error @ tunnel::Error::OpenVpnTunnelMonitoringError(
+ tunnel::openvpn::Error::MissingTapAdapter,
) => {
warn!(
"{}",
@@ -351,8 +345,8 @@ impl TunnelState for ConnectingState {
}
Err(error) => {
log::error!("Failed to start tunnel: {}", error);
- let block_reason = match *error.kind() {
- tunnel::ErrorKind::EnableIpv6Error => BlockReason::Ipv6Unavailable,
+ let block_reason = match error {
+ tunnel::Error::EnableIpv6Error => BlockReason::Ipv6Unavailable,
_ => BlockReason::StartTunnelError,
};
BlockedState::enter(shared_values, block_reason)
diff --git a/talpid-openvpn-plugin/Cargo.toml b/talpid-openvpn-plugin/Cargo.toml
index caf1e5637b..439d10131e 100644
--- a/talpid-openvpn-plugin/Cargo.toml
+++ b/talpid-openvpn-plugin/Cargo.toml
@@ -17,7 +17,7 @@ edition = "2018"
crate-type = ["cdylib"]
[dependencies]
-error-chain = "0.12"
+err-derive = "0.1.5"
log = "0.4"
env_logger = "0.6"
jsonrpc-client-core = { git = "https://github.com/mullvad/jsonrpc-client-rs", rev = "68aac55b" }
@@ -28,6 +28,7 @@ futures = "0.1"
openvpn-plugin = { git = "https://github.com/mullvad/openvpn-plugin-rs", branch = "auth-failed-event", features = ["serde", "log"] }
talpid-ipc = { path = "../talpid-ipc" }
+talpid-types = { path = "../talpid-types" }
[target.'cfg(windows)'.build-dependencies]
diff --git a/talpid-openvpn-plugin/src/lib.rs b/talpid-openvpn-plugin/src/lib.rs
index 34ddce52bb..c2080e294a 100644
--- a/talpid-openvpn-plugin/src/lib.rs
+++ b/talpid-openvpn-plugin/src/lib.rs
@@ -8,36 +8,36 @@
#![deny(rust_2018_idioms)]
-#[macro_use]
-extern crate error_chain;
-
-use error_chain::ChainedError;
use openvpn_plugin::{openvpn_plugin, EventResult, EventType};
-use std::{collections::HashMap, ffi::CString, sync::Mutex};
-
+use std::{collections::HashMap, ffi::CString, io, sync::Mutex};
+use talpid_types::ErrorExt;
mod processing;
use crate::processing::EventProcessor;
-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")
- }
- ParseArgsFailed {
- description("Unable to parse arguments from OpenVPN")
- }
- EventProcessingFailed {
- description("Failed to process the event")
- }
- }
+#[derive(err_derive::Error, Debug)]
+pub enum Error {
+ #[error(display = "No core server id given as first argument")]
+ MissingCoreServerId,
+
+ #[error(display = "Failed to send an event to daemon over the IPC channel")]
+ SendEvent(#[error(cause)] jsonrpc_client_core::Error),
+
+ #[error(display = "Connection is shut down")]
+ Shutdown,
+
+ #[error(display = "Unable to start Tokio runtime")]
+ CreateRuntime(#[error(cause)] io::Error),
+
+ #[error(display = "Unable to create IPC transport")]
+ CreateTransport(#[error(cause)] io::Error),
+
+ #[error(display = "Unable to parse environment variables from OpenVPN")]
+ ParseEnvFailed(#[error(cause)] std::str::Utf8Error),
+
+ #[error(display = "Unable to parse arguments from OpenVPN")]
+ ParseArgsFailed(#[error(cause)] std::str::Utf8Error),
}
@@ -63,7 +63,7 @@ pub struct Arguments {
fn openvpn_open(
args: Vec<CString>,
_env: HashMap<CString, CString>,
-) -> Result<(Vec<EventType>, Mutex<EventProcessor>)> {
+) -> Result<(Vec<EventType>, Mutex<EventProcessor>), Error> {
env_logger::init();
log::debug!("Initializing plugin");
@@ -72,20 +72,18 @@ fn openvpn_open(
"Connecting back to talpid core at {}",
arguments.ipc_socket_path
);
- let processor = EventProcessor::new(arguments).chain_err(|| ErrorKind::InitHandleFailed)?;
+ let processor = EventProcessor::new(arguments)?;
Ok((INTERESTING_EVENTS.to_vec(), Mutex::new(processor)))
}
-fn parse_args(args: &[CString]) -> Result<Arguments> {
+fn parse_args(args: &[CString]) -> Result<Arguments, Error> {
let mut args_iter = openvpn_plugin::ffi::parse::string_array_utf8(args)
- .chain_err(|| ErrorKind::ParseArgsFailed)?
+ .map_err(Error::ParseArgsFailed)?
.into_iter();
let _plugin_path = args_iter.next();
- let ipc_socket_path: String = args_iter
- .next()
- .ok_or_else(|| ErrorKind::Msg("No core server id given as first argument".to_owned()))?;
+ let ipc_socket_path: String = args_iter.next().ok_or_else(|| Error::MissingCoreServerId)?;
Ok(Arguments { ipc_socket_path })
}
@@ -100,17 +98,15 @@ fn openvpn_event(
_args: Vec<CString>,
env: HashMap<CString, CString>,
handle: &mut Mutex<EventProcessor>,
-) -> Result<EventResult> {
+) -> Result<EventResult, Error> {
log::debug!("Received event: {:?}", event);
- let parsed_env =
- openvpn_plugin::ffi::parse::env_utf8(&env).chain_err(|| ErrorKind::ParseEnvFailed)?;
+ let parsed_env = openvpn_plugin::ffi::parse::env_utf8(&env).map_err(Error::ParseEnvFailed)?;
let result = handle
.lock()
.expect("failed to obtain mutex for EventProcessor")
- .process_event(event, parsed_env)
- .chain_err(|| ErrorKind::EventProcessingFailed);
+ .process_event(event, parsed_env);
match result {
Ok(()) => Ok(EventResult::Success),
Err(e) => {
diff --git a/talpid-openvpn-plugin/src/processing.rs b/talpid-openvpn-plugin/src/processing.rs
index 4e1eb361a8..4124b6491c 100644
--- a/talpid-openvpn-plugin/src/processing.rs
+++ b/talpid-openvpn-plugin/src/processing.rs
@@ -1,4 +1,4 @@
-use super::Arguments;
+use super::{Arguments, Error};
use jsonrpc_client_core::{
expand_params, jsonrpc_client, Future, Result as ClientResult, Transport,
};
@@ -6,19 +6,6 @@ use jsonrpc_client_ipc::IpcTransport;
use std::{collections::HashMap, sync::mpsc, thread};
use tokio::{reactor::Handle, runtime::Runtime};
-error_chain! {
- errors {
- IpcSendingError {
- description("Failed while sending an event over the IPC channel")
- }
-
- Shutdown {
- description("Connection is shut down")
- }
-
- }
-}
-
/// Struct processing OpenVPN events and notifies listeners over IPC
pub struct EventProcessor {
@@ -27,23 +14,37 @@ pub struct EventProcessor {
}
impl EventProcessor {
- pub fn new(arguments: Arguments) -> Result<EventProcessor> {
+ pub fn new(arguments: Arguments) -> Result<EventProcessor, Error> {
log::trace!("Creating EventProcessor");
let (start_tx, start_rx) = mpsc::channel();
let (client_result_tx, client_result_rx) = mpsc::channel();
thread::spawn(move || {
- let mut rt = Runtime::new().expect("failed to spawn runtime");
-
+ let mut rt = match Runtime::new().map_err(Error::CreateRuntime) {
+ Err(e) => {
+ let _ = start_tx.send(Err(e));
+ return;
+ }
+ Ok(rt) => rt,
+ };
let (client, client_handle) =
- IpcTransport::new(&arguments.ipc_socket_path, &Handle::current())
- .expect("Unable to create IPC transport")
- .into_client();
+ match IpcTransport::new(&arguments.ipc_socket_path, &Handle::default())
+ .map_err(Error::CreateTransport)
+ .map(|transport| transport.into_client())
+ {
+ Err(e) => {
+ let _ = start_tx.send(Err(e));
+ return;
+ }
+ Ok((client, client_handle)) => (client, client_handle),
+ };
- let _ = start_tx.send(client_handle);
+ let _ = start_tx.send(Ok(client_handle));
let _ = client_result_tx.send(rt.block_on(client));
});
- let client_handle = start_rx.recv().chain_err(|| ErrorKind::Shutdown)?;
+ let client_handle = start_rx
+ .recv()
+ .expect("No start result from EventProcessor thread")?;
let ipc_client = EventProxy::new(client_handle);
Ok(EventProcessor {
@@ -56,22 +57,22 @@ impl EventProcessor {
&mut self,
event: openvpn_plugin::EventType,
env: HashMap<String, String>,
- ) -> Result<()> {
+ ) -> Result<(), Error> {
log::trace!("Processing \"{:?}\" event", event);
let call_future = self
.ipc_client
.openvpn_event(event, env)
- .map_err(|e| Error::with_chain(e, ErrorKind::IpcSendingError));
+ .map_err(Error::SendEvent);
call_future.wait()?;
self.check_client_status()
}
- fn check_client_status(&mut self) -> Result<()> {
+ fn check_client_status(&mut self) -> Result<(), Error> {
use std::sync::mpsc::TryRecvError::*;
match self.client_result_rx.try_recv() {
Err(Empty) => Ok(()),
- Err(Disconnected) | Ok(Ok(())) => Err(ErrorKind::Shutdown.into()),
- Ok(Err(e)) => Err(Error::with_chain(e, ErrorKind::IpcSendingError)),
+ Err(Disconnected) | Ok(Ok(())) => Err(Error::Shutdown),
+ Ok(Err(e)) => Err(Error::SendEvent(e)),
}
}
}