summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-03-02 18:23:23 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-06-02 10:05:02 +0200
commit5be8c76e9a67aec7dd8084425313ed03ed996d44 (patch)
tree71752d545ca698c9d03eda2cdae17646753d1983
parentc410f341152f752c686674d2ea51aac733f8fa97 (diff)
downloadmullvadvpn-5be8c76e9a67aec7dd8084425313ed03ed996d44.tar.xz
mullvadvpn-5be8c76e9a67aec7dd8084425313ed03ed996d44.zip
Conditionally compile split tunneling code for Linux
-rw-r--r--mullvad-cli/src/cmds/mod.rs6
-rw-r--r--mullvad-daemon/src/lib.rs30
-rw-r--r--mullvad-daemon/src/management_interface.rs56
-rw-r--r--talpid-core/src/split.rs1
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs18
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs14
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs1
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs8
8 files changed, 72 insertions, 62 deletions
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs
index 5631ae03b4..e215e3da2d 100644
--- a/mullvad-cli/src/cmds/mod.rs
+++ b/mullvad-cli/src/cmds/mod.rs
@@ -34,9 +34,9 @@ pub use self::relay::Relay;
mod reset;
pub use self::reset::Reset;
-#[cfg(unix)]
+#[cfg(target_os = "linux")]
mod split;
-#[cfg(unix)]
+#[cfg(target_os = "linux")]
pub use self::split::Split;
mod status;
@@ -62,7 +62,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
Box::new(Lan),
Box::new(Relay),
Box::new(Reset),
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
Box::new(Split),
Box::new(Status),
Box::new(Tunnel),
diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs
index 2b92162b2c..e4cd1383c5 100644
--- a/mullvad-daemon/src/lib.rs
+++ b/mullvad-daemon/src/lib.rs
@@ -55,9 +55,10 @@ use std::{
thread,
time::Duration,
};
+#[cfg(target_os = "linux")]
+use talpid_core::split;
use talpid_core::{
mpsc::Sender,
- split,
tunnel_state_machine::{self, TunnelCommand, TunnelParametersGenerator},
};
#[cfg(target_os = "android")]
@@ -96,6 +97,7 @@ pub enum Error {
#[error(display = "Unable to load account history with wireguard key cache")]
LoadAccountHistory(#[error(source)] account_history::Error),
+ #[cfg(target_os = "linux")]
#[error(display = "Unable to initialize split tunneling")]
InitSplitTunneling(#[error(source)] split::Error),
@@ -217,16 +219,16 @@ pub enum DaemonCommand {
#[cfg(not(target_os = "android"))]
FactoryReset(oneshot::Sender<()>),
/// Request list of processes excluded from the tunnel
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
GetSplitTunnelProcesses(oneshot::Sender<Vec<i32>>),
/// Exclude traffic of a process (PID) from the tunnel
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
AddSplitTunnelProcess(oneshot::Sender<()>, i32),
/// Remove process (PID) from list of processes excluded from the tunnel
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
RemoveSplitTunnelProcess(oneshot::Sender<()>, i32),
/// Clear list of processes excluded from the tunnel
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
ClearSplitTunnelProcesses(oneshot::Sender<()>),
/// Makes the daemon exit the main loop and quit.
Shutdown,
@@ -447,6 +449,7 @@ pub struct Daemon<L: EventListener> {
tunnel_state: TunnelState,
target_state: TargetState,
state: DaemonExecutionState,
+ #[cfg(target_os = "linux")]
exclude_pids: split::PidManager,
rx: Wait<UnboundedReceiver<InternalDaemonEvent>>,
tx: DaemonEventSender,
@@ -591,6 +594,7 @@ where
tunnel_state: TunnelState::Disconnected,
target_state: initial_target_state,
state: DaemonExecutionState::Running,
+ #[cfg(target_os = "linux")]
exclude_pids: split::PidManager::new().map_err(Error::InitSplitTunneling)?,
rx: internal_event_rx.wait(),
tx: internal_event_tx,
@@ -1010,13 +1014,13 @@ where
GetCurrentVersion(tx) => self.on_get_current_version(tx),
#[cfg(not(target_os = "android"))]
FactoryReset(tx) => self.on_factory_reset(tx),
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
GetSplitTunnelProcesses(tx) => self.on_get_split_tunnel_processes(tx),
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
AddSplitTunnelProcess(tx, pid) => self.on_add_split_tunnel_process(tx, pid),
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
RemoveSplitTunnelProcess(tx, pid) => self.on_remove_split_tunnel_process(tx, pid),
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
ClearSplitTunnelProcesses(tx) => self.on_clear_split_tunnel_processes(tx),
Shutdown => self.trigger_shutdown_event(),
PrepareRestart => self.on_prepare_restart(),
@@ -1381,7 +1385,7 @@ where
}));
}
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
fn on_get_split_tunnel_processes(&mut self, tx: oneshot::Sender<Vec<i32>>) {
match self.exclude_pids.list() {
Ok(pids) => Self::oneshot_send(tx, pids, "get_split_tunnel_processes response"),
@@ -1389,7 +1393,7 @@ where
}
}
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
fn on_add_split_tunnel_process(&mut self, tx: oneshot::Sender<()>, pid: i32) {
match self.exclude_pids.add(pid) {
Ok(()) => Self::oneshot_send(tx, (), "add_split_tunnel_process response"),
@@ -1397,7 +1401,7 @@ where
}
}
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
fn on_remove_split_tunnel_process(&mut self, tx: oneshot::Sender<()>, pid: i32) {
match self.exclude_pids.remove(pid) {
Ok(()) => Self::oneshot_send(tx, (), "remove_split_tunnel_process response"),
@@ -1405,7 +1409,7 @@ where
}
}
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
fn on_clear_split_tunnel_processes(&mut self, tx: oneshot::Sender<()>) {
match self.exclude_pids.clear() {
Ok(()) => Self::oneshot_send(tx, (), "clear_split_tunnel_processes response"),
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 52d793d12f..75ea62168c 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -756,7 +756,7 @@ impl ManagementInterfaceApi for ManagementInterface {
}
fn get_split_tunnel_processes(&self, _: Self::Metadata) -> BoxFuture<Vec<i32>, Error> {
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
{
log::debug!("get_split_tunnel_processes");
let (tx, rx) = sync::oneshot::channel();
@@ -765,46 +765,42 @@ impl ManagementInterfaceApi for ManagementInterface {
.and_then(|_| rx.map_err(|_| Error::internal_error()));
Box::new(future)
}
- #[cfg(not(unix))]
+ #[cfg(not(target_os = "linux"))]
{
Box::new(future::ok(Vec::with_capacity(0)))
}
}
+ #[cfg(target_os = "linux")]
fn add_split_tunnel_process(&self, _: Self::Metadata, pid: i32) -> BoxFuture<(), Error> {
- #[cfg(unix)]
- {
- log::debug!("add_split_tunnel_process");
- let (tx, rx) = sync::oneshot::channel();
- let future = self
- .send_command_to_daemon(DaemonCommand::AddSplitTunnelProcess(tx, pid))
- .and_then(|_| rx.map_err(|_| Error::internal_error()));
- Box::new(future)
- }
- #[cfg(not(unix))]
- {
- Box::new(future::ok(()))
- }
+ log::debug!("add_split_tunnel_process");
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self
+ .send_command_to_daemon(DaemonCommand::AddSplitTunnelProcess(tx, pid))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()));
+ Box::new(future)
+ }
+ #[cfg(not(target_os = "linux"))]
+ fn add_split_tunnel_process(&self, _: Self::Metadata, _: i32) -> BoxFuture<(), Error> {
+ Box::new(future::ok(()))
}
+ #[cfg(target_os = "linux")]
fn remove_split_tunnel_process(&self, _: Self::Metadata, pid: i32) -> BoxFuture<(), Error> {
- #[cfg(unix)]
- {
- log::debug!("remove_split_tunnel_process");
- let (tx, rx) = sync::oneshot::channel();
- let future = self
- .send_command_to_daemon(DaemonCommand::RemoveSplitTunnelProcess(tx, pid))
- .and_then(|_| rx.map_err(|_| Error::internal_error()));
- Box::new(future)
- }
- #[cfg(not(unix))]
- {
- Box::new(future::ok(()))
- }
+ log::debug!("remove_split_tunnel_process");
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self
+ .send_command_to_daemon(DaemonCommand::RemoveSplitTunnelProcess(tx, pid))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()));
+ Box::new(future)
+ }
+ #[cfg(not(target_os = "linux"))]
+ fn remove_split_tunnel_process(&self, _: Self::Metadata, _: i32) -> BoxFuture<(), Error> {
+ Box::new(future::ok(()))
}
fn clear_split_tunnel_processes(&self, _: Self::Metadata) -> BoxFuture<(), Error> {
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
{
log::debug!("clear_split_tunnel_processes");
let (tx, rx) = sync::oneshot::channel();
@@ -813,7 +809,7 @@ impl ManagementInterfaceApi for ManagementInterface {
.and_then(|_| rx.map_err(|_| Error::internal_error()));
Box::new(future)
}
- #[cfg(not(unix))]
+ #[cfg(not(target_os = "linux"))]
{
Box::new(future::ok(()))
}
diff --git a/talpid-core/src/split.rs b/talpid-core/src/split.rs
index 8c9d4fa54a..d72d41cc8f 100644
--- a/talpid-core/src/split.rs
+++ b/talpid-core/src/split.rs
@@ -1,3 +1,4 @@
+#![cfg(target_os = "linux")]
use regex::Regex;
use std::{
fs,
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index 55c4a28697..3c99d5b098 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -75,28 +75,30 @@ impl ConnectedState {
dns_ips.push(ipv6_gateway.into());
};
+ #[cfg(target_os = "linux")]
shared_values
- .dns_monitor
- .set(&self.metadata.interface, &dns_ips)
+ .split_tunnel
+ .route_dns(&self.metadata.interface, &dns_ips)
.map_err(BoxedError::new)?;
shared_values
- .split_tunnel
- .route_dns(&self.metadata.interface, &dns_ips)
+ .dns_monitor
+ .set(&self.metadata.interface, &dns_ips)
.map_err(BoxedError::new)
}
fn reset_dns(shared_values: &mut SharedTunnelStateValues) {
+ if let Err(error) = shared_values.dns_monitor.reset() {
+ log::error!("{}", error.display_chain_with_msg("Unable to reset DNS"));
+ }
+
+ #[cfg(target_os = "linux")]
if let Err(error) = shared_values.split_tunnel.flush_dns() {
log::error!(
"{}",
error.display_chain_with_msg("Unable to update split-tunnel route")
);
}
-
- if let Err(error) = shared_values.dns_monitor.reset() {
- log::error!("{}", error.display_chain_with_msg("Unable to reset DNS"));
- }
}
fn reset_routes(shared_values: &mut SharedTunnelStateValues) {
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index da61626de1..2c895fb707 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -358,13 +358,15 @@ impl TunnelState for ConnectingState {
)
);
ErrorState::enter(shared_values, ErrorStateCause::StartTunnelError)
- } else if let Err(error) = shared_values.split_tunnel.enable_routing() {
- error!(
- "{}",
- error.display_chain_with_msg("Failed to set up split tunneling")
- );
- ErrorState::enter(shared_values, ErrorStateCause::StartTunnelError)
} else {
+ #[cfg(target_os = "linux")]
+ if let Err(error) = shared_values.split_tunnel.enable_routing() {
+ error!(
+ "{}",
+ error.display_chain_with_msg("Failed to set up split tunneling")
+ );
+ }
+
#[cfg(target_os = "android")]
{
if retry_attempt > 0 && retry_attempt % MAX_ATTEMPTS_WITH_SAME_TUN == 0 {
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 7742f276ad..4cb0a97e20 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -39,6 +39,7 @@ impl TunnelState for DisconnectedState {
shared_values: &mut SharedTunnelStateValues,
_: Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ #[cfg(target_os = "linux")]
if let Err(error) = shared_values.split_tunnel.disable_routing() {
log::error!(
"{}",
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 3515a72529..bf4a17bad4 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -14,6 +14,8 @@ use self::{
disconnecting_state::{AfterDisconnect, DisconnectingState},
error_state::ErrorState,
};
+#[cfg(target_os = "linux")]
+use crate::split;
use crate::{
dns::DnsMonitor,
firewall::{Firewall, FirewallArguments},
@@ -52,6 +54,7 @@ pub enum Error {
OfflineMonitorError(#[error(source)] crate::offline::Error),
/// Unable to set up split tunneling
+ #[cfg(target_os = "linux")]
#[error(display = "Failed to initialize split tunneling")]
InitSplitTunneling(#[error(source)] crate::split::Error),
@@ -241,7 +244,7 @@ impl TunnelStateMachine {
}
};
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
let split_tunnel = split::SplitTunnel::new().map_err(Error::InitSplitTunneling)?;
let firewall = Firewall::new(args).map_err(Error::InitFirewallError)?;
@@ -250,7 +253,7 @@ impl TunnelStateMachine {
RouteManager::new(HashSet::new()).map_err(Error::InitRouteManagerError)?;
let mut shared_values = SharedTunnelStateValues {
firewall,
- #[cfg(unix)]
+ #[cfg(target_os = "linux")]
split_tunnel,
dns_monitor,
route_manager,
@@ -336,6 +339,7 @@ pub trait TunnelParametersGenerator: Send + 'static {
/// Values that are common to all tunnel states.
struct SharedTunnelStateValues {
firewall: Firewall,
+ #[cfg(target_os = "linux")]
split_tunnel: split::SplitTunnel,
dns_monitor: DnsMonitor,
route_manager: RouteManager,