summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-10-27 09:27:07 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-10-27 09:27:07 +0100
commite382e1125cb45c6503b9be9b10625fa954e0599e (patch)
treed8f24598281ec617a2995d805f13c8ab9ba3538a
parent4331a3fb74d998740d352d78e597ffba6a0c0dd2 (diff)
parentd119c6cc378e401ebf1bc7fdf666b0aa3022f069 (diff)
downloadmullvadvpn-e382e1125cb45c6503b9be9b10625fa954e0599e.tar.xz
mullvadvpn-e382e1125cb45c6503b9be9b10625fa954e0599e.zip
Merge branch 'linux-custom-dns'
-rw-r--r--CHANGELOG.md1
-rw-r--r--mullvad-cli/src/cmds/mod.rs2
-rw-r--r--mullvad-daemon/src/lib.rs14
-rw-r--r--mullvad-daemon/src/management_interface.rs10
-rw-r--r--mullvad-daemon/src/settings.rs4
-rw-r--r--mullvad-types/src/settings/mod.rs8
-rw-r--r--talpid-core/src/firewall/linux.rs94
-rw-r--r--talpid-core/src/firewall/mod.rs6
-rw-r--r--talpid-core/src/routing/linux.rs74
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs8
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs2
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs2
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs6
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs2
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs14
15 files changed, 177 insertions, 70 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d993c6690e..388c5ea94a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -33,6 +33,7 @@ Line wrap the file at 100 chars. Th
#### Linux
- Use NetworkManager to create a WireGuard interface.
+- Add support for custom DNS resolvers (CLI only).
### Changed
- Use the API to fetch API IP addresses instead of DNS.
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs
index d542eb7844..cee2361164 100644
--- a/mullvad-cli/src/cmds/mod.rs
+++ b/mullvad-cli/src/cmds/mod.rs
@@ -63,7 +63,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
Box::new(Disconnect),
Box::new(Reconnect),
Box::new(Lan),
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Box::new(CustomDns),
Box::new(Relay),
Box::new(Reset),
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 320e839a0a..fa9f679848 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -26,7 +26,7 @@ use futures::{
};
use log::{debug, error, info, warn};
use mullvad_rpc::AccountsProxy;
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use mullvad_types::settings::DnsOptions;
use mullvad_types::{
account::{AccountData, AccountToken, VoucherSubmission},
@@ -43,7 +43,7 @@ use mullvad_types::{
wireguard::KeygenEvent,
};
use settings::SettingsPersister;
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use std::net::IpAddr;
#[cfg(not(target_os = "android"))]
use std::path::Path;
@@ -197,7 +197,7 @@ pub enum DaemonCommand {
/// Set if IPv6 should be enabled in the tunnel
SetEnableIpv6(oneshot::Sender<()>, bool),
/// Set custom DNS servers to use instead of passing requests to the gateway
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
SetDnsOptions(oneshot::Sender<()>, DnsOptions),
/// Set MTU for wireguard tunnels
SetWireguardMtu(oneshot::Sender<()>, Option<u16>),
@@ -582,7 +582,7 @@ where
let tunnel_command_tx = tunnel_state_machine::spawn(
settings.allow_lan,
settings.block_when_disconnected,
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Self::get_custom_resolvers(&settings.tunnel_options.dns_options),
tunnel_parameters_generator,
log_dir,
@@ -636,7 +636,7 @@ where
Ok(daemon)
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
fn get_custom_resolvers(dns_options: &DnsOptions) -> Option<Vec<IpAddr>> {
if dns_options.custom {
Some(dns_options.addresses.clone())
@@ -1056,7 +1056,7 @@ where
}
SetBridgeState(tx, bridge_state) => self.on_set_bridge_state(tx, bridge_state),
SetEnableIpv6(tx, enable_ipv6) => self.on_set_enable_ipv6(tx, enable_ipv6),
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
SetDnsOptions(tx, dns_servers) => self.on_set_dns_options(tx, dns_servers),
SetWireguardMtu(tx, mtu) => self.on_set_wireguard_mtu(tx, mtu),
SetWireguardRotationInterval(tx, interval) => {
@@ -1696,7 +1696,7 @@ where
}
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
fn on_set_dns_options(&mut self, tx: oneshot::Sender<()>, dns_options: DnsOptions) {
let save_result = self.settings.set_dns_options(dns_options.clone());
match save_result {
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index ca324308cb..d248a10dc5 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -6,7 +6,7 @@ use mullvad_management_interface::{
};
use mullvad_paths;
use mullvad_rpc::{rest::Error as RestError, StatusCode};
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use mullvad_types::settings::DnsOptions;
use mullvad_types::{
account::AccountToken,
@@ -410,7 +410,7 @@ impl ManagementService for ManagementServiceImpl {
.map_err(|_| Status::internal("internal error"))
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
async fn set_dns_options(&self, request: Request<types::DnsOptions>) -> ServiceResult<()> {
let options = request.into_inner();
log::debug!(
@@ -441,7 +441,7 @@ impl ManagementService for ManagementServiceImpl {
.map(Response::new)
.map_err(|_| Status::internal("internal error"))
}
- #[cfg(not(windows))]
+ #[cfg(not(any(windows, target_os = "linux")))]
async fn set_dns_options(&self, _: Request<types::DnsOptions>) -> ServiceResult<()> {
Ok(Response::new(()))
}
@@ -1179,7 +1179,7 @@ fn convert_tunnel_options(options: &TunnelOptions) -> types::TunnelOptions {
generic: Some(types::tunnel_options::GenericOptions {
enable_ipv6: options.generic.enable_ipv6,
}),
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
dns_options: Some(types::DnsOptions {
custom: options.dns_options.custom,
addresses: options
@@ -1189,7 +1189,7 @@ fn convert_tunnel_options(options: &TunnelOptions) -> types::TunnelOptions {
.map(|addr| addr.to_string())
.collect(),
}),
- #[cfg(not(windows))]
+ #[cfg(not(any(windows, target_os = "linux")))]
dns_options: None,
}
}
diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs
index bcc07f84ae..f9986c49a5 100644
--- a/mullvad-daemon/src/settings.rs
+++ b/mullvad-daemon/src/settings.rs
@@ -1,5 +1,5 @@
use log::{debug, error, info};
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use mullvad_types::settings::DnsOptions;
use mullvad_types::{
relay_constraints::{BridgeSettings, BridgeState, RelaySettingsUpdate},
@@ -212,7 +212,7 @@ impl SettingsPersister {
self.update(should_save)
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
pub fn set_dns_options(&mut self, options: DnsOptions) -> Result<bool, Error> {
let should_save =
Self::update_field(&mut self.settings.tunnel_options.dns_options, options);
diff --git a/mullvad-types/src/settings/mod.rs b/mullvad-types/src/settings/mod.rs
index 0c8810b1db..df0d622815 100644
--- a/mullvad-types/src/settings/mod.rs
+++ b/mullvad-types/src/settings/mod.rs
@@ -7,7 +7,7 @@ use jnix::IntoJava;
use log::{debug, info};
use serde::{Deserialize, Serialize};
use serde_json;
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use std::net::IpAddr;
use talpid_types::net::{openvpn, wireguard, GenericTunnelOptions};
@@ -167,12 +167,12 @@ pub struct TunnelOptions {
#[cfg_attr(target_os = "android", jnix(skip))]
pub generic: GenericTunnelOptions,
/// Custom DNS options.
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
pub dns_options: DnsOptions,
}
/// Custom DNS config
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
#[serde(default)]
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub struct DnsOptions {
@@ -194,7 +194,7 @@ impl Default for TunnelOptions {
// Enable IPv6 be default on Android
enable_ipv6: cfg!(target_os = "android"),
},
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
dns_options: DnsOptions::default(),
}
}
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 1ca10784bf..f7efcb6fba 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -471,11 +471,12 @@ impl<'a> PolicyBatch<'a> {
peer_endpoint,
tunnel,
allow_lan,
+ dns_servers,
use_fwmark,
} => {
self.add_allow_endpoint_rules(peer_endpoint, *use_fwmark);
- self.add_allow_dns_rules(tunnel, TransportProtocol::Udp)?;
- self.add_allow_dns_rules(tunnel, TransportProtocol::Tcp)?;
+ self.add_allow_dns_rules(tunnel, &dns_servers, TransportProtocol::Udp)?;
+ self.add_allow_dns_rules(tunnel, &dns_servers, TransportProtocol::Tcp)?;
// Important to block DNS *before* we allow the tunnel and allow LAN. So DNS
// can't leak to the wrong IPs in the tunnel or on the LAN.
self.add_drop_dns_rule();
@@ -559,17 +560,31 @@ impl<'a> PolicyBatch<'a> {
fn add_allow_dns_rules(
&mut self,
tunnel: &tunnel::TunnelMetadata,
+ dns_servers: &[IpAddr],
protocol: TransportProtocol,
) -> Result<()> {
- // allow DNS traffic to the tunnel gateway(s)
- self.add_allow_dns_rule(&tunnel.interface, protocol, tunnel.ipv4_gateway.into())?;
- if let Some(ipv6_gateway) = tunnel.ipv6_gateway {
- self.add_allow_dns_rule(&tunnel.interface, protocol, ipv6_gateway.into())?;
- };
+ let (local_resolvers, remote_resolvers): (Vec<IpAddr>, Vec<IpAddr>) =
+ dns_servers.iter().partition(|server| {
+ is_local_address(server)
+ && *server != &tunnel.ipv4_gateway
+ && !tunnel
+ .ipv6_gateway
+ .map(|ref gateway| *server == gateway)
+ .unwrap_or(false)
+ });
+
+ for resolver in &local_resolvers {
+ self.add_allow_local_dns_rule(&tunnel.interface, protocol, *resolver)?;
+ }
+
+ for resolver in &remote_resolvers {
+ self.add_allow_tunnel_dns_rule(&tunnel.interface, protocol, *resolver)?;
+ }
+
Ok(())
}
- fn add_allow_dns_rule(
+ fn add_allow_tunnel_dns_rule(
&mut self,
interface: &str,
protocol: TransportProtocol,
@@ -593,6 +608,45 @@ impl<'a> PolicyBatch<'a> {
Ok(())
}
+ fn add_allow_local_dns_rule(
+ &mut self,
+ tunnel_interface: &str,
+ protocol: TransportProtocol,
+ host: IpAddr,
+ ) -> Result<()> {
+ let chains = [
+ (&self.out_chain, Direction::Out),
+ (&self.in_chain, Direction::In),
+ ];
+
+ for (chain, direction) in &chains {
+ let mut allow_rule = Rule::new(chain);
+ let addr = match (host, direction) {
+ (IpAddr::V4(_), Direction::Out) => nft_expr!(payload ipv4 daddr),
+ (IpAddr::V6(_), Direction::Out) => nft_expr!(payload ipv6 daddr),
+ (IpAddr::V4(_), Direction::In) => nft_expr!(payload ipv4 saddr),
+ (IpAddr::V6(_), Direction::In) => nft_expr!(payload ipv6 saddr),
+ };
+
+ let port_dir = match direction {
+ Direction::In => End::Src,
+ Direction::Out => End::Dst,
+ };
+
+ check_not_iface(&mut allow_rule, *direction, tunnel_interface)?;
+ check_port(&mut allow_rule, protocol, port_dir, 53);
+ check_l3proto(&mut allow_rule, host);
+
+ allow_rule.add_expr(&addr);
+ allow_rule.add_expr(&nft_expr!(cmp == host));
+ add_verdict(&mut allow_rule, &Verdict::Accept);
+
+ self.batch.add(&allow_rule, nftnl::MsgType::Add);
+ }
+
+ Ok(())
+ }
+
/// Blocks all outgoing DNS (port 53) on both TCP and UDP
fn add_drop_dns_rule(&mut self) {
let mut block_udp_rule = Rule::new(&self.out_chain);
@@ -706,6 +760,17 @@ fn check_iface(rule: &mut Rule<'_>, direction: Direction, iface: &str) -> Result
Ok(())
}
+fn check_not_iface(rule: &mut Rule<'_>, direction: Direction, iface: &str) -> Result<()> {
+ let iface_index = crate::linux::iface_index(iface)
+ .map_err(|e| Error::LookupIfaceIndexError(iface.to_owned(), e))?;
+ rule.add_expr(&match direction {
+ Direction::In => nft_expr!(meta iif),
+ Direction::Out => nft_expr!(meta oif),
+ });
+ rule.add_expr(&nft_expr!(cmp != iface_index));
+ Ok(())
+}
+
fn check_net(rule: &mut Rule<'_>, end: End, net: impl Into<IpNetwork>) {
let net = net.into();
// Must check network layer protocol before loading network layer payload
@@ -789,3 +854,16 @@ fn add_verdict(rule: &mut Rule<'_>, verdict: &expr::Verdict) {
}
rule.add_expr(verdict);
}
+
+fn is_local_address(address: &IpAddr) -> bool {
+ let address = address.clone();
+ for net in (&*super::ALLOWED_LAN_NETS)
+ .iter()
+ .chain(&*super::LOOPBACK_NETS)
+ {
+ if net.contains(address) {
+ return true;
+ }
+ }
+ false
+}
diff --git a/talpid-core/src/firewall/mod.rs b/talpid-core/src/firewall/mod.rs
index b427e459d5..4ae51a73a2 100644
--- a/talpid-core/src/firewall/mod.rs
+++ b/talpid-core/src/firewall/mod.rs
@@ -67,6 +67,10 @@ lazy_static! {
Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 1, 3),
];
static ref ROUTER_SOLICITATION_OUT_DST_ADDR: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 2);
+ static ref LOOPBACK_NETS: [IpNetwork; 2] = [
+ IpNetwork::V4(ipnetwork::Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 8).unwrap()),
+ IpNetwork::V6(ipnetwork::Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 128).unwrap()),
+ ];
}
#[cfg(all(unix, not(target_os = "android")))]
const DHCPV4_SERVER_PORT: u16 = 67;
@@ -112,7 +116,7 @@ pub enum FirewallPolicy {
/// Flag setting if communication with LAN networks should be possible.
allow_lan: bool,
/// Servers that are allowed to respond to DNS requests.
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
dns_servers: Vec<IpAddr>,
/// A process that is allowed to send packets to the relay.
#[cfg(windows)]
diff --git a/talpid-core/src/routing/linux.rs b/talpid-core/src/routing/linux.rs
index dbe35f2c96..9b7d016d1a 100644
--- a/talpid-core/src/routing/linux.rs
+++ b/talpid-core/src/routing/linux.rs
@@ -94,6 +94,8 @@ pub struct RouteManagerImpl {
split_table_id: u32,
split_ignored_interface: Option<String>,
+
+ dns_routes: HashSet<Route>,
}
impl RouteManagerImpl {
@@ -129,6 +131,8 @@ impl RouteManagerImpl {
split_table_id,
split_ignored_interface: None,
+
+ dns_routes: HashSet::new(),
};
monitor.initialize_exclusions_routes().await?;
@@ -265,26 +269,47 @@ impl RouteManagerImpl {
}
}
+ async fn clear_exclusions_dns(&mut self) -> Result<()> {
+ for route in self.dns_routes.clone() {
+ self.delete_route_if_exists(&route).await?;
+ self.dns_routes.remove(&route);
+ self.added_routes.remove(&route);
+ }
+ self.dns_routes.clear();
+
+ Ok(())
+ }
+
/// Route DNS requests through the tunnel interface.
- #[cfg(target_os = "linux")]
async fn route_exclusions_dns(
&mut self,
tunnel_alias: &str,
dns_servers: &[IpAddr],
) -> Result<()> {
+ self.clear_exclusions_dns().await?;
+
let mut dns_routes = HashSet::new();
for server in dns_servers {
dns_routes.insert(
- RequiredRoute::new(
- IpNetwork::from(*server),
+ Route::new(
Node::device(tunnel_alias.to_string()),
+ IpNetwork::from(*server),
)
.table(self.split_table_id),
);
}
- self.add_required_routes(dns_routes).await
+ if let Some(capacity_needed) = dns_routes.len().checked_sub(self.dns_routes.capacity()) {
+ self.dns_routes.reserve(capacity_needed);
+ }
+
+ for route in dns_routes {
+ self.add_route(route.clone()).await?;
+ self.dns_routes.insert(route);
+ }
+
+ Ok(())
}
async fn add_required_default_routes(
@@ -478,9 +503,8 @@ impl RouteManagerImpl {
self.default_routes.remove(&route);
self.update_default_routes().await?;
}
- if self.added_routes.contains(&route) {
- self.added_routes.remove(&route);
- }
+ self.added_routes.remove(&route);
+ self.dns_routes.remove(&route);
Ok(())
}
@@ -583,32 +607,17 @@ impl RouteManagerImpl {
let route =
Route::new(best_node, required_route.destination).table(required_route.table_id);
- if let Err(e) = self.delete_route(&route).await {
- if let Error::NetlinkError(err) = &e {
- if let rtnetlink::Error::NetlinkError(msg) = err {
- // -3 means that the route doesn't exist anymore anyway
- if msg.code == -3 {
- continue;
- }
- }
- }
+ if let Err(e) = self.delete_route_if_exists(&route).await {
log::error!("Failed to remove route - {} - {}", route, e);
}
}
self.required_default_routes.clear();
for route in self.added_routes.drain().collect::<Vec<_>>().iter() {
- if let Err(e) = self.delete_route(&route).await {
- if let Error::NetlinkError(err) = &e {
- if let rtnetlink::Error::NetlinkError(msg) = err {
- // -3 means that the route doesn't exist anymore anyway
- if msg.code == -3 {
- continue;
- }
- }
- }
+ if let Err(e) = self.delete_route_if_exists(&route).await {
log::error!("Failed to remove route - {} - {}", route, e);
}
+ self.dns_routes.remove(&route);
}
}
@@ -810,6 +819,21 @@ impl RouteManagerImpl {
}
}
+ async fn delete_route_if_exists(&self, route: &Route) -> Result<()> {
+ if let Err(error) = self.delete_route(route).await {
+ if let Error::NetlinkError(netlink_error) = &error {
+ if let rtnetlink::Error::NetlinkError(msg) = &netlink_error {
+ if msg.code == -libc::ESRCH {
+ return Ok(());
+ }
+ }
+ }
+ Err(error)
+ } else {
+ Ok(())
+ }
+ }
+
async fn delete_route(&self, route: &Route) -> Result<()> {
let compat_table = compat_table_id(route.table_id);
let scope = match route.prefix {
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index a7fd495c50..2ef41b4a91 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -78,7 +78,7 @@ impl ConnectedState {
#[allow(unused_variables)]
fn get_dns_servers(&self, shared_values: &SharedTunnelStateValues) -> Vec<IpAddr> {
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
if let Some(ref servers) = shared_values.custom_dns {
servers.clone()
} else {
@@ -89,7 +89,7 @@ impl ConnectedState {
};
dns_ips
}
- #[cfg(not(windows))]
+ #[cfg(not(any(windows, target_os = "linux")))]
{
let mut dns_ips = vec![];
dns_ips.push(self.metadata.ipv4_gateway.into());
@@ -105,7 +105,7 @@ impl ConnectedState {
peer_endpoint: self.tunnel_parameters.get_next_hop_endpoint(),
tunnel: self.metadata.clone(),
allow_lan: shared_values.allow_lan,
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
dns_servers: self.get_dns_servers(shared_values),
#[cfg(windows)]
relay_client: TunnelMonitor::get_relay_client(
@@ -182,7 +182,7 @@ impl ConnectedState {
}
}
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
if shared_values.custom_dns != servers {
shared_values.custom_dns = servers;
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 6f081697e5..036e4356cd 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -227,7 +227,7 @@ impl ConnectingState {
}
}
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
SameState(self.into())
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 4781f19091..9fc8aa781f 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -82,7 +82,7 @@ impl TunnelState for DisconnectedState {
}
SameState(self.into())
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
SameState(self.into())
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index 356df9be53..2ea612e26e 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -32,7 +32,7 @@ impl DisconnectingState {
let _ = shared_values.set_allow_lan(allow_lan);
AfterDisconnect::Nothing
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
AfterDisconnect::Nothing
@@ -54,7 +54,7 @@ impl DisconnectingState {
let _ = shared_values.set_allow_lan(allow_lan);
AfterDisconnect::Block(reason)
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
AfterDisconnect::Block(reason)
@@ -81,7 +81,7 @@ impl DisconnectingState {
let _ = shared_values.set_allow_lan(allow_lan);
AfterDisconnect::Reconnect(retry_attempt)
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
AfterDisconnect::Reconnect(retry_attempt)
diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs
index aa53e0b0b5..91abf34688 100644
--- a/talpid-core/src/tunnel_state_machine/error_state.rs
+++ b/talpid-core/src/tunnel_state_machine/error_state.rs
@@ -102,7 +102,7 @@ impl TunnelState for ErrorState {
SameState(self.into())
}
}
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
Some(TunnelCommand::CustomDns(servers)) => {
shared_values.custom_dns = servers;
SameState(self.into())
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 90bf9a5d29..d4d337925f 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -24,7 +24,7 @@ use futures::{
channel::{mpsc, oneshot},
stream, StreamExt,
};
-#[cfg(windows)]
+#[cfg(any(windows, target_os = "linux"))]
use std::net::IpAddr;
use std::{
collections::HashSet,
@@ -76,7 +76,7 @@ pub enum Error {
pub async fn spawn(
allow_lan: bool,
block_when_disconnected: bool,
- #[cfg(windows)] custom_dns: Option<Vec<IpAddr>>,
+ #[cfg(any(windows, target_os = "linux"))] custom_dns: Option<Vec<IpAddr>>,
tunnel_parameters_generator: impl TunnelParametersGenerator,
log_dir: Option<PathBuf>,
resource_dir: PathBuf,
@@ -112,7 +112,7 @@ pub async fn spawn(
allow_lan,
block_when_disconnected,
is_offline,
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
custom_dns,
tunnel_parameters_generator,
tun_provider,
@@ -153,7 +153,7 @@ pub enum TunnelCommand {
/// Enable or disable LAN access in the firewall.
AllowLan(bool),
/// Set custom DNS servers to use.
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
CustomDns(Option<Vec<IpAddr>>),
/// Enable or disable the block_when_disconnected feature.
BlockWhenDisconnected(bool),
@@ -192,7 +192,7 @@ impl TunnelStateMachine {
allow_lan: bool,
block_when_disconnected: bool,
is_offline: bool,
- #[cfg(windows)] custom_dns: Option<Vec<IpAddr>>,
+ #[cfg(any(windows, target_os = "linux"))] custom_dns: Option<Vec<IpAddr>>,
tunnel_parameters_generator: impl TunnelParametersGenerator,
tun_provider: TunProvider,
log_dir: Option<PathBuf>,
@@ -217,7 +217,7 @@ impl TunnelStateMachine {
allow_lan,
block_when_disconnected,
is_offline,
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
custom_dns,
tunnel_parameters_generator: Box::new(tunnel_parameters_generator),
tun_provider,
@@ -289,7 +289,7 @@ struct SharedTunnelStateValues {
/// True when the computer is known to be offline.
is_offline: bool,
/// Custom DNS servers to use.
- #[cfg(windows)]
+ #[cfg(any(windows, target_os = "linux"))]
custom_dns: Option<Vec<IpAddr>>,
/// The generator of new `TunnelParameter`s
tunnel_parameters_generator: Box<dyn TunnelParametersGenerator>,