summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2024-07-30 13:04:20 +0200
committerMarkus Pettersson <markus.pettersson@mullvad.net>2024-07-30 14:22:18 +0200
commit5c9d6fc2de0c44c22a003b30fb83c1532b7ca9d0 (patch)
treec7c7709779dd410f15c3214ca7f427da4b181240
parenta9464196dbf588e193b133927b2ef54bca323e2c (diff)
downloadmullvadvpn-5c9d6fc2de0c44c22a003b30fb83c1532b7ca9d0.tar.xz
mullvadvpn-5c9d6fc2de0c44c22a003b30fb83c1532b7ca9d0.zip
Reconnect if split tunnel state changed
-rw-r--r--mullvad-management-interface/src/types/conversions/states.rs6
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs22
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs18
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs7
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnecting_state.rs21
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs7
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs19
-rw-r--r--talpid-tunnel/src/tun_provider/android/mod.rs2
-rw-r--r--talpid-types/src/tunnel.rs4
9 files changed, 85 insertions, 21 deletions
diff --git a/mullvad-management-interface/src/types/conversions/states.rs b/mullvad-management-interface/src/types/conversions/states.rs
index 3fd8fbacb5..80dbb8bf2f 100644
--- a/mullvad-management-interface/src/types/conversions/states.rs
+++ b/mullvad-management-interface/src/types/conversions/states.rs
@@ -107,7 +107,11 @@ impl From<mullvad_types::states::TunnelState> for proto::TunnelState {
talpid_tunnel::ErrorStateCause::InvalidDnsServers(_) => {
i32::from(Cause::SetDnsError)
}
- #[cfg(any(target_os = "windows", target_os = "macos"))]
+ #[cfg(any(
+ target_os = "windows",
+ target_os = "macos",
+ target_os = "android"
+ ))]
talpid_tunnel::ErrorStateCause::SplitTunnelError => {
i32::from(Cause::SplitTunnelError)
}
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index 0e4b095bf5..bd67e975ef 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -330,11 +330,31 @@ impl ConnectedState {
shared_values.bypass_socket(fd, done_tx);
SameState(self)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
SameState(self)
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ match shared_values.exclude_paths(paths) {
+ Ok(changed) => {
+ let _ = result_tx.send(Ok(()));
+ if changed {
+ self.disconnect(shared_values, AfterDisconnect::Reconnect(0))
+ } else {
+ SameState(self)
+ }
+ }
+ Err(err) => {
+ let _ = result_tx.send(Err(err));
+ self.disconnect(
+ shared_values,
+ AfterDisconnect::Block(ErrorStateCause::SplitTunnelError),
+ )
+ }
+ }
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
match shared_values.set_exclude_paths(paths) {
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index ce347e764a..9e6a21190c 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -470,11 +470,27 @@ impl ConnectingState {
shared_values.bypass_socket(fd, done_tx);
SameState(self)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
SameState(self)
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ match shared_values.exclude_paths(paths) {
+ Ok(_changed) => {
+ let _ = result_tx.send(Ok(()));
+ SameState(self)
+ }
+ Err(error) => {
+ let _ = result_tx.send(Err(error));
+ self.disconnect(
+ shared_values,
+ AfterDisconnect::Block(ErrorStateCause::SplitTunnelError),
+ )
+ }
+ }
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
match shared_values.set_exclude_paths(paths) {
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index 326ae5070b..e570d3af64 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -211,11 +211,16 @@ impl TunnelState for DisconnectedState {
shared_values.bypass_socket(fd, done_tx);
SameState(self)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
SameState(self)
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ let _ = result_tx.send(shared_values.exclude_paths(paths).map(|_| ()));
+ SameState(self)
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
let _ = result_tx.send(shared_values.set_exclude_paths(paths).map(|_| ()));
diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
index def8b246e9..099208201e 100644
--- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs
@@ -76,11 +76,16 @@ impl DisconnectingState {
shared_values.bypass_socket(fd, done_tx);
AfterDisconnect::Nothing
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
AfterDisconnect::Nothing
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ let _ = result_tx.send(shared_values.exclude_paths(paths).map(|_| ()));
+ AfterDisconnect::Nothing
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
let _ = result_tx.send(shared_values.set_exclude_paths(paths).map(|_| ()));
@@ -127,11 +132,16 @@ impl DisconnectingState {
shared_values.bypass_socket(fd, done_tx);
AfterDisconnect::Block(reason)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
AfterDisconnect::Block(reason)
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ let _ = result_tx.send(shared_values.exclude_paths(paths).map(|_| ()));
+ AfterDisconnect::Block(reason)
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
let _ = result_tx.send(shared_values.set_exclude_paths(paths).map(|_| ()));
@@ -179,11 +189,16 @@ impl DisconnectingState {
shared_values.bypass_socket(fd, done_tx);
AfterDisconnect::Reconnect(retry_attempt)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
AfterDisconnect::Reconnect(retry_attempt)
}
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ let _ = result_tx.send(shared_values.exclude_paths(paths).map(|_| ()));
+ AfterDisconnect::Reconnect(retry_attempt)
+ }
#[cfg(target_os = "macos")]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
let _ = result_tx.send(shared_values.set_exclude_paths(paths).map(|_| ()));
diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs
index 19630cb7b0..b4f642d8e2 100644
--- a/talpid-core/src/tunnel_state_machine/error_state.rs
+++ b/talpid-core/src/tunnel_state_machine/error_state.rs
@@ -211,7 +211,12 @@ impl TunnelState for ErrorState {
shared_values.bypass_socket(fd, done_tx);
SameState(self)
}
- #[cfg(any(windows, target_os = "android"))]
+ #[cfg(target_os = "android")]
+ Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
+ let _ = result_tx.send(shared_values.exclude_paths(paths).map(|_| ()));
+ SameState(self)
+ }
+ #[cfg(windows)]
Some(TunnelCommand::SetExcludedApps(result_tx, paths)) => {
shared_values.exclude_paths(paths, result_tx);
SameState(self)
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 95a90e26c1..f1f0340cd9 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -651,14 +651,10 @@ impl SharedTunnelStateValues {
}
/// Update the set of excluded paths (split tunnel apps) for the tunnel provider.
+ /// Returns `Ok(true)` if the tunnel state machine should issue a tunnel reconnect.
#[cfg(target_os = "android")]
- pub fn exclude_paths(
- &mut self,
- apps: Vec<String>,
- tx: oneshot::Sender<Result<(), split_tunnel::Error>>,
- ) {
- let exclude_apps_result = self
- .tun_provider
+ pub fn exclude_paths(&mut self, apps: Vec<String>) -> Result<bool, split_tunnel::Error> {
+ self.tun_provider
.lock()
.unwrap()
.set_exclude_apps(apps)
@@ -670,9 +666,12 @@ impl SharedTunnelStateValues {
"Failed to restart tunnel after updating excluded apps",
)
);
- });
-
- let _ = tx.send(exclude_apps_result);
+ })?;
+ // NOTE: For now, we tell the TSM to always reconnect when this function has been
+ // successfully called. We still return a boolean value in case we would like to introduce
+ // some condition in the future, thus forcing the TSM to be ready to handle both cases
+ // already.
+ Ok(true)
}
}
diff --git a/talpid-tunnel/src/tun_provider/android/mod.rs b/talpid-tunnel/src/tun_provider/android/mod.rs
index 9ebae88ea3..f8ede32954 100644
--- a/talpid-tunnel/src/tun_provider/android/mod.rs
+++ b/talpid-tunnel/src/tun_provider/android/mod.rs
@@ -299,7 +299,7 @@ impl AndroidTunProvider {
}
fn prepare_tun_config_for_excluded_apps(&self, config: &mut TunConfig) {
- config.excluded_packages = self.excluded_apps.clone();
+ config.excluded_packages.clone_from(&self.excluded_apps);
}
/// Allow a socket to bypass the tunnel.
diff --git a/talpid-types/src/tunnel.rs b/talpid-types/src/tunnel.rs
index a3b2eb5638..eb8d155e35 100644
--- a/talpid-types/src/tunnel.rs
+++ b/talpid-types/src/tunnel.rs
@@ -96,7 +96,7 @@ pub enum ErrorStateCause {
#[cfg(target_os = "android")]
VpnPermissionDenied,
/// Error reported by split tunnel module.
- #[cfg(any(target_os = "windows", target_os = "macos"))]
+ #[cfg(any(target_os = "windows", target_os = "macos", target_os = "android"))]
SplitTunnelError,
/// Missing permissions required by macOS split tunneling.
#[cfg(target_os = "macos")]
@@ -202,7 +202,7 @@ impl fmt::Display for ErrorStateCause {
IsOffline => "This device is offline, no tunnels can be established",
#[cfg(target_os = "android")]
VpnPermissionDenied => "The Android VPN permission was denied when creating the tunnel",
- #[cfg(any(target_os = "windows", target_os = "macos"))]
+ #[cfg(any(target_os = "windows", target_os = "macos", target_os = "android"))]
SplitTunnelError => "The split tunneling module reported an error",
#[cfg(target_os = "macos")]
NeedFullDiskPermissions => "Need full disk access to enable split tunneling",