diff options
| author | Odd Stranne <odd@mullvad.net> | 2019-09-04 12:04:18 +0200 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2019-09-05 10:19:08 +0200 |
| commit | fd56752bf7a5b86d19c52dba56c7677d27aacf8d (patch) | |
| tree | 3921038c932af4de4c40119f5b85f3b0f9f7c556 | |
| parent | e2ef1227283c252ec5a7190ed9b4bd278405fa9b (diff) | |
| download | mullvadvpn-fd56752bf7a5b86d19c52dba56c7677d27aacf8d.tar.xz mullvadvpn-fd56752bf7a5b86d19c52dba56c7677d27aacf8d.zip | |
Adjust Rust code responsible for setting DNS
| -rw-r--r-- | talpid-core/src/dns/windows/mod.rs | 107 | ||||
| -rw-r--r-- | talpid-core/src/dns/windows/system_state.rs | 78 |
2 files changed, 20 insertions, 165 deletions
diff --git a/talpid-core/src/dns/windows/mod.rs b/talpid-core/src/dns/windows/mod.rs index 74cef023e5..d04e5b8b00 100644 --- a/talpid-core/src/dns/windows/mod.rs +++ b/talpid-core/src/dns/windows/mod.rs @@ -1,4 +1,4 @@ -use log::{debug, error, info, trace, warn}; +use log::{error, info, trace}; use std::{ borrow::Borrow, net::IpAddr, @@ -28,19 +28,9 @@ pub enum Error { /// Failure to set new DNS servers. #[error(display = "Failed to set new DNS servers")] Setting, - - /// Failure to reset DNS settings. - #[error(display = "Failed to reset DNS")] - Resetting, - - /// Failure to reset DNS settings from backup. - #[error(display = "Failed to recover to backed up system state")] - Recovery, } -pub struct DnsMonitor { - backup_writer: SystemStateWriter, -} +pub struct DnsMonitor {} impl super::DnsMonitorT for DnsMonitor { type Error = Error; @@ -54,12 +44,11 @@ impl super::DnsMonitorT for DnsMonitor { .join(DNS_STATE_FILENAME) .into_boxed_path(), ); - let mut dns = DnsMonitor { backup_writer }; - dns.restore_system_backup(); - Ok(dns) + let _ = backup_writer.remove_backup(); + Ok(DnsMonitor {}) } - fn set(&mut self, _interface: &str, servers: &[IpAddr]) -> Result<(), Error> { + fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Error> { let ipv4 = servers .iter() .filter(|ip| ip.is_ipv4()) @@ -71,7 +60,6 @@ impl super::DnsMonitorT for DnsMonitor { .map(ip_to_widestring) .collect::<Vec<_>>(); - let mut ipv4_address_ptrs = ipv4 .iter() .map(|ip_cstr| ip_cstr.as_ptr()) @@ -86,52 +74,21 @@ impl super::DnsMonitorT for DnsMonitor { unsafe { WinDns_Set( + WideCString::from_str(interface).unwrap().as_ptr(), ipv4_address_ptrs.as_mut_ptr(), ipv4_address_ptrs.len() as u32, ipv6_address_ptrs.as_mut_ptr(), ipv6_address_ptrs.len() as u32, - Some(write_system_state_backup_cb), - &self.backup_writer as *const _ as *const c_void, ) .into_result() } } fn reset(&mut self) -> Result<(), Error> { - unsafe { WinDns_Reset().into_result()? }; - - if let Err(e) = self.backup_writer.remove_backup() { - warn!("Failed to remove DNS state backup file: {}", e); - } Ok(()) } } -impl DnsMonitor { - 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) { - 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), - } - } -} - fn ip_to_widestring(ip: &IpAddr) -> WideCString { WideCString::new(ip.to_string().encode_utf16().collect::<Vec<_>>()).unwrap() } @@ -189,47 +146,8 @@ impl Drop for DnsMonitor { 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 -pub extern "system" fn write_system_state_backup_cb( - blob: *const u8, - length: u32, - state_writer_ptr: *mut c_void, -) -> i32 { - let state_writer = state_writer_ptr as *mut SystemStateWriter; - if state_writer.is_null() { - error!("State writer pointer is null, can't save system state backup"); - return -1; - } - - unsafe { - trace!( - "Writing {} bytes to store system state backup to {}", - length, - (*state_writer).backup_path.to_string_lossy() - ); - let data = slice::from_raw_parts(blob, length as usize); - match (*state_writer).write_backup(data) { - Ok(()) => 0, - Err(e) => { - error!( - "Failed to write system state backup to {} because {}", - (*state_writer).backup_path.to_string_lossy(), - e - ); - e.raw_os_error().unwrap_or(-1) - } - } - } -} - - -type DNSConfigSink = - extern "system" fn(data: *const u8, length: u32, state_writer: *mut c_void) -> i32; - // This callback can be called from multiple threads concurrently, thus if there ever is a real // context object passed around, it should probably implement Sync. type ErrorSink = extern "system" fn( @@ -258,21 +176,10 @@ extern "system" { // Configure which DNS servers should be used and start enforcing these settings. #[link_name = "WinDns_Set"] pub fn WinDns_Set( + interface_alias: *const u16, v4_ips: *mut *const u16, v4_n_ips: u32, v6_ips: *mut *const u16, v6_n_ips: u32, - callback: Option<DNSConfigSink>, - backup_writer: *const c_void, ) -> SettingResult; - - // Revert server settings to what they were before calling WinDns_Set. - // - // (Also taking into account external changes to DNS settings that have ocurred - // during the period of enforcing specific settings.) - #[link_name = "WinDns_Reset"] - pub fn WinDns_Reset() -> ResettingResult; - - #[link_name = "WinDns_Recover"] - pub fn WinDns_Recover(data: *const u8, length: u32) -> RecoverResult; } diff --git a/talpid-core/src/dns/windows/system_state.rs b/talpid-core/src/dns/windows/system_state.rs index f2557e7cf7..36ad49793b 100644 --- a/talpid-core/src/dns/windows/system_state.rs +++ b/talpid-core/src/dns/windows/system_state.rs @@ -1,11 +1,7 @@ //! A writer for a blob that would persistently store the system state. Useful //! for when the application of a secuirty policy proves to be persistent across //! reboots -use std::{ - fs::{self, File}, - io::{self, Write}, - path::Path, -}; +use std::{fs, io, path::Path}; /// This struct is responsible for saving a binary blob to disk. The binary blob is intended to /// store system DNS settings that should be restored when the DNS settings are reset. @@ -23,24 +19,6 @@ impl SystemStateWriter { } } - /// Writes a binary blob representing the system DNS settings to the backup location before any - /// DNS changes are applied. - pub fn write_backup(&self, data: &[u8]) -> io::Result<()> { - let mut backup_file = File::create(&self.backup_path)?; - backup_file.write_all(data)?; - backup_file.sync_all() - } - - pub fn read_backup(&self) -> io::Result<Option<Vec<u8>>> { - match fs::read(&self.backup_path).map(|blob| Some(blob)) { - Ok(b) => Ok(b), - Err(e) => match e.kind() { - io::ErrorKind::NotFound => Ok(None), - _ => Err(e), - }, - } - } - /// Removes a previously created state backup if it exists. pub fn remove_backup(&self) -> io::Result<()> { match fs::remove_file(&self.backup_path) { @@ -59,40 +37,28 @@ impl SystemStateWriter { #[cfg(test)] mod tests { use super::*; + use fs::{self, File}; + use std::io::prelude::*; #[test] - fn can_create_backup() { - let temp_dir = tempfile::tempdir().expect("failed to crate temp dir"); + fn can_remove_backup() { + let temp_dir = tempfile::tempdir().expect("failed to create temp dir"); let temp_file = temp_dir.path().join("test_file"); - let mock_system_state: Vec<_> = b"8.8.8.8\n8.8.4.4\n".to_vec(); - let writer = SystemStateWriter::new(&temp_file); - writer - .write_backup(&mock_system_state) - .expect("failed to write system state"); - - let backup = writer - .read_backup() - .expect("error when reading system state backup") - .expect("expected to read system state backup"); - assert_eq!(backup, mock_system_state); - } - - #[test] - fn can_succeed_without_backup() { - let temp_dir = tempfile::tempdir().expect("failed to crate temp dir"); - let temp_file = temp_dir.path().join("test_file"); + let mut file_handle = File::create(&temp_file).expect("failed to create dummy backup file"); + file_handle + .write_all(b"Hello, world!") + .expect("failed to write to dummy backup file"); let writer = SystemStateWriter::new(&temp_file); - let backup = writer - .read_backup() - .expect("error when reading system state backup"); - assert_eq!(backup, None); + writer + .remove_backup() + .expect("failed to remove backup file"); } #[test] fn can_remove_when_no_backup_exists() { - let temp_dir = tempfile::tempdir().expect("failed to crate temp dir"); + let temp_dir = tempfile::tempdir().expect("failed to create temp dir"); let temp_file = temp_dir.path().join("test_file"); let writer = SystemStateWriter::new(&temp_file); @@ -100,22 +66,4 @@ mod tests { .remove_backup() .expect("Encountered IO error when running remove_backup when no state file exists"); } - - #[test] - fn can_remove_backup() { - let temp_dir = tempfile::tempdir().expect("failed to crate temp dir"); - let temp_file = temp_dir.path().join("test_file"); - let writer = SystemStateWriter::new(&temp_file); - let mock_system_state = b"8.8.8.8\n8.8.4.4\n".to_vec(); - - writer - .write_backup(&mock_system_state) - .expect("Failed to write backup"); - writer.remove_backup().expect("Failed to remove state file"); - - let empty_backup = writer - .read_backup() - .expect("Encountered IO error when no backup file exists"); - assert_eq!(empty_backup, None); - } } |
