diff options
| author | David Göransson <david.goransson@mullvad.net> | 2024-11-18 14:23:05 +0100 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2024-11-27 09:00:18 +0100 |
| commit | 1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988 (patch) | |
| tree | a83565926fb753a2dd9fd24f0e2bd07262e4507e /talpid-core/src | |
| parent | 0d155385e1cb7075012bd270de0398d83a438bc5 (diff) | |
| download | mullvadvpn-1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988.tar.xz mullvadvpn-1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988.zip | |
Handle legacy always-on vpn profiles
Co-authored-by: Jonatan Rhodin <jonatan.rhodin@mullvad.net>
Diffstat (limited to 'talpid-core/src')
6 files changed, 54 insertions, 18 deletions
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs index b2ebd7a3fe..eadb313501 100644 --- a/talpid-core/src/tunnel_state_machine/connected_state.rs +++ b/talpid-core/src/tunnel_state_machine/connected_state.rs @@ -13,6 +13,8 @@ use futures::{ stream::Fuse, StreamExt, }; +#[cfg(target_os = "android")] +use talpid_tunnel::tun_provider::Error; use talpid_types::{ net::{AllowedClients, AllowedEndpoint, TunnelParameters}, tunnel::{ErrorStateCause, FirewallPolicyError}, @@ -283,6 +285,7 @@ impl ConnectedState { let _ = complete_tx.send(()); consequence } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { shared_values.allowed_endpoint = endpoint; let _ = tx.send(()); @@ -293,10 +296,18 @@ impl ConnectedState { #[cfg(target_os = "android")] { if let Err(_err) = shared_values.restart_tunnel(false) { - self.disconnect( - shared_values, - AfterDisconnect::Block(ErrorStateCause::StartTunnelError), - ) + match _err { + Error::InvalidDnsServers(ip_addrs) => self.disconnect( + shared_values, + AfterDisconnect::Block(ErrorStateCause::InvalidDnsServers( + ip_addrs, + )), + ), + _ => self.disconnect( + shared_values, + AfterDisconnect::Block(ErrorStateCause::StartTunnelError), + ), + } } else { self.disconnect(shared_values, AfterDisconnect::Reconnect(0)) } diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index 6739cb4402..f07a941ac1 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -267,14 +267,34 @@ impl ConnectingState { log::error!("{}", error.display_chain_with_msg("Failed to start tunnel")); let block_reason = match error { tunnel::Error::EnableIpv6Error => ErrorStateCause::Ipv6Unavailable, + #[cfg(target_os = "android")] tunnel::Error::WireguardTunnelMonitoringError( talpid_wireguard::Error::TunnelError( talpid_wireguard::TunnelError::SetupTunnelDevice( - tun_provider::Error::PermissionDenied, + tun_provider::Error::OtherLegacyAlwaysOnVpn, ), ), - ) => ErrorStateCause::VpnPermissionDenied, + ) => ErrorStateCause::OtherLegacyAlwaysOnVpn, + + #[cfg(target_os = "android")] + tunnel::Error::WireguardTunnelMonitoringError( + talpid_wireguard::Error::TunnelError( + talpid_wireguard::TunnelError::SetupTunnelDevice( + tun_provider::Error::OtherAlwaysOnApp { app_name }, + ), + ), + ) => ErrorStateCause::OtherAlwaysOnApp { app_name }, + + #[cfg(target_os = "android")] + tunnel::Error::WireguardTunnelMonitoringError( + talpid_wireguard::Error::TunnelError( + talpid_wireguard::TunnelError::SetupTunnelDevice( + tun_provider::Error::NotPrepared, + ), + ), + ) => ErrorStateCause::NotPrepared, + #[cfg(target_os = "android")] tunnel::Error::WireguardTunnelMonitoringError( talpid_wireguard::Error::TunnelError( @@ -435,6 +455,7 @@ impl ConnectingState { let _ = complete_tx.send(()); consequence } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { if shared_values.allowed_endpoint != endpoint { shared_values.allowed_endpoint = endpoint; diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs index 12e9c5aaa2..de1d4822cb 100644 --- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs @@ -173,6 +173,7 @@ impl TunnelState for DisconnectedState { let _ = complete_tx.send(()); SameState(self) } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { if shared_values.allowed_endpoint != endpoint { shared_values.allowed_endpoint = endpoint; diff --git a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs index b8d43ac7e9..781ccaeede 100644 --- a/talpid-core/src/tunnel_state_machine/disconnecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnecting_state.rs @@ -45,6 +45,7 @@ impl DisconnectingState { let _ = complete_tx.send(()); AfterDisconnect::Nothing } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { shared_values.allowed_endpoint = endpoint; let _ = tx.send(()); @@ -100,6 +101,8 @@ impl DisconnectingState { let _ = complete_tx.send(()); AfterDisconnect::Block(reason) } + + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { shared_values.allowed_endpoint = endpoint; let _ = tx.send(()); @@ -159,6 +162,7 @@ impl DisconnectingState { let _ = complete_tx.send(()); AfterDisconnect::Reconnect(retry_attempt) } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { shared_values.allowed_endpoint = endpoint; let _ = tx.send(()); diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs index a9ba470bfb..bdd8e9a014 100644 --- a/talpid-core/src/tunnel_state_machine/error_state.rs +++ b/talpid-core/src/tunnel_state_machine/error_state.rs @@ -4,12 +4,13 @@ use super::{ }; #[cfg(target_os = "macos")] use crate::dns::DnsConfig; +#[cfg(not(target_os = "android"))] use crate::firewall::FirewallPolicy; use futures::StreamExt; #[cfg(target_os = "macos")] use std::net::Ipv4Addr; use talpid_types::{ - tunnel::{self as talpid_tunnel, ErrorStateCause, FirewallPolicyError}, + tunnel::{ErrorStateCause, FirewallPolicyError}, ErrorExt, }; @@ -66,13 +67,14 @@ impl ErrorState { Box::new(ErrorState { block_reason: block_reason.clone(), }), - TunnelStateTransition::Error(talpid_tunnel::ErrorState::new( + TunnelStateTransition::Error(talpid_types::tunnel::ErrorState::new( block_reason, block_failure, )), ) } + #[cfg(not(target_os = "android"))] fn set_firewall_policy( shared_values: &mut SharedTunnelStateValues, ) -> Result<(), FirewallPolicyError> { @@ -145,19 +147,11 @@ impl TunnelState for ErrorState { let _ = complete_tx.send(()); consequence } + #[cfg(not(target_os = "android"))] Some(TunnelCommand::AllowEndpoint(endpoint, tx)) => { if shared_values.allowed_endpoint != endpoint { shared_values.allowed_endpoint = endpoint; let _ = Self::set_firewall_policy(shared_values); - - #[cfg(target_os = "android")] - if let Err(_err) = shared_values.restart_tunnel(true) { - let _ = tx.send(()); - return NewState(Self::enter( - shared_values, - ErrorStateCause::SetFirewallPolicyError(FirewallPolicyError::Generic), - )); - } } let _ = tx.send(()); SameState(self) @@ -168,7 +162,11 @@ impl TunnelState for ErrorState { { // DNS is blocked in the error state, so only update tun config shared_values.prepare_tun_config(true); - SameState(self) + if let ErrorStateCause::InvalidDnsServers(_) = self.block_reason { + NewState(ConnectingState::enter(shared_values, 0)) + } else { + SameState(self) + } } #[cfg(not(target_os = "android"))] { diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 2541bc88e6..57ee4e6ecb 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -192,6 +192,7 @@ pub enum TunnelCommand { /// Endpoint that should never be blocked. `()` is sent to the /// channel after attempting to set the firewall policy, regardless /// of whether it succeeded. + #[cfg(not(target_os = "android"))] AllowEndpoint(AllowedEndpoint, oneshot::Sender<()>), /// Set DNS configuration to use. Dns(crate::dns::DnsConfig, oneshot::Sender<()>), |
