summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-10-24 15:09:28 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-10-24 18:00:35 +0200
commit0b49d7c1e1fbbb10ef0f2c9408eeba4e3f54a026 (patch)
treecd8fa20bc26657aae636c03280aba31395c245ff /talpid-core/src
parent4c811088dc9f4ac90f5bf6146d8ea71ec5dc9b6c (diff)
downloadmullvadvpn-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.rs43
-rw-r--r--talpid-core/src/dns/mod.rs13
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs8
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs5
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs5
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!(
"{}",