diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-03-29 14:31:30 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-03-29 18:24:27 +0100 |
| commit | bf6a9a7ed566c663107eb865fa4ff53ae33bc19a (patch) | |
| tree | 999912a29c48c755c0fc00f88142d47046a07b44 | |
| parent | 3bda600c843903696cbf33f2142167b87831ac4a (diff) | |
| download | mullvadvpn-bf6a9a7ed566c663107eb865fa4ff53ae33bc19a.tar.xz mullvadvpn-bf6a9a7ed566c663107eb865fa4ff53ae33bc19a.zip | |
Get rid of error-chain in Linux DNS module
| -rw-r--r-- | Cargo.lock | 13 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/mod.rs | 41 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/network_manager.rs | 48 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/resolvconf.rs | 58 |
5 files changed, 90 insertions, 71 deletions
diff --git a/Cargo.lock b/Cargo.lock index fc76a682b5..e4fac23be8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -306,6 +306,17 @@ dependencies = [ ] [[package]] +name = "derive_more" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "digest" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1970,6 +1981,7 @@ version = "0.1.0" dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "dbus 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "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)", @@ -2633,6 +2645,7 @@ dependencies = [ "checksum derive-try-from-primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81dbd65eb15734b6d50dc6ac86f14f928462be0a5df6bda17761e909071ede5d" "checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439" "checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757" +"checksum derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbe9f11be34f800b3ecaaed0ec9ec2e015d1d0ba0c8644c1310f73d6e8994615" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum duct 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3640af123c78bedc20c1d3928e43cc0621e57011899d1ef917900c12fdb7a1ee" diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index d7116a7457..1d2e0f5276 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [dependencies] atty = "0.2" +derive_more = "0.14" duct = "0.12" error-chain = "0.12" err-derive = "0.1.5" diff --git a/talpid-core/src/dns/linux/mod.rs b/talpid-core/src/dns/linux/mod.rs index 17ec6b7e39..5f378875f4 100644 --- a/talpid-core/src/dns/linux/mod.rs +++ b/talpid-core/src/dns/linux/mod.rs @@ -12,19 +12,30 @@ use std::{env, fmt, net::IpAddr, path::Path}; const RESOLV_CONF_PATH: &str = "/etc/resolv.conf"; -error_chain! { - errors { - NoDnsMonitor { - description("No suitable DNS monitor implementation detected") - } - } +pub type Result<T> = std::result::Result<T, Error>; - links { - Resolvconf(resolvconf::Error, resolvconf::ErrorKind); - StaticResolvConf(static_resolv_conf::Error, static_resolv_conf::ErrorKind); - SystemdResolved(systemd_resolved::Error, systemd_resolved::ErrorKind); - NetworkManager(network_manager::Error, network_manager::ErrorKind); - } +/// Errors that can happen in the Linux DNS monitor +#[derive(err_derive::Error, derive_more::From, Debug)] +pub enum Error { + /// Error in systemd-resolved DNS monitor + #[error(display = "Error in systemd-resolved DNS monitor")] + SystemdResolved(#[error(cause)] systemd_resolved::Error), + + /// Error in NetworkManager DNS monitor + #[error(display = "Error in NetworkManager DNS monitor")] + NetworkManager(#[error(cause)] network_manager::Error), + + /// Error in resolvconf DNS monitor + #[error(display = "Error in resolvconf DNS monitor")] + Resolvconf(#[error(cause)] resolvconf::Error), + + /// Error in static /etc/resolv.conf DNS monitor + #[error(display = "Error in static /etc/resolv.conf DNS monitor")] + StaticResolvConf(#[error(cause)] static_resolv_conf::Error), + + /// No suitable DNS monitor implementation detected + #[error(display = "No suitable DNS monitor implementation detected")] + NoDnsMonitor, } pub struct DnsMonitor { @@ -56,10 +67,10 @@ impl super::DnsMonitorT for DnsMonitor { } pub enum DnsMonitorHolder { - Resolvconf(Resolvconf), - StaticResolvConf(StaticResolvConf), SystemdResolved(SystemdResolved), NetworkManager(NetworkManager), + Resolvconf(Resolvconf), + StaticResolvConf(StaticResolvConf), } impl fmt::Display for DnsMonitorHolder { @@ -96,7 +107,7 @@ impl DnsMonitorHolder { .or_else(|_| NetworkManager::new().map(DnsMonitorHolder::NetworkManager)) .or_else(|_| Resolvconf::new().map(DnsMonitorHolder::Resolvconf)) .or_else(|_| StaticResolvConf::new().map(DnsMonitorHolder::StaticResolvConf)) - .chain_err(|| ErrorKind::NoDnsMonitor) + .map_err(|_| Error::NoDnsMonitor) } fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<()> { diff --git a/talpid-core/src/dns/linux/network_manager.rs b/talpid-core/src/dns/linux/network_manager.rs index d42bb4efab..46777e8223 100644 --- a/talpid-core/src/dns/linux/network_manager.rs +++ b/talpid-core/src/dns/linux/network_manager.rs @@ -3,7 +3,6 @@ use dbus::{ stdintf::*, BusType, }; -use error_chain::ChainedError; use std::{ collections::HashMap, fs::File, @@ -12,22 +11,21 @@ use std::{ path::Path, }; -error_chain! { - errors { - NoNetworkManager { - description("NetworkManager not detected") - } - NmTooOld { - description("NetworkManager is too old") - } - NmNotManagingDns{ - description("NetworkManager is not managing DNS") - } - } +pub type Result<T> = std::result::Result<T, Error>; - foreign_links { - DbusError(dbus::Error); - } +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "NetworkManager not detected")] + NetworkManagerNotDetected(#[error(cause)] dbus::Error), + + #[error(display = "NetworkManager is too old")] + TooOldNetworkManager(#[error(cause)] dbus::Error), + + #[error(display = "NetworkManager is not managing DNS")] + NetworkManagerNotManagingDns, + + #[error(display = "Error while communicating over Dbus")] + Dbus(#[error(cause)] dbus::Error), } const NM_BUS: &str = "org.freedesktop.NetworkManager"; @@ -46,7 +44,8 @@ pub struct NetworkManager { impl NetworkManager { pub fn new() -> Result<Self> { - let dbus_connection = dbus::Connection::get_private(BusType::System)?; + let dbus_connection = + dbus::Connection::get_private(BusType::System).map_err(Error::Dbus)?; let manager = NetworkManager { dbus_connection }; manager.ensure_network_manager_exists()?; manager.ensure_resolv_conf_is_managed()?; @@ -57,7 +56,7 @@ impl NetworkManager { let _: Box<RefArg> = self .as_manager() .get(&NM_TOP_OBJECT, GLOBAL_DNS_CONF_KEY) - .chain_err(|| ErrorKind::NoNetworkManager)?; + .map_err(Error::NetworkManagerNotDetected)?; Ok(()) } @@ -67,16 +66,13 @@ impl NetworkManager { .dbus_connection .with_path(NM_BUS, NM_DNS_MANAGER_PATH, RPC_TIMEOUT_MS) .get(NM_DNS_MANAGER, RC_MANAGEMENT_MODE_KEY) - .chain_err(|| ErrorKind::NmTooOld); + .map_err(Error::TooOldNetworkManager); match management_mode { - Err(e) => { - log::debug!("Failed to get NM management mode - {}", e.display_chain()); - return Err(e); - } + Err(e) => return Err(e), Ok(management_mode) => { if management_mode == "unmanaged" { - return Err(Error::from(ErrorKind::NmNotManagingDns)); + return Err(Error::NetworkManagerNotManagingDns); } } } @@ -85,7 +81,7 @@ impl NetworkManager { let actual_resolv_conf = "/etc/resolv.conf"; if !eq_file_content(&expected_resolv_conf, &actual_resolv_conf) { log::debug!("/etc/resolv.conf differs from reference resolv.conf, therefore NM is not managing DNS"); - bail!(ErrorKind::NmNotManagingDns); + return Err(Error::NetworkManagerNotManagingDns); } Ok(()) @@ -103,7 +99,7 @@ impl NetworkManager { fn set_global_dns(&mut self, config: GlobalDnsConfig) -> Result<()> { self.as_manager() .set(NM_TOP_OBJECT, GLOBAL_DNS_CONF_KEY, config) - .map_err(|e| e.into()) + .map_err(Error::Dbus) } pub fn reset(&mut self) -> Result<()> { diff --git a/talpid-core/src/dns/linux/resolvconf.rs b/talpid-core/src/dns/linux/resolvconf.rs index 32b8fcd6b9..14ce3107a1 100644 --- a/talpid-core/src/dns/linux/resolvconf.rs +++ b/talpid-core/src/dns/linux/resolvconf.rs @@ -1,31 +1,30 @@ use std::{ collections::HashSet, ffi::OsStr, - fs, + fs, io, net::IpAddr, path::{Path, PathBuf}, }; use which::which; -error_chain! { - errors { - NoResolvconf { - description("Failed to detect 'resolvconf' program") - } - ResolvconfUsesResolved { - description("The existing resolvconf binary is just a symlink to systemd-resolved") - } - RunResolvconf { - description("Failed to execute 'resolvconf' program") - } - AddRecordError(stderr: String) { - description("Using 'resolvconf' to add a record failed") - display("Using 'resolvconf' to add a record failed: {}", stderr) - } - DeleteRecordError { - description("Using 'resolvconf' to delete a record failed") - } - } +pub type Result<T> = std::result::Result<T, Error>; + +#[derive(err_derive::Error, Debug)] +pub enum Error { + #[error(display = "Failed to detect 'resolvconf' program")] + NoResolvconf, + + #[error(display = "The resolvconf in PATH is just a symlink to systemd-resolved")] + ResolvconfUsesResolved, + + #[error(display = "Failed to execute 'resolvconf' program")] + RunResolvconf(#[error(cause)] io::Error), + + #[error(display = "Using 'resolvconf' to add a record failed: {}", stderr)] + AddRecordError { stderr: String }, + + #[error(display = "Using 'resolvconf' to delete a record failed")] + DeleteRecordError, } pub struct Resolvconf { @@ -35,10 +34,9 @@ pub struct Resolvconf { impl Resolvconf { pub fn new() -> Result<Self> { - let resolvconf_path = - which("resolvconf").map_err(|_| Error::from(ErrorKind::NoResolvconf))?; + let resolvconf_path = which("resolvconf").map_err(|_| Error::NoResolvconf)?; if Self::resolvconf_is_resolved_symlink(&resolvconf_path) { - bail!(ErrorKind::ResolvconfUsesResolved); + return Err(Error::ResolvconfUsesResolved); } Ok(Resolvconf { record_names: HashSet::new(), @@ -69,12 +67,12 @@ impl Resolvconf { .stderr_capture() .unchecked() .run() - .chain_err(|| ErrorKind::RunResolvconf)?; + .map_err(Error::RunResolvconf)?; - ensure!( - output.status.success(), - ErrorKind::AddRecordError(String::from_utf8_lossy(&output.stderr).to_string()) - ); + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr).to_string(); + return Err(Error::AddRecordError { stderr }); + } self.record_names.insert(record_name); @@ -89,7 +87,7 @@ impl Resolvconf { .stderr_capture() .unchecked() .run() - .chain_err(|| ErrorKind::RunResolvconf)?; + .map_err(Error::RunResolvconf)?; if !output.status.success() { log::error!( @@ -97,7 +95,7 @@ impl Resolvconf { record_name, String::from_utf8_lossy(&output.stderr) ); - result = Err(Error::from(ErrorKind::DeleteRecordError)); + result = Err(Error::DeleteRecordError); } } |
