diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-10-24 15:09:28 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-10-24 18:00:35 +0200 |
| commit | 0b49d7c1e1fbbb10ef0f2c9408eeba4e3f54a026 (patch) | |
| tree | cd8fa20bc26657aae636c03280aba31395c245ff /talpid-core/src | |
| parent | 4c811088dc9f4ac90f5bf6146d8ea71ec5dc9b6c (diff) | |
| download | mullvadvpn-0b49d7c1e1fbbb10ef0f2c9408eeba4e3f54a026.tar.xz mullvadvpn-0b49d7c1e1fbbb10ef0f2c9408eeba4e3f54a026.zip | |
Configure DNS port in SCDynamicStore
Diffstat (limited to 'talpid-core/src')
| -rw-r--r-- | talpid-core/src/dns/macos.rs | 43 | ||||
| -rw-r--r-- | talpid-core/src/dns/mod.rs | 13 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 8 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 5 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/disconnected_state.rs | 5 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/error_state.rs | 5 |
6 files changed, 69 insertions, 10 deletions
diff --git a/talpid-core/src/dns/macos.rs b/talpid-core/src/dns/macos.rs index dbfd056d01..35c6cce986 100644 --- a/talpid-core/src/dns/macos.rs +++ b/talpid-core/src/dns/macos.rs @@ -12,12 +12,15 @@ use system_configuration::{ array::CFArray, base::{CFType, TCFType, ToVoid}, dictionary::{CFDictionary, CFMutableDictionary}, + number::CFNumber, propertylist::CFPropertyList, runloop::{kCFRunLoopCommonModes, CFRunLoop}, string::CFString, }, dynamic_store::{SCDynamicStore, SCDynamicStoreBuilder, SCDynamicStoreCallBackContext}, - sys::schema_definitions::{kSCPropNetDNSServerAddresses, kSCPropNetInterfaceDeviceName}, + sys::schema_definitions::{ + kSCPropNetDNSServerAddresses, kSCPropNetDNSServerPort, kSCPropNetInterfaceDeviceName, + }, }; use talpid_routing::debounce::BurstGuard; @@ -25,6 +28,8 @@ use super::ResolvedDnsConfig; pub type Result<T> = std::result::Result<T, Error>; +const DNS_PORT: u16 = 53; + /// Errors that can happen when setting/monitoring DNS on macOS. #[derive(thiserror::Error, Debug)] pub enum Error { @@ -78,11 +83,13 @@ impl State { store: &SCDynamicStore, interface: &str, servers: &[IpAddr], + port: u16, ) -> Result<()> { talpid_types::detect_flood!(); let servers: Vec<DnsServer> = servers.iter().map(|ip| ip.to_string()).collect(); - let new_settings = DnsSettings::from_server_addresses(&servers, interface.to_string()); + let new_settings = + DnsSettings::from_server_addresses(&servers, interface.to_string(), port); match &self.dns_settings { None => { self.dns_settings = Some(new_settings); @@ -221,7 +228,7 @@ struct DnsSettings { unsafe impl Send for DnsSettings {} impl DnsSettings { - pub fn from_server_addresses(server_addresses: &[DnsServer], name: String) -> Self { + pub fn from_server_addresses(server_addresses: &[DnsServer], name: String, port: u16) -> Self { let mut mut_dict = CFMutableDictionary::new(); if !server_addresses.is_empty() { let cf_string_servers: Vec<CFString> = @@ -233,6 +240,14 @@ impl DnsSettings { &server_addresses_key.to_void(), &server_addresses_value.to_void(), ); + + // Set port if non-standard + if port != DNS_PORT { + let server_port_key = + unsafe { CFString::wrap_under_get_rule(kSCPropNetDNSServerPort) }; + let server_port_value = CFNumber::from(i32::from(port)); + mut_dict.add(&server_port_key.to_void(), &server_port_value.to_void()); + } } let dict = mut_dict.to_immutable(); DnsSettings { dict, name } @@ -370,10 +385,11 @@ impl super::DnsMonitorT for DnsMonitor { } fn set(&mut self, interface: &str, config: ResolvedDnsConfig) -> Result<()> { + let port = config.port; let servers: Vec<_> = config.addresses().collect(); let mut state = self.state.lock(); - state.apply_new_config(&self.store, interface, &servers) + state.apply_new_config(&self.store, interface, &servers, port) } fn reset(&mut self) -> Result<()> { @@ -508,6 +524,8 @@ fn state_to_setup_path(state_path: &str) -> Option<String> { #[cfg(test)] mod test { + use crate::dns::imp::DNS_PORT; + use super::{DnsSettings, State}; use std::collections::{BTreeSet, HashMap}; @@ -523,6 +541,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["1.2.3.4".to_owned()], "iface_b".to_owned(), + DNS_PORT, )), ), // One of our states already equals the desired state. It should be stored regardless. @@ -531,6 +550,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["10.64.0.1".to_owned()], "iface_c".to_owned(), + DNS_PORT, )), ), ]); @@ -552,6 +572,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["1.2.3.4".to_owned()], "iface_b".to_owned(), + DNS_PORT, )), ), ( @@ -559,6 +580,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["10.64.0.1".to_owned()], "iface_c".to_owned(), + DNS_PORT, )), ), ( @@ -566,6 +588,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["1.3.3.7".to_owned()], "iface_d".to_owned(), + DNS_PORT, )), ), ]); @@ -576,6 +599,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["10.64.0.1".to_owned()], "iface_a".to_owned(), + DNS_PORT, )), ), // This change should be ignored @@ -584,6 +608,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["10.64.0.1".to_owned()], "iface_b".to_owned(), + DNS_PORT, )), ), // This change should be ignored @@ -592,6 +617,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["4.3.2.1".to_owned()], "iface_c".to_owned(), + DNS_PORT, )), ), // This change should NOT be ignored @@ -600,6 +626,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["4.3.2.1".to_owned()], "iface_d".to_owned(), + DNS_PORT, )), ), ]); @@ -610,6 +637,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["1.2.3.4".to_owned()], "iface_b".to_owned(), + DNS_PORT, )), ), ( @@ -617,6 +645,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["4.3.2.1".to_owned()], "iface_c".to_owned(), + DNS_PORT, )), ), ( @@ -624,6 +653,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["4.3.2.1".to_owned()], "iface_d".to_owned(), + DNS_PORT, )), ), ]); @@ -644,6 +674,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["10.64.0.1".to_owned()], "iface_a".to_owned(), + DNS_PORT, )), ), ( @@ -651,6 +682,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["1.2.3.4".to_owned()], "iface_b".to_owned(), + DNS_PORT, )), ), ("c".to_owned(), None), @@ -677,6 +709,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["192.168.100.1".to_owned()], "iface_a".to_owned(), + DNS_PORT, )), )]); let new_state = HashMap::from([( @@ -684,6 +717,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["192.168.1.1".to_owned()], "iface_a".to_owned(), + DNS_PORT, )), )]); let expect_state = HashMap::from([( @@ -691,6 +725,7 @@ mod test { Some(DnsSettings::from_server_addresses( &["192.168.1.1".to_owned()], "iface_a".to_owned(), + DNS_PORT, )), )]); diff --git a/talpid-core/src/dns/mod.rs b/talpid-core/src/dns/mod.rs index f803842ef9..eac609fa84 100644 --- a/talpid-core/src/dns/mod.rs +++ b/talpid-core/src/dns/mod.rs @@ -67,11 +67,17 @@ enum InnerDnsConfig { } impl DnsConfig { - pub(crate) fn resolve(&self, default_tun_config: &[IpAddr]) -> ResolvedDnsConfig { + pub(crate) fn resolve( + &self, + default_tun_config: &[IpAddr], + #[cfg(target_os = "macos")] port: u16, + ) -> ResolvedDnsConfig { match &self.config { InnerDnsConfig::Default => ResolvedDnsConfig { tunnel_config: default_tun_config.to_owned(), non_tunnel_config: vec![], + #[cfg(target_os = "macos")] + port, }, InnerDnsConfig::Override { tunnel_config, @@ -79,6 +85,8 @@ impl DnsConfig { } => ResolvedDnsConfig { tunnel_config: tunnel_config.to_owned(), non_tunnel_config: non_tunnel_config.to_owned(), + #[cfg(target_os = "macos")] + port, }, } } @@ -93,6 +101,9 @@ pub struct ResolvedDnsConfig { /// For the most part, the tunnel state machine will not handle any of this configuration /// on non-tunnel interface, only allow them in the firewall. non_tunnel_config: Vec<IpAddr>, + /// Port to use + #[cfg(target_os = "macos")] + port: u16, } impl fmt::Display for ResolvedDnsConfig { diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 10d9ac9b72..ffe181ce49 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -151,11 +151,15 @@ impl ConnectedState { metadata: &TunnelMetadata, shared_values: &SharedTunnelStateValues, ) -> ResolvedDnsConfig { - shared_values.dns_config.resolve(&metadata.gateways()) + shared_values.dns_config.resolve( + &metadata.gateways(), + #[cfg(target_os = "macos")] + 53, + ) } fn set_dns(&self, shared_values: &mut SharedTunnelStateValues) -> Result<(), BoxedError> { - let dns_config = Self::resolve_dns(&self.metadata, shared_values); + let dns_config: ResolvedDnsConfig = Self::resolve_dns(&self.metadata, shared_values); #[cfg(not(target_os = "macos"))] shared_values diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 199aa7eaa7..7a790a11b6 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -60,7 +60,10 @@ impl ConnectingState { #[cfg(target_os = "macos")] if let Err(err) = shared_values.dns_monitor.set( "lo", - crate::dns::DnsConfig::default().resolve(&[std::net::Ipv4Addr::LOCALHOST.into()]), + crate::dns::DnsConfig::default().resolve( + &[std::net::Ipv4Addr::LOCALHOST.into()], + shared_values.filtering_resolver.listening_port(), + ), ) { log::error!( "{}", diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs index baf6012103..c65a04c3f3 100644 --- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs @@ -137,7 +137,10 @@ impl DisconnectedState { shared_values.dns_monitor.set( "lo", - dns::DnsConfig::default().resolve(&[Ipv4Addr::LOCALHOST.into()]), + dns::DnsConfig::default().resolve( + &[Ipv4Addr::LOCALHOST.into()], + shared_values.filtering_resolver.listening_port(), + ), ) } } diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs index eeaf48956b..1b154840e2 100644 --- a/talpid-core/src/tunnel_state_machine/error_state.rs +++ b/talpid-core/src/tunnel_state_machine/error_state.rs @@ -37,7 +37,10 @@ impl ErrorState { if !block_reason.prevents_filtering_resolver() { if let Err(err) = shared_values.dns_monitor.set( "lo", - DnsConfig::default().resolve(&[Ipv4Addr::LOCALHOST.into()]), + DnsConfig::default().resolve( + &[Ipv4Addr::LOCALHOST.into()], + shared_values.filtering_resolver.listening_port(), + ), ) { log::error!( "{}", |
