diff options
| author | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-05-12 13:21:49 +0200 |
|---|---|---|
| committer | Joakim Hulthe <joakim.hulthe@mullvad.net> | 2025-05-14 18:00:31 +0200 |
| commit | cb28ff3100a15ff07e5af9c27f8ad9f92fa19886 (patch) | |
| tree | ab7727b8527eef66e942068ed1d1da91b158d090 | |
| parent | c4d2fc9ee1ad74d0c5e8bfb160048044f222e72d (diff) | |
| download | mullvadvpn-cb28ff3100a15ff07e5af9c27f8ad9f92fa19886.tar.xz mullvadvpn-cb28ff3100a15ff07e5af9c27f8ad9f92fa19886.zip | |
Add stricter checking of forwarding DNS config
Do not filter out all loopback addresses, only the address of the
running local DNS resolver.
| -rw-r--r-- | talpid-core/src/resolver.rs | 60 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connected_state.rs | 12 |
2 files changed, 36 insertions, 36 deletions
diff --git a/talpid-core/src/resolver.rs b/talpid-core/src/resolver.rs index e7cdaafc2c..b9ea1cb44e 100644 --- a/talpid-core/src/resolver.rs +++ b/talpid-core/src/resolver.rs @@ -120,6 +120,8 @@ struct LocalResolver { rx: mpsc::UnboundedReceiver<ResolverMessage>, dns_server_task: JoinHandle<()>, inner_resolver: Resolver, + /// Which IP+port the local resolver is bound to. + bound_to: SocketAddr, } /// A message to [LocalResolver] @@ -163,29 +165,6 @@ enum Resolver { Forwarding(TokioAsyncResolver), } -impl From<Config> for Resolver { - fn from(mut config: Config) -> Self { - match &mut config { - Config::Blocking => Resolver::Blocking, - Config::Forwarding { dns_servers } => { - // make sure not to accidentally forward queries to ourselves - dns_servers.retain(|addr| !addr.is_loopback()); - - let forward_server_config = - NameServerConfigGroup::from_ips_clear(dns_servers, DNS_PORT, true); - - let forward_config = - ResolverConfig::from_parts(None, vec![], forward_server_config); - let resolver_opts = ResolverOpts::default(); - - let resolver = TokioAsyncResolver::tokio(forward_config, resolver_opts); - - Resolver::Forwarding(resolver) - } - } - } -} - impl Resolver { pub fn resolve( &self, @@ -349,7 +328,8 @@ impl LocalResolver { let resolver = Self { rx: command_rx, dns_server_task, - inner_resolver: Resolver::from(Config::Blocking), + bound_to: resolver_addr, + inner_resolver: Resolver::Blocking, }; Ok((resolver, ResolverHandle::new(command_tx, resolver_addr))) @@ -460,7 +440,7 @@ impl LocalResolver { } => { log::debug!("Updating config: {new_config:?}"); - self.inner_resolver = Resolver::from(new_config); + self.update_config(new_config); flush_system_cache(); let _ = response_tx.send(()); } @@ -473,6 +453,36 @@ impl LocalResolver { } } } + + /// Update the current DNS config. + fn update_config(&mut self, config: Config) { + match config { + Config::Blocking => self.blocking(), + Config::Forwarding { mut dns_servers } => { + // make sure not to accidentally forward queries to ourselves + dns_servers.retain(|addr| *addr != self.bound_to.ip()); + self.forwarding(dns_servers); + } + } + } + + /// Turn into a blocking resolver. + fn blocking(&mut self) { + self.inner_resolver = Resolver::Blocking; + } + + /// Turn into a forwarding resolver (forward DNS queries to [dns_servers]). + fn forwarding(&mut self, dns_servers: Vec<IpAddr>) { + let forward_server_config = + NameServerConfigGroup::from_ips_clear(&dns_servers, DNS_PORT, true); + + let forward_config = ResolverConfig::from_parts(None, vec![], forward_server_config); + let resolver_opts = ResolverOpts::default(); + + let resolver = TokioAsyncResolver::tokio(forward_config, resolver_opts); + + self.inner_resolver = Resolver::Forwarding(resolver); + } } /// Flush the DNS cache. diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index 9055194f9b..8dfa6b33ae 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -10,8 +10,6 @@ use talpid_types::{BoxedError, ErrorExt}; use crate::dns::DnsConfig; use crate::dns::ResolvedDnsConfig; use crate::firewall::FirewallPolicy; -#[cfg(target_os = "macos")] -use crate::resolver::LOCAL_DNS_RESOLVER; #[cfg(windows)] use crate::tunnel::TunnelMonitor; use crate::tunnel::{TunnelEvent, TunnelMetadata}; @@ -166,15 +164,7 @@ impl ConnectedState { // On macOS, configure only the local DNS resolver #[cfg(target_os = "macos")] - // We do not want to forward DNS queries to *our* local resolver if we do not run a local - // DNS resolver *or* if the DNS config points to a loopback address. - if dns_config.is_loopback() || !*LOCAL_DNS_RESOLVER { - log::debug!("Not enabling local DNS resolver"); - shared_values - .dns_monitor - .set(&self.metadata.interface, dns_config) - .map_err(BoxedError::new)?; - } else { + { log::debug!("Enabling local DNS resolver"); // Tell local DNS resolver to start forwarding DNS queries to whatever `dns_config` // specifies as DNS. |
