diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-03-29 12:58:00 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-03-29 12:58:00 +0100 |
| commit | f019ca88e7387fd0a0871baed97fec047f55242f (patch) | |
| tree | c61093f6be1a41983c33250a3a14db1db7943879 | |
| parent | c95b0e55a5b56a7dc3fa15e51240ec531a48f9a5 (diff) | |
| parent | b03e207b211f46eee6aaf7398b8963bc8ac2c9a9 (diff) | |
| download | mullvadvpn-f019ca88e7387fd0a0871baed97fec047f55242f.tar.xz mullvadvpn-f019ca88e7387fd0a0871baed97fec047f55242f.zip | |
Merge branch 'eliminate-some-error-chain'
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | mullvad-paths/Cargo.toml | 2 | ||||
| -rw-r--r-- | mullvad-paths/src/cache.rs | 2 | ||||
| -rw-r--r-- | mullvad-paths/src/lib.rs | 41 | ||||
| -rw-r--r-- | mullvad-paths/src/settings.rs | 3 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-core/src/dns/windows/mod.rs | 107 | ||||
| -rw-r--r-- | talpid-core/src/ffi.rs | 6 | ||||
| -rw-r--r-- | talpid-core/src/firewall/mod.rs | 10 | ||||
| -rw-r--r-- | talpid-core/src/firewall/windows.rs | 90 | ||||
| -rw-r--r-- | talpid-core/src/network_interface.rs | 74 | ||||
| -rw-r--r-- | talpid-core/src/routing/linux.rs | 45 | ||||
| -rw-r--r-- | talpid-core/src/routing/macos.rs | 45 |
13 files changed, 212 insertions, 216 deletions
diff --git a/Cargo.lock b/Cargo.lock index 53d74ecece..76061d1a26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1131,7 +1131,7 @@ name = "mullvad-paths" version = "0.1.0" dependencies = [ "dirs 1.0.5 (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)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/mullvad-paths/Cargo.toml b/mullvad-paths/Cargo.toml index ceb6391e32..131a6dd798 100644 --- a/mullvad-paths/Cargo.toml +++ b/mullvad-paths/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" edition = "2018" [dependencies] -error-chain = "0.12" +err-derive = "0.1.5" log = "0.4" [target.'cfg(any(windows, target_os = "macos"))'.dependencies] diff --git a/mullvad-paths/src/cache.rs b/mullvad-paths/src/cache.rs index 7493606d66..dd4307572c 100644 --- a/mullvad-paths/src/cache.rs +++ b/mullvad-paths/src/cache.rs @@ -22,7 +22,7 @@ pub fn get_default_cache_dir() -> Result<PathBuf> { } #[cfg(any(target_os = "macos", windows))] { - dir = dirs::cache_dir().ok_or_else(|| crate::ErrorKind::FindDirError.into()) + dir = dirs::cache_dir().ok_or(crate::Error::FindDirError) } dir.map(|dir| dir.join(crate::PRODUCT_NAME)) } diff --git a/mullvad-paths/src/lib.rs b/mullvad-paths/src/lib.rs index 2e458c7169..1d829e1145 100644 --- a/mullvad-paths/src/lib.rs +++ b/mullvad-paths/src/lib.rs @@ -1,23 +1,22 @@ -#[macro_use] -extern crate error_chain; +use std::{fs, io, path::PathBuf}; -use std::{fs, path::PathBuf}; +pub type Result<T> = std::result::Result<T, Error>; -error_chain! { - errors { - CreateDirFailed(path: PathBuf) { - description("Failed to create directory") - display("Failed to create directory {}", path.display()) - } - SetDirPermissionFailed(path: PathBuf) { - description("Failed to set directory permissions") - display("Failed to set directory permissions on {}", path.display()) - } - #[cfg(any(windows, target_os = "macos"))] - FindDirError { description("Not able to find requested directory" )} - #[cfg(windows)] - NoProgramDataDir { description("Missing %ALLUSERSPROFILE% environment variable") } - } +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "Failed to create directory {}", _0)] + CreateDirFailed(String, #[error(cause)] io::Error), + + #[error(display = "Failed to set directory permissions on {}", _0)] + SetDirPermissionFailed(String, #[error(cause)] io::Error), + + #[cfg(any(windows, target_os = "macos"))] + #[error(display = "Not able to find requested directory")] + FindDirError, + + #[cfg(windows)] + #[error(display = "Missing %ALLUSERSPROFILE% environment variable")] + NoProgramDataDir, } #[cfg(unix)] @@ -31,7 +30,7 @@ const PRODUCT_NAME: &str = "Mullvad VPN"; fn get_allusersprofile_dir() -> Result<PathBuf> { match std::env::var_os("ALLUSERSPROFILE") { Some(dir) => Ok(PathBuf::from(&dir)), - None => bail!(ErrorKind::NoProgramDataDir), + None => Err(Error::NoProgramDataDir), } } @@ -40,10 +39,10 @@ fn create_and_return( permissions: Option<fs::Permissions>, ) -> Result<PathBuf> { let dir = dir_fn()?; - fs::create_dir_all(&dir).chain_err(|| ErrorKind::CreateDirFailed(dir.clone()))?; + fs::create_dir_all(&dir).map_err(|e| Error::CreateDirFailed(dir.display().to_string(), e))?; if let Some(permissions) = permissions { fs::set_permissions(&dir, permissions) - .chain_err(|| ErrorKind::SetDirPermissionFailed(dir.clone()))?; + .map_err(|e| Error::SetDirPermissionFailed(dir.display().to_string(), e))?; } Ok(dir) } diff --git a/mullvad-paths/src/settings.rs b/mullvad-paths/src/settings.rs index 1c720eab50..0645a38a6e 100644 --- a/mullvad-paths/src/settings.rs +++ b/mullvad-paths/src/settings.rs @@ -1,5 +1,4 @@ use crate::Result; - use std::{env, path::PathBuf}; /// Creates and returns the settings directory pointed to by `MULLVAD_SETTINGS_DIR`, or the default @@ -23,7 +22,7 @@ pub fn get_default_settings_dir() -> Result<PathBuf> { } #[cfg(windows)] { - dir = dirs::data_local_dir().ok_or_else(|| crate::ErrorKind::FindDirError.into()); + dir = dirs::data_local_dir().ok_or(crate::Error::FindDirError); } dir.map(|dir| dir.join(crate::PRODUCT_NAME)) } diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 2ebdf0a59e..d7116a7457 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" atty = "0.2" 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" } jsonrpc-macros = { git = "https://github.com/mullvad/jsonrpc", branch = "mullvad-fork" } diff --git a/talpid-core/src/dns/windows/mod.rs b/talpid-core/src/dns/windows/mod.rs index 9d2a8245b2..74cef023e5 100644 --- a/talpid-core/src/dns/windows/mod.rs +++ b/talpid-core/src/dns/windows/mod.rs @@ -6,43 +6,36 @@ use std::{ path::Path, ptr, slice, }; +use widestring::WideCString; mod system_state; use self::system_state::SystemStateWriter; -use error_chain::ChainedError; -use widestring::WideCString; - const DNS_STATE_FILENAME: &'static str = "dns-state-backup"; -error_chain! { - errors{ - /// Failure to initialize WinDns - Initialization{ - description("Failed to initialize WinDns") - } +/// Errors that can happen when configuring DNS on Windows. +#[derive(err_derive::Error, Debug)] +pub enum Error { + /// Failure to initialize WinDns. + #[error(display = "Failed to initialize WinDns")] + Initialization, - /// Failure to deinitialize WinDns - Deinitialization{ - description("Failed to deinitialize WinDns") - } + /// Failure to deinitialize WinDns. + #[error(display = "Failed to deinitialize WinDns")] + Deinitialization, - /// Failure to set new DNS servers - Setting{ - description("Failed to set new DNS servers") - } + /// Failure to set new DNS servers. + #[error(display = "Failed to set new DNS servers")] + Setting, - /// Failure to reset DNS settings - Resetting{ - description("Failed to reset DNS") - } + /// Failure to reset DNS settings. + #[error(display = "Failed to reset DNS")] + Resetting, - /// Failure to reset DNS settings from backup - Recovery{ - description("Failed to recover to backed up system state") - } - } + /// Failure to reset DNS settings from backup. + #[error(display = "Failed to recover to backed up system state")] + Recovery, } pub struct DnsMonitor { @@ -52,7 +45,7 @@ pub struct DnsMonitor { impl super::DnsMonitorT for DnsMonitor { type Error = Error; - fn new(cache_dir: impl AsRef<Path>) -> Result<Self> { + fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Error> { unsafe { WinDns_Initialize(Some(log_sink), ptr::null_mut()).into_result()? }; let backup_writer = SystemStateWriter::new( @@ -62,16 +55,11 @@ impl super::DnsMonitorT for DnsMonitor { .into_boxed_path(), ); let mut dns = DnsMonitor { backup_writer }; - if let Err(error) = dns - .restore_system_backup() - .chain_err(|| "Failed to restore DNS backup") - { - error!("{}", error.display_chain()); - } + dns.restore_system_backup(); Ok(dns) } - fn set(&mut self, _interface: &str, servers: &[IpAddr]) -> Result<()> { + fn set(&mut self, _interface: &str, servers: &[IpAddr]) -> Result<(), Error> { let ipv4 = servers .iter() .filter(|ip| ip.is_ipv4()) @@ -109,7 +97,7 @@ impl super::DnsMonitorT for DnsMonitor { } } - fn reset(&mut self) -> Result<()> { + fn reset(&mut self) -> Result<(), Error> { unsafe { WinDns_Reset().into_result()? }; if let Err(e) = self.backup_writer.remove_backup() { @@ -120,30 +108,27 @@ impl super::DnsMonitorT for DnsMonitor { } impl DnsMonitor { - fn restore_dns_settings(&mut self, data: &[u8]) -> Result<()> { + fn restore_dns_settings(&mut self, data: &[u8]) -> Result<(), Error> { unsafe { WinDns_Recover(data.as_ptr(), data.len() as u32) }.into_result() } - fn restore_system_backup(&mut self) -> Result<()> { - if let Some(previous_state) = self - .backup_writer - .read_backup() - .chain_err(|| "Failed to read backed up DNS state")? - { - info!("Restoring DNS state from backup"); - if let Err(e) = self.restore_dns_settings(&previous_state) { - error!("Failed to restore DNS settings - {}", e); - } else { - trace!("Successfully restored DNS state"); - }; - self.backup_writer - .remove_backup() - .chain_err(|| "Failed to remove backed up DNS state after restoring it")?; - debug!("DNS recovery file removed!"); - } else { - trace!("No DNS state to restore"); + fn restore_system_backup(&mut self) { + match self.backup_writer.read_backup() { + Ok(Some(previous_state)) => { + info!("Restoring DNS state from backup"); + if let Err(e) = self.restore_dns_settings(&previous_state) { + error!("Failed to restore DNS settings - {}", e); + } else { + trace!("Successfully restored DNS state"); + }; + if let Err(e) = self.backup_writer.remove_backup() { + error!("Failed to remove backed up DNS state after restore - {}", e); + } + debug!("DNS recovery file removed!"); + } + Ok(None) => trace!("No DNS state to restore"), + Err(e) => error!("Failed to read backed up DNS state - {}", e), } - Ok(()) } } @@ -201,11 +186,11 @@ impl Drop for DnsMonitor { } -ffi_error!(InitializationResult, ErrorKind::Initialization.into()); -ffi_error!(DeinitializationResult, ErrorKind::Deinitialization.into()); -ffi_error!(SettingResult, ErrorKind::Setting.into()); -ffi_error!(ResettingResult, ErrorKind::Resetting.into()); -ffi_error!(RecoveringResult, ErrorKind::Recovery.into()); +ffi_error!(InitializationResult, Error::Initialization); +ffi_error!(DeinitializationResult, Error::Deinitialization); +ffi_error!(SettingResult, Error::Setting); +ffi_error!(ResettingResult, Error::Resetting); +ffi_error!(RecoverResult, Error::Recovery); /// A callback for writing system state data @@ -289,5 +274,5 @@ extern "system" { pub fn WinDns_Reset() -> ResettingResult; #[link_name = "WinDns_Recover"] - pub fn WinDns_Recover(data: *const u8, length: u32) -> RecoveringResult; + pub fn WinDns_Recover(data: *const u8, length: u32) -> RecoverResult; } diff --git a/talpid-core/src/ffi.rs b/talpid-core/src/ffi.rs index 6c4d8381d4..7f994b787a 100644 --- a/talpid-core/src/ffi.rs +++ b/talpid-core/src/ffi.rs @@ -9,7 +9,7 @@ macro_rules! ffi_error { } impl $result { - pub fn into_result(self) -> Result<()> { + pub fn into_result(self) -> Result<(), Error> { match self.success { true => Ok(()), false => Err($error), @@ -17,8 +17,8 @@ macro_rules! ffi_error { } } - impl Into<Result<()>> for $result { - fn into(self) -> Result<()> { + impl Into<Result<(), Error>> for $result { + fn into(self) -> Result<(), Error> { self.into_result() } } diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs index 865226ae4d..e7b388245f 100644 --- a/talpid-core/src/firewall/mod.rs +++ b/talpid-core/src/firewall/mod.rs @@ -77,7 +77,7 @@ pub enum FirewallPolicy { } impl fmt::Display for FirewallPolicy { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { FirewallPolicy::Connecting { peer_endpoint, @@ -154,15 +154,15 @@ impl Firewall { /// Abstract firewall interaction trait. Used by the OS specific implementations. trait FirewallT: Sized { /// The error type thrown by the implementer of this trait - type Error: ::std::error::Error; + type Error: std::error::Error; /// Create new instance - fn new() -> ::std::result::Result<Self, Self::Error>; + fn new() -> Result<Self, Self::Error>; /// Enable the given FirewallPolicy - fn apply_policy(&mut self, policy: FirewallPolicy) -> ::std::result::Result<(), Self::Error>; + fn apply_policy(&mut self, policy: FirewallPolicy) -> Result<(), Self::Error>; /// Revert the system firewall state to what it was before this instance started /// modifying the system. - fn reset_policy(&mut self) -> ::std::result::Result<(), Self::Error>; + fn reset_policy(&mut self) -> Result<(), Self::Error>; } diff --git a/talpid-core/src/firewall/windows.rs b/talpid-core/src/firewall/windows.rs index f84d01dc98..2ab290005f 100644 --- a/talpid-core/src/firewall/windows.rs +++ b/talpid-core/src/firewall/windows.rs @@ -7,43 +7,37 @@ use log::{debug, error, trace}; use talpid_types::net::Endpoint; use widestring::WideCString; -error_chain! { - errors { - /// Failure to initialize windows firewall module - Initialization { - description("Failed to initialise windows firewall module") - } - /// Failure to deinitialize windows firewall module - Deinitialization { - description("Failed to deinitialize windows firewall module") - } +/// Errors that can happen when configuring the Windows firewall. +#[derive(err_derive::Error, Debug)] +pub enum Error { + /// Failure to initialize windows firewall module + #[error(display = "Failed to initialize windows firewall module")] + Initialization, - /// Failure to apply a firewall _connecting_ policy - ApplyingConnectingPolicy { - description("Failed to apply firewall policy for when the daemon is connecting to a tunnel") - } + /// Failure to deinitialize windows firewall module + #[error(display = "Failed to deinitialize windows firewall module")] + Deinitialization, - /// Failure to apply a firewall _connected_ policy - ApplyingConnectedPolicy { - description("Failed to apply firewall policy for when the daemon is connected to a tunnel") - } + /// Failure to apply a firewall _connecting_ policy + #[error(display = "Failed to apply connecting firewall policy")] + ApplyingConnectingPolicy, - /// Failure to apply firewall _blocked_ policy - ApplyingBlockedPolicy { - description("Failed to apply blocked firewall policy") - } + /// Failure to apply a firewall _connected_ policy + #[error(display = "Failed to apply connected firewall policy")] + ApplyingConnectedPolicy, - /// Failure to reset firewall policies - ResettingPolicy { - description("Failed to reset firewall policies") - } + /// Failure to apply firewall _blocked_ policy + #[error(display = "Failed to apply blocked firewall policy")] + ApplyingBlockedPolicy, - /// Failure to set TAP adapter metric - SetTapMetric { - description("Unable to set TAP adapter metric") - } - } + /// Failure to reset firewall policies + #[error(display = "Failed to reset firewall policies")] + ResettingPolicy, + + /// Failure to set TAP adapter metric + #[error(display = "Unable to set TAP adapter metric")] + SetTapMetric(#[error(cause)] crate::winnet::Error), } const WINFW_TIMEOUT_SECONDS: u32 = 2; @@ -54,7 +48,7 @@ pub struct Firewall(()); impl FirewallT for Firewall { type Error = Error; - fn new() -> Result<Self> { + fn new() -> Result<Self, Self::Error> { unsafe { WinFw_Initialize( WINFW_TIMEOUT_SECONDS, @@ -67,7 +61,7 @@ impl FirewallT for Firewall { Ok(Firewall(())) } - fn apply_policy(&mut self, policy: FirewallPolicy) -> Result<()> { + fn apply_policy(&mut self, policy: FirewallPolicy) -> Result<(), Self::Error> { match policy { FirewallPolicy::Connecting { peer_endpoint, @@ -93,7 +87,7 @@ impl FirewallT for Firewall { } } - fn reset_policy(&mut self) -> Result<()> { + fn reset_policy(&mut self) -> Result<(), Self::Error> { unsafe { WinFw_Reset().into_result() }?; Ok(()) } @@ -114,7 +108,7 @@ impl Firewall { &mut self, endpoint: &Endpoint, winfw_settings: &WinFwSettings, - ) -> Result<()> { + ) -> Result<(), Error> { trace!("Applying 'connecting' firewall policy"); let ip_str = Self::widestring_ip(endpoint.address.ip()); @@ -138,7 +132,7 @@ impl Firewall { endpoint: &Endpoint, winfw_settings: &WinFwSettings, tunnel_metadata: &crate::tunnel::TunnelMetadata, - ) -> Result<()> { + ) -> Result<(), Error> { trace!("Applying 'connected' firewall policy"); let ip_str = Self::widestring_ip(endpoint.address.ip()); let v4_gateway = Self::widestring_ip(tunnel_metadata.ipv4_gateway.into()); @@ -157,7 +151,7 @@ impl Firewall { }; let metrics_set = winnet::ensure_top_metric_for_interface(&tunnel_metadata.interface) - .chain_err(|| ErrorKind::SetTapMetric)?; + .map_err(Error::SetTapMetric)?; if metrics_set { debug!("Network interface metrics were changed"); @@ -182,7 +176,7 @@ impl Firewall { } } - fn set_blocked_state(&mut self, winfw_settings: &WinFwSettings) -> Result<()> { + fn set_blocked_state(&mut self, winfw_settings: &WinFwSettings) -> Result<(), Error> { trace!("Applying 'blocked' firewall policy"); unsafe { WinFw_ApplyPolicyBlocked(winfw_settings).into_result() } } @@ -191,7 +185,7 @@ impl Firewall { #[allow(non_snake_case)] mod winfw { - use super::{ErrorKind, Result}; + use super::Error; use crate::winnet; use libc; use talpid_types::net::TransportProtocol; @@ -234,18 +228,12 @@ mod winfw { } } - ffi_error!(InitializationResult, ErrorKind::Initialization.into()); - ffi_error!(DeinitializationResult, ErrorKind::Deinitialization.into()); - ffi_error!( - ApplyConnectingResult, - ErrorKind::ApplyingConnectingPolicy.into() - ); - ffi_error!( - ApplyConnectedResult, - ErrorKind::ApplyingConnectedPolicy.into() - ); - ffi_error!(ApplyBlockedResult, ErrorKind::ApplyingBlockedPolicy.into()); - ffi_error!(ResettingPolicyResult, ErrorKind::ResettingPolicy.into()); + ffi_error!(InitializationResult, Error::Initialization); + ffi_error!(DeinitializationResult, Error::Deinitialization); + ffi_error!(ApplyConnectingResult, Error::ApplyingConnectingPolicy); + ffi_error!(ApplyConnectedResult, Error::ApplyingConnectedPolicy); + ffi_error!(ApplyBlockedResult, Error::ApplyingBlockedPolicy); + ffi_error!(ResettingPolicyResult, Error::ResettingPolicy); extern "system" { #[link_name = "WinFw_Initialize"] diff --git a/talpid-core/src/network_interface.rs b/talpid-core/src/network_interface.rs index 7117dadd69..201a2582c8 100644 --- a/talpid-core/src/network_interface.rs +++ b/talpid-core/src/network_interface.rs @@ -1,34 +1,45 @@ use nix::fcntl; use std::{ + io, net::IpAddr, os::unix::io::{AsRawFd, IntoRawFd, RawFd}, }; use tun::{platform, Configuration, Device}; -error_chain! { - errors { - /// Unable to open a tunnel device - SetupDeviceError { description("Failed to setup a device") } - /// Unable to get the name of a tunnel device - GetNameError { description("Failed to get a name for the device") } - /// Failed to set IP address - SetIpError{ description( "Failed to set IP address" ) } - /// Failed to toggle device state - ToggleDeviceError{ description( "Failed to enable/disable link device" ) } - } -} +/// Errors that can happen when working with *nix tunnel interfaces. +#[derive(err_derive::Error, Debug)] +pub enum Error { + /// Failed to set IP address + #[error(display = "Failed to set IPv4 address")] + SetIpv4Error(#[error(cause)] tun::Error), + + /// Failed to set IP address + #[error(display = "Failed to set IPv6 address")] + SetIpv6Error(#[error(cause)] io::Error), + + /// Unable to open a tunnel device + #[error(display = "Unable to open a tunnel device")] + CreateDeviceError(#[error(cause)] tun::Error), + /// Failed to apply async flags to tunnel device + #[error(display = "Failed to apply async flags to tunnel device")] + SetDeviceAsyncError(#[error(cause)] nix::Error), + + /// Failed to enable/disable link device + #[error(display = "Failed to enable/disable link device")] + ToggleDeviceError(#[error(cause)] tun::Error), +} /// A trait for managing link devices pub trait NetworkInterface: Sized { /// Bring a given interface up or down - fn set_up(&mut self, up: bool) -> Result<()>; + fn set_up(&mut self, up: bool) -> Result<(), Error>; /// Set host IPs for interface - fn set_ip(&mut self, ip: IpAddr) -> Result<()>; + fn set_ip(&mut self, ip: IpAddr) -> Result<(), Error>; /// Set MTU for interface - fn set_mtu(&mut self, mtu: u16) -> Result<()>; + fn set_mtu(&mut self, mtu: u16) -> Result<(), Error>; /// Get name of interface fn get_name(&self) -> &str; @@ -37,10 +48,10 @@ pub trait NetworkInterface: Sized { trait WireguardLink: AsRawFd + IntoRawFd {} -fn apply_async_flags(fd: RawFd) -> Result<()> { - fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFL).chain_err(|| ErrorKind::SetupDeviceError)?; +fn apply_async_flags(fd: RawFd) -> Result<(), nix::Error> { + fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFL)?; let arg = fcntl::FcntlArg::F_SETFL(fcntl::OFlag::O_RDWR | fcntl::OFlag::O_NONBLOCK); - fcntl::fcntl(fd, arg).chain_err(|| ErrorKind::SetupDeviceError)?; + fcntl::fcntl(fd, arg)?; Ok(()) } @@ -52,15 +63,15 @@ pub struct TunnelDevice { impl TunnelDevice { /// Creates a new Tunnel device #[allow(unused_mut)] - pub fn new() -> Result<Self> { + pub fn new() -> Result<Self, Error> { let mut config = Configuration::default(); #[cfg(target_os = "linux")] config.platform(|config| { config.packet_information(true); }); - let mut dev = platform::create(&config).chain_err(|| ErrorKind::SetupDeviceError)?; - apply_async_flags(dev.as_raw_fd())?; + let mut dev = platform::create(&config).map_err(Error::CreateDeviceError)?; + apply_async_flags(dev.as_raw_fd()).map_err(Error::SetDeviceAsyncError)?; Ok(Self { dev }) } } @@ -78,12 +89,9 @@ impl IntoRawFd for TunnelDevice { } impl NetworkInterface for TunnelDevice { - fn set_ip(&mut self, ip: IpAddr) -> Result<()> { + fn set_ip(&mut self, ip: IpAddr) -> Result<(), Error> { match ip { - IpAddr::V4(ipv4) => self - .dev - .set_address(ipv4) - .chain_err(|| ErrorKind::SetIpError), + IpAddr::V4(ipv4) => self.dev.set_address(ipv4).map_err(Error::SetIpv4Error), IpAddr::V6(ipv6) => { #[cfg(target_os = "linux")] { @@ -98,7 +106,7 @@ impl NetworkInterface for TunnelDevice { ) .run() .map(|_| ()) - .chain_err(|| ErrorKind::SetIpError) + .map_err(Error::SetIpv6Error) } #[cfg(target_os = "macos")] { @@ -111,22 +119,20 @@ impl NetworkInterface for TunnelDevice { ) .run() .map(|_| ()) - .chain_err(|| ErrorKind::SetIpError) + .map_err(Error::SetIpv6Error) } } } } - fn set_up(&mut self, up: bool) -> Result<()> { - self.dev - .enabled(up) - .chain_err(|| ErrorKind::ToggleDeviceError) + fn set_up(&mut self, up: bool) -> Result<(), Error> { + self.dev.enabled(up).map_err(Error::ToggleDeviceError) } - fn set_mtu(&mut self, mtu: u16) -> Result<()> { + fn set_mtu(&mut self, mtu: u16) -> Result<(), Error> { self.dev .set_mtu(i32::from(mtu)) - .chain_err(|| ErrorKind::ToggleDeviceError) + .map_err(Error::ToggleDeviceError) } fn get_name(&self) -> &str { diff --git a/talpid-core/src/routing/linux.rs b/talpid-core/src/routing/linux.rs index 4c4712ac1e..73de509a0e 100644 --- a/talpid-core/src/routing/linux.rs +++ b/talpid-core/src/routing/linux.rs @@ -1,21 +1,30 @@ use super::{NetNode, RequiredRoutes, Route}; use super::subprocess::{Exec, RunExpr}; -use std::{collections::HashSet, net::IpAddr}; +use std::{ + collections::HashSet, + io, + net::{AddrParseError, IpAddr}, +}; +pub type Result<T> = std::result::Result<T, Error>; -error_chain! { - errors { - FailedToAddRoute { - description("Failed to add route") - } - FailedToRemoveRoute { - description("Failed to remove route") - } - FailedToGetDefaultRoute { - description("Failed to get default route") - } - } +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "Failed to add route")] + FailedToAddRoute(#[error(cause)] io::Error), + + #[error(display = "Failed to remove route")] + FailedToRemoveRoute(#[error(cause)] io::Error), + + #[error(display = "Error while running \"ip route\"")] + FailedToRunIp(#[error(cause)] io::Error), + + #[error(display = "No default route in \"ip route\" output")] + NoDefaultRoute, + + #[error(display = "Failed to parse default route as IP: {}", _0)] + ParseDefaultRoute(String, #[error(cause)] AddrParseError), } @@ -42,7 +51,7 @@ impl RouteManager { cmd.into_expr() .run_expr() - .chain_err(|| ErrorKind::FailedToAddRoute)?; + .map_err(Error::FailedToAddRoute)?; self.added_routes.insert(route); Ok(()) @@ -99,7 +108,7 @@ impl super::RoutingT for RouteManager { route.prefix.to_string() ) .run_expr() - .chain_err(|| ErrorKind::FailedToRemoveRoute); + .map_err(Error::FailedToRemoveRoute); if let Err(e) = result { log::error!("Failed to remove route {} - {}", route.prefix, e); end_result = Err(e); @@ -112,15 +121,15 @@ impl super::RoutingT for RouteManager { fn get_default_route_node(&mut self) -> Result<IpAddr> { let output = duct::cmd!("ip", "route") .stdout() - .chain_err(|| ErrorKind::FailedToGetDefaultRoute)?; + .map_err(Error::FailedToRunIp)?; let ip_str: &str = output .lines() .find(|line| line.trim().starts_with("default via ")) .and_then(|line| line.trim().split_whitespace().nth(2)) - .ok_or_else(|| Error::from(ErrorKind::FailedToGetDefaultRoute))?; + .ok_or(Error::NoDefaultRoute)?; ip_str .parse() - .map_err(|_| Error::from(ErrorKind::FailedToGetDefaultRoute)) + .map_err(|e| Error::ParseDefaultRoute(ip_str.to_owned(), e)) } } diff --git a/talpid-core/src/routing/macos.rs b/talpid-core/src/routing/macos.rs index 582c453439..d0e9497c1c 100644 --- a/talpid-core/src/routing/macos.rs +++ b/talpid-core/src/routing/macos.rs @@ -1,22 +1,31 @@ use super::{NetNode, RequiredRoutes, Route}; use super::subprocess::{Exec, RunExpr}; -use std::{collections::HashSet, net::IpAddr}; +use std::{ + collections::HashSet, + io, + net::{AddrParseError, IpAddr}, +}; -error_chain! { - errors { - FailedToAddRoute { - description("Failed to add route") - } - FailedToGetDefaultRoute { - description("Failed to get default route") - } +pub type Result<T> = std::result::Result<T, Error>; - FailedToRemoveRoute { - description("Failed to remove route") - } - } +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "Failed to add route")] + FailedToAddRoute(#[error(cause)] io::Error), + + #[error(display = "Failed to remove route")] + FailedToRemoveRoute(#[error(cause)] io::Error), + + #[error(display = "Error while running \"ip route\"")] + FailedToRunIp(#[error(cause)] io::Error), + + #[error(display = "No default route in \"ip route\" output")] + NoDefaultRoute, + + #[error(display = "Failed to parse default route as IP: {}", _0)] + ParseDefaultRoute(String, #[error(cause)] AddrParseError), } pub struct RouteManager { @@ -51,7 +60,7 @@ impl RouteManager { cmd.into_expr() .run_expr() - .chain_err(|| ErrorKind::FailedToAddRoute)?; + .map_err(Error::FailedToAddRoute)?; self.set_routes.insert(route); Ok(()) } @@ -96,7 +105,7 @@ impl super::RoutingT for RouteManager { route.prefix.to_string() ) .run_expr() - .chain_err(|| ErrorKind::FailedToRemoveRoute); + .map_err(Error::FailedToRemoveRoute); if let Err(e) = result { log::error!("failed to reset remove route: {}", e); end_result = Err(e); @@ -110,15 +119,15 @@ impl super::RoutingT for RouteManager { fn get_default_route_node(&mut self) -> Result<IpAddr> { let output = duct::cmd!("route", "-n", "get", "default") .stdout() - .chain_err(|| ErrorKind::FailedToGetDefaultRoute)?; + .map_err(Error::FailedToRunIp)?; let ip_str: &str = output .lines() .find(|line| line.trim().starts_with("gateway: ")) .and_then(|line| line.trim().split_whitespace().skip(1).next()) - .ok_or(Error::from(ErrorKind::FailedToGetDefaultRoute))?; + .ok_or(Error::NoDefaultRoute)?; ip_str .parse() - .map_err(|_| Error::from(ErrorKind::FailedToGetDefaultRoute)) + .map_err(|e| Error::ParseDefaultRoute(ip_str.to_owned(), e)) } } |
