diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-02-01 12:24:38 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-02-01 12:24:38 +0100 |
| commit | 86ea31a4a3a9d6f4c23043abd993a42170eb2ed2 (patch) | |
| tree | 6e3777aa027102ad710f9e965b628bf8c1a9ead8 /talpid-core/src | |
| parent | c697a40bb0534b2f8e3f9b94b0580bb7f079892d (diff) | |
| download | mullvadvpn-86ea31a4a3a9d6f4c23043abd993a42170eb2ed2.tar.xz mullvadvpn-86ea31a4a3a9d6f4c23043abd993a42170eb2ed2.zip | |
Fix dns/firewall code to work with new structure
Diffstat (limited to 'talpid-core/src')
| -rw-r--r-- | talpid-core/src/dns/linux/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/systemd_resolved.rs | 3 | ||||
| -rw-r--r-- | talpid-core/src/dns/macos.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/dns/mod.rs | 47 | ||||
| -rw-r--r-- | talpid-core/src/dns/windows.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/lib.rs | 7 | ||||
| -rw-r--r-- | talpid-core/src/linux.rs | 24 | ||||
| -rw-r--r-- | talpid-core/src/security/linux.rs | 23 | ||||
| -rw-r--r-- | talpid-core/src/security/mod.rs | 48 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 6 |
10 files changed, 89 insertions, 75 deletions
diff --git a/talpid-core/src/dns/linux/mod.rs b/talpid-core/src/dns/linux/mod.rs index 74267e2c19..17ec6b7e39 100644 --- a/talpid-core/src/dns/linux/mod.rs +++ b/talpid-core/src/dns/linux/mod.rs @@ -31,7 +31,7 @@ pub struct DnsMonitor { inner: Option<DnsMonitorHolder>, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; fn new(_cache_dir: impl AsRef<Path>) -> Result<Self> { diff --git a/talpid-core/src/dns/linux/systemd_resolved.rs b/talpid-core/src/dns/linux/systemd_resolved.rs index f4eac9e486..6734a1819c 100644 --- a/talpid-core/src/dns/linux/systemd_resolved.rs +++ b/talpid-core/src/dns/linux/systemd_resolved.rs @@ -1,4 +1,5 @@ -use super::{super::iface_index, RESOLV_CONF_PATH}; +use super::RESOLV_CONF_PATH; +use crate::linux::iface_index; use dbus::{ arg::RefArg, stdintf::*, BusType, Interface, Member, Message, MessageItem, MessageItemArray, Signature, diff --git a/talpid-core/src/dns/macos.rs b/talpid-core/src/dns/macos.rs index a1fad021de..d65fdbf6c0 100644 --- a/talpid-core/src/dns/macos.rs +++ b/talpid-core/src/dns/macos.rs @@ -126,7 +126,7 @@ pub struct DnsMonitor { state: Arc<Mutex<Option<State>>>, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; /// Creates and returns a new `DnsMonitor`. This spawns a background thread that will monitor diff --git a/talpid-core/src/dns/mod.rs b/talpid-core/src/dns/mod.rs index a997abd665..2631be00a9 100644 --- a/talpid-core/src/dns/mod.rs +++ b/talpid-core/src/dns/mod.rs @@ -1,3 +1,5 @@ +use std::{net::IpAddr, path::Path}; + #[cfg(target_os = "macos")] #[path = "macos.rs"] mod imp; @@ -10,6 +12,47 @@ mod imp; #[path = "windows.rs"] mod imp; -pub use self::imp::{DnsError, Error}; +pub use self::imp::Error; + +/// Sets and monitors system DNS settings. Makes sure the desired DNS servers are being used. +pub struct DnsMonitor { + inner: imp::DnsMonitor, +} + +impl DnsMonitor { + /// Returns a new `DnsMonitor` that can set and monitor the system DNS. + pub fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Error> { + Ok(DnsMonitor { + inner: imp::DnsMonitor::new(cache_dir)?, + }) + } + + /// Set DNS to the given servers. And start monitoring the system for changes. + pub fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Error> { + log::info!( + "Setting DNS servers to {}", + servers + .iter() + .map(|ip| ip.to_string()) + .collect::<Vec<String>>() + .join(", ") + ); + self.inner.set(interface, servers) + } + + /// Reset system DNS settings to what it was before being set by this instance. + pub fn reset(&mut self) -> Result<(), Error> { + log::info!("Resetting DNS"); + self.inner.reset() + } +} + +trait DnsMonitorT: Sized { + type Error: ::std::error::Error; + + fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Self::Error>; + + fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Self::Error>; -pub use self::imp::{DnsMonitor, Error as DnsError};
\ No newline at end of file + fn reset(&mut self) -> Result<(), Self::Error>; +} diff --git a/talpid-core/src/dns/windows.rs b/talpid-core/src/dns/windows.rs index 6c04c03e57..6f7cf3f07f 100644 --- a/talpid-core/src/dns/windows.rs +++ b/talpid-core/src/dns/windows.rs @@ -47,7 +47,7 @@ pub struct DnsMonitor { backup_writer: SystemStateWriter, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; fn new(cache_dir: impl AsRef<Path>) -> Result<Self> { diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs index 437fb2ff6f..f0337970c5 100644 --- a/talpid-core/src/lib.rs +++ b/talpid-core/src/lib.rs @@ -40,7 +40,14 @@ pub mod mpsc; /// Abstractions over operating system network security settings. pub mod security; +/// Abstractions over operating system DNS settings. +pub mod dns; + /// State machine to handle tunnel configuration. pub mod tunnel_state_machine; mod mktemp; + +/// Misc utilities for the Linux platform. +#[cfg(target_os = "linux")] +mod linux; diff --git a/talpid-core/src/linux.rs b/talpid-core/src/linux.rs new file mode 100644 index 0000000000..2822d5837b --- /dev/null +++ b/talpid-core/src/linux.rs @@ -0,0 +1,24 @@ +use std::{ffi::{self, CString}, io}; + +/// Converts an interface name into the corresponding index. +pub fn iface_index(name: &str) -> Result<libc::c_uint, IfaceIndexLookupError> { + let c_name = CString::new(name) + .map_err(|e| IfaceIndexLookupError::InvalidInterfaceName(name.to_owned(), e))?; + let index = unsafe { libc::if_nametoindex(c_name.as_ptr()) }; + if index == 0 { + Err(IfaceIndexLookupError::InterfaceLookupError( + name.to_owned(), + io::Error::last_os_error(), + )) + } else { + Ok(index) + } +} + +#[derive(Debug, err_derive::Error)] +pub enum IfaceIndexLookupError { + #[error(display = "Invalid network interface name: {}", _0)] + InvalidInterfaceName(String, #[error(cause)] ffi::NulError), + #[error(display = "Failed to get index for interface {}", _0)] + InterfaceLookupError(String, #[error(cause)] io::Error), +} diff --git a/talpid-core/src/security/linux.rs b/talpid-core/src/security/linux.rs index 464ed515f1..7f25e8c9f8 100644 --- a/talpid-core/src/security/linux.rs +++ b/talpid-core/src/security/linux.rs @@ -11,7 +11,6 @@ use nftnl::{ use std::{ env, ffi::{CStr, CString}, - io, net::{IpAddr, Ipv4Addr}, }; use talpid_types::net::{Endpoint, TransportProtocol}; @@ -29,15 +28,13 @@ error_chain! { /// Failed to verify that our tables are set. Probably means that /// it's the host does not support nftables properly. NetfilterTableNotSetError{ description("Failed to set firewall rules") } - /// The name is not a valid Linux network interface name - InvalidInterfaceName(name: String) { - description("Invalid network interface name") - display("Invalid network interface name: {}", name) - } } links { Nftnl(nftnl::Error, nftnl::ErrorKind) #[doc = "Error in nftnl"]; } + foreign_links { + IfaceIndexLookupError(crate::linux::IfaceIndexLookupError); + } } lazy_static! { @@ -416,7 +413,7 @@ fn allow_interface_rule<'a>( } fn check_iface(rule: &mut Rule, direction: Direction, iface: &str) -> Result<()> { - let iface_index = iface_index(iface)?; + let iface_index = crate::linux::iface_index(iface)?; rule.add_expr(&match direction { Direction::In => nft_expr!(meta iif), Direction::Out => nft_expr!(meta oif), @@ -425,18 +422,6 @@ fn check_iface(rule: &mut Rule, direction: Direction, iface: &str) -> Result<()> Ok(()) } -fn iface_index(name: &str) -> Result<libc::c_uint> { - let c_name = - CString::new(name).chain_err(|| ErrorKind::InvalidInterfaceName(name.to_owned()))?; - let index = unsafe { libc::if_nametoindex(c_name.as_ptr()) }; - if index == 0 { - let error = io::Error::last_os_error(); - Err(error).chain_err(|| ErrorKind::InvalidInterfaceName(name.to_owned())) - } else { - Ok(index) - } -} - fn check_net(rule: &mut Rule, end: End, net: IpNetwork) -> Result<()> { // Must check network layer protocol before loading network layer payload check_l3proto(rule, net.ip())?; diff --git a/talpid-core/src/security/mod.rs b/talpid-core/src/security/mod.rs index 10ad9d8556..75bb4cef87 100644 --- a/talpid-core/src/security/mod.rs +++ b/talpid-core/src/security/mod.rs @@ -4,7 +4,7 @@ use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; use lazy_static::lazy_static; #[cfg(unix)] use std::net::{Ipv4Addr, Ipv6Addr}; -use std::{fmt, net::IpAddr, path::Path}; +use std::{fmt, net::IpAddr}; use talpid_types::net::Endpoint; @@ -20,6 +20,8 @@ mod imp; #[path = "windows/mod.rs"] mod imp; +pub use self::imp::Error; + #[cfg(unix)] lazy_static! { @@ -138,40 +140,6 @@ impl NetworkSecurity { } } -/// Sets and monitors system DNS settings. Makes sure the desired DNS servers are being used. -pub struct DnsMonitor { - inner: imp::DnsMonitor, -} - -impl DnsMonitor { - /// Returns a new `DnsMonitor` that can set and monitor the system DNS. - pub fn new(cache_dir: impl AsRef<Path>) -> Result<Self, DnsError> { - Ok(DnsMonitor { - inner: imp::DnsMonitor::new(cache_dir)?, - }) - } - - /// Set DNS to the given servers. And start monitoring the system for changes. - pub fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), DnsError> { - log::info!( - "Setting DNS servers to {}", - servers - .iter() - .map(|ip| ip.to_string()) - .collect::<Vec<String>>() - .join(", ") - ); - self.inner.set(interface, servers) - } - - /// Reset system DNS settings to what it was before being set by this instance. - pub fn reset(&mut self) -> Result<(), DnsError> { - log::info!("Resetting DNS"); - self.inner.reset() - } -} - - /// Abstract firewall interaction trait. Used by the OS specific implementations. trait NetworkSecurityT: Sized { /// The error type thrown by the implementer of this trait @@ -187,13 +155,3 @@ trait NetworkSecurityT: Sized { /// modifying the system. fn reset_policy(&mut self) -> ::std::result::Result<(), Self::Error>; } - -trait DnsMonitorT: Sized { - type Error: ::std::error::Error; - - fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Self::Error>; - - fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Self::Error>; - - fn reset(&mut self) -> Result<(), Self::Error>; -} diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 8e20e3a159..5226c315e8 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -29,11 +29,7 @@ use self::{ disconnected_state::DisconnectedState, disconnecting_state::{AfterDisconnect, DisconnectingState}, }; -use crate::{ - mpsc::IntoSender, - offline, - security::{DnsMonitor, NetworkSecurity}, -}; +use crate::{dns::DnsMonitor, mpsc::IntoSender, offline, security::NetworkSecurity}; error_chain! { errors { |
