summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2025-05-12 13:21:49 +0200
committerJoakim Hulthe <joakim.hulthe@mullvad.net>2025-05-14 18:00:31 +0200
commitcb28ff3100a15ff07e5af9c27f8ad9f92fa19886 (patch)
treeab7727b8527eef66e942068ed1d1da91b158d090
parentc4d2fc9ee1ad74d0c5e8bfb160048044f222e72d (diff)
downloadmullvadvpn-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.rs60
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs12
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.