Skip to content

Commit 0bc17c3

Browse files
committed
Rework DnsConfig, remove ability to disable local resolver
1 parent 1e8e788 commit 0bc17c3

20 files changed

Lines changed: 355 additions & 456 deletions

File tree

nym-vpn-core/Cargo.lock

Lines changed: 34 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nym-vpn-core/README.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,6 @@ make -C nym-vpn-core -f Android.mk
303303
- `netsh`: use the `netsh` program
304304
- `tcpip`: set TCP/IP parameters in the registry
305305

306-
- `NYM_DISABLE_LOCAL_DNS_RESOLVER` - Set this variable to `1` to disable the local DNS resolver
307-
(macOS only).
308-
309306
- `NYM_DISABLE_OFFLINE_MONITOR` - Set to `1` to forces the daemon to always assume the host is online.
310307

311308
- `NYM_USE_PATH_MONITOR` - Set to `1` to use Apple Network framework for offline monitoring. (macOS only)

nym-vpn-core/crates/nym-dns/src/android.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright 2024 Nym Technologies SA <contact@nymtech.net>
33
// SPDX-License-Identifier: GPL-3.0-only
44

5-
use crate::ResolvedDnsConfig;
5+
use crate::DnsConfig;
66

77
/// Stub error type for DNS errors on Android.
88
#[derive(Debug, thiserror::Error)]
@@ -18,11 +18,7 @@ impl super::DnsMonitorT for DnsMonitor {
1818
Ok(DnsMonitor)
1919
}
2020

21-
async fn set(
22-
&mut self,
23-
_interface: &str,
24-
_servers: ResolvedDnsConfig,
25-
) -> Result<(), Self::Error> {
21+
async fn set(&mut self, _interface: &str, _servers: DnsConfig) -> Result<(), Self::Error> {
2622
Ok(())
2723
}
2824

nym-vpn-core/crates/nym-dns/src/lib.rs

Lines changed: 8 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright 2024 Nym Technologies SA <contact@nymtech.net>
33
// SPDX-License-Identifier: GPL-3.0-only
44

5-
use std::{fmt, net::IpAddr};
5+
use std::net::IpAddr;
66

77
#[cfg(target_os = "linux")]
88
use nym_routing::RouteManagerHandle;
@@ -31,142 +31,13 @@ pub use self::imp::Error;
3131
pub use imp::flush_resolver_cache;
3232

3333
/// DNS configuration
34-
#[derive(Debug, Clone, PartialEq)]
34+
#[derive(Debug, Clone, PartialEq, Eq)]
3535
pub struct DnsConfig {
36-
config: InnerDnsConfig,
37-
}
38-
39-
impl Default for DnsConfig {
40-
fn default() -> Self {
41-
Self {
42-
config: InnerDnsConfig::Default,
43-
}
44-
}
45-
}
46-
47-
impl DnsConfig {
48-
/// Use the specified addresses for DNS resolution
49-
pub fn from_addresses(tunnel_config: &[IpAddr], non_tunnel_config: &[IpAddr]) -> Self {
50-
DnsConfig {
51-
config: InnerDnsConfig::Override {
52-
tunnel_config: tunnel_config.to_owned(),
53-
non_tunnel_config: non_tunnel_config.to_owned(),
54-
},
55-
}
56-
}
57-
}
36+
/// DNS server addresses
37+
pub addresses: Vec<IpAddr>,
5838

59-
impl DnsConfig {
60-
pub fn resolve(
61-
&self,
62-
default_tun_config: &[IpAddr],
63-
#[cfg(not(any(target_os = "android", target_os = "ios")))] port: u16,
64-
) -> ResolvedDnsConfig {
65-
match &self.config {
66-
InnerDnsConfig::Default => ResolvedDnsConfig {
67-
tunnel_config: default_tun_config.to_owned(),
68-
non_tunnel_config: vec![],
69-
#[cfg(not(any(target_os = "android", target_os = "ios")))]
70-
port,
71-
},
72-
InnerDnsConfig::Override {
73-
tunnel_config,
74-
non_tunnel_config,
75-
} => ResolvedDnsConfig {
76-
tunnel_config: tunnel_config.to_owned(),
77-
non_tunnel_config: non_tunnel_config.to_owned(),
78-
#[cfg(not(any(target_os = "android", target_os = "ios")))]
79-
port,
80-
},
81-
}
82-
}
83-
}
84-
85-
#[derive(Debug, Clone, PartialEq)]
86-
enum InnerDnsConfig {
87-
/// Use gateway addresses from the tunnel config
88-
Default,
89-
/// Use the specified addresses for DNS resolution
90-
Override {
91-
/// Addresses to configure on the tunnel interface
92-
tunnel_config: Vec<IpAddr>,
93-
/// Addresses to allow on non-tunnel interface.
94-
/// For the most part, the tunnel state machine will not handle any of this configuration
95-
/// on non-tunnel interface, only allow them in the firewall.
96-
non_tunnel_config: Vec<IpAddr>,
97-
},
98-
}
99-
100-
/// DNS configuration with `DnsConfig::Default` resolved
101-
#[derive(Debug, Clone, PartialEq, Eq)]
102-
pub struct ResolvedDnsConfig {
103-
/// Addresses to configure on the tunnel interface
104-
tunnel_config: Vec<IpAddr>,
105-
/// Addresses to allow on non-tunnel interface.
106-
/// For the most part, the tunnel state machine will not handle any of this configuration
107-
/// on non-tunnel interface, only allow them in the firewall.
108-
non_tunnel_config: Vec<IpAddr>,
10939
/// Port to use
110-
#[cfg(not(any(target_os = "android", target_os = "ios")))]
111-
port: u16,
112-
}
113-
114-
impl fmt::Display for ResolvedDnsConfig {
115-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116-
f.write_str("Tunnel DNS: ")?;
117-
Self::fmt_addr_set(f, &self.tunnel_config)?;
118-
119-
f.write_str(" Non-tunnel DNS: ")?;
120-
Self::fmt_addr_set(f, &self.non_tunnel_config)?;
121-
122-
#[cfg(not(any(target_os = "android", target_os = "ios")))]
123-
write!(f, " Port: {}", self.port)?;
124-
125-
Ok(())
126-
}
127-
}
128-
129-
impl ResolvedDnsConfig {
130-
fn fmt_addr_set(f: &mut fmt::Formatter<'_>, addrs: &[IpAddr]) -> fmt::Result {
131-
f.write_str("{")?;
132-
for (i, addr) in addrs.iter().enumerate() {
133-
if i > 0 {
134-
f.write_str(", ")?;
135-
}
136-
write!(f, "{addr}")?;
137-
}
138-
f.write_str("}")
139-
}
140-
141-
/// Addresses to configure on the tunnel interface
142-
pub fn tunnel_config(&self) -> &[IpAddr] {
143-
&self.tunnel_config
144-
}
145-
146-
/// Addresses to allow on non-tunnel interface.
147-
/// For the most part, the tunnel state machine will not handle any of this configuration
148-
/// on non-tunnel interface, only allow them in the firewall.
149-
pub fn non_tunnel_config(&self) -> &[IpAddr] {
150-
&self.non_tunnel_config
151-
}
152-
153-
/// Consume `self` and return a vector of all addresses
154-
pub fn addresses(self) -> impl Iterator<Item = IpAddr> {
155-
self.non_tunnel_config.into_iter().chain(self.tunnel_config)
156-
}
157-
158-
/// Return whether the config contains only (and at least one) loopback addresses, and zero
159-
/// non-loopback addresses
160-
pub fn is_loopback(&self) -> bool {
161-
let (loopback_addrs, non_loopback_addrs) = self
162-
.tunnel_config
163-
.iter()
164-
.chain(self.non_tunnel_config.iter())
165-
.copied()
166-
.partition::<Vec<_>, _>(|ip| ip.is_loopback());
167-
168-
!loopback_addrs.is_empty() && non_loopback_addrs.is_empty()
169-
}
40+
pub port: u16,
17041
}
17142

17243
/// Sets and monitors system DNS settings. Makes sure the desired DNS servers are being used.
@@ -188,8 +59,8 @@ impl DnsMonitor {
18859
}
18960

19061
/// Set DNS to the given servers. And start monitoring the system for changes.
191-
pub async fn set(&mut self, interface: &str, config: ResolvedDnsConfig) -> Result<(), Error> {
192-
tracing::info!("Setting DNS servers on interface '{interface}': {config}");
62+
pub async fn set(&mut self, interface: &str, config: DnsConfig) -> Result<(), Error> {
63+
tracing::info!("Setting DNS servers on interface '{interface}': {config:?}");
19364
self.inner.set(interface, config).await
19465
}
19566

@@ -216,8 +87,7 @@ trait DnsMonitorT: Sized {
21687
#[cfg(target_os = "linux")] route_manager: RouteManagerHandle,
21788
) -> Result<Self, Self::Error>;
21889

219-
async fn set(&mut self, interface: &str, servers: ResolvedDnsConfig)
220-
-> Result<(), Self::Error>;
90+
async fn set(&mut self, interface: &str, servers: DnsConfig) -> Result<(), Self::Error>;
22191

22292
async fn reset(&mut self) -> Result<(), Self::Error>;
22393

nym-vpn-core/crates/nym-dns/src/macos.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use tokio::sync::Mutex;
3030

3131
use nym_routing::debounce::BurstGuard;
3232

33-
use super::ResolvedDnsConfig;
33+
use super::DnsConfig;
3434

3535
pub type Result<T> = std::result::Result<T, Error>;
3636

@@ -402,9 +402,9 @@ impl super::DnsMonitorT for DnsMonitor {
402402
})
403403
}
404404

405-
async fn set(&mut self, interface: &str, config: ResolvedDnsConfig) -> Result<()> {
405+
async fn set(&mut self, interface: &str, config: DnsConfig) -> Result<()> {
406406
let port = config.port;
407-
let servers: Vec<_> = config.addresses().collect();
407+
let servers: Vec<_> = config.addresses;
408408

409409
let mut state = self.state.lock().await;
410410
state.apply_new_config(&self.store, interface, &servers, port)

nym-vpn-core/crates/nym-firewall/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ libc.workspace = true
2020
thiserror.workspace = true
2121
tracing.workspace = true
2222

23-
nym-dns.workspace = true
2423
nym-common.workspace = true
2524
nym-firewall-config.workspace = true
2625

nym-vpn-core/crates/nym-firewall/src/lib.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
#[cfg(any(target_os = "linux", target_os = "macos"))]
55
use std::net::Ipv6Addr;
6+
#[cfg(not(target_os = "android"))]
7+
use std::net::SocketAddr;
68
use std::{borrow::Cow, fmt, net::IpAddr};
79

810
#[cfg(any(target_os = "linux", target_os = "macos"))]
911
use ipnetwork::Ipv6Network;
10-
#[cfg(not(target_os = "android"))]
11-
use nym_dns::ResolvedDnsConfig;
1212

1313
#[cfg(target_os = "linux")]
1414
use nym_cgroup::v2::CGroup2;
@@ -34,6 +34,8 @@ mod imp;
3434
mod imp;
3535

3636
mod net;
37+
#[cfg(not(target_os = "android"))]
38+
pub use net::AllowedDns;
3739
pub use net::{
3840
AllowedClients, AllowedEndpoint, AllowedTunnelTraffic, Endpoint, TransportProtocol,
3941
TunnelInterface, TunnelMetadata,
@@ -76,11 +78,6 @@ const ROOT_UID: u32 = 0;
7678
const DNS_TCP_PORTS: [u16; 2] = [443, 853];
7779

7880
/// A enum that describes network security strategy
79-
///
80-
/// # Firewall block/allow specification.
81-
///
82-
/// See the [security](../../../docs/security.md) document for the specification on how to
83-
/// implement these policies and what should and should not be allowed to flow.
8481
#[derive(Debug, Clone, Eq, PartialEq)]
8582
pub enum FirewallPolicy {
8683
/// Allow traffic only to server
@@ -93,7 +90,7 @@ pub enum FirewallPolicy {
9390
allow_lan: bool,
9491
/// Servers that are allowed to respond to DNS requests.
9592
#[cfg(not(target_os = "android"))]
96-
dns_config: ResolvedDnsConfig,
93+
dns_config: AllowedDns,
9794
/// Hosts that should be reachable while connecting.
9895
allowed_endpoints: Vec<AllowedEndpoint>,
9996
/// Networks for which to permit entry in-tunnel traffic.
@@ -116,7 +113,7 @@ pub enum FirewallPolicy {
116113
allow_lan: bool,
117114
/// Servers that are allowed to respond to DNS requests.
118115
#[cfg(not(target_os = "android"))]
119-
dns_config: ResolvedDnsConfig,
116+
dns_config: AllowedDns,
120117
/// Interface to redirect (VPN tunnel) traffic to
121118
#[cfg(target_os = "macos")]
122119
redirect_interface: Option<String>,
@@ -214,7 +211,7 @@ impl FirewallPolicy {
214211
}
215212

216213
#[cfg(not(target_os = "android"))]
217-
pub fn dns_config(&self) -> Option<&ResolvedDnsConfig> {
214+
pub fn dns_config(&self) -> Option<&AllowedDns> {
218215
match self {
219216
FirewallPolicy::Connecting { dns_config, .. }
220217
| FirewallPolicy::Connected { dns_config, .. } => Some(dns_config),
@@ -313,14 +310,14 @@ impl fmt::Display for FirewallPolicy {
313310
}
314311

315312
#[cfg(not(target_os = "android"))]
316-
fn display_allowed_non_tunnel_dns(dns_config: &ResolvedDnsConfig) -> String {
317-
if dns_config.non_tunnel_config().is_empty() {
313+
fn display_allowed_non_tunnel_dns(dns_config: &AllowedDns) -> String {
314+
if dns_config.non_tunnel_dns().is_empty() {
318315
"none".to_owned()
319316
} else {
320317
dns_config
321-
.non_tunnel_config()
318+
.non_tunnel_dns()
322319
.iter()
323-
.map(|ip| ip.to_string())
320+
.map(|ep| ep.to_string())
324321
.collect::<Vec<_>>()
325322
.join(",")
326323
}

0 commit comments

Comments
 (0)