diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-01-15 14:20:01 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-01-15 16:56:35 +0100 |
| commit | 6f2bddd8ceb6204906c43c847c7e0380b462d4ec (patch) | |
| tree | 449feb17b7166bb4591e1ceeb95738bc80936b2f | |
| parent | fbdcaa4f1ab82d1ba6b49fe8fc362b72efe9061e (diff) | |
| download | mullvadvpn-6f2bddd8ceb6204906c43c847c7e0380b462d4ec.tar.xz mullvadvpn-6f2bddd8ceb6204906c43c847c7e0380b462d4ec.zip | |
Reconnect if default route disappears while connecting on macOS
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/connecting_state.rs | 14 | ||||
| -rw-r--r-- | talpid-routing/src/lib.rs | 2 | ||||
| -rw-r--r-- | talpid-routing/src/unix/macos/mod.rs | 4 | ||||
| -rw-r--r-- | talpid-routing/src/unix/macos/watch.rs | 8 |
4 files changed, 25 insertions, 3 deletions
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index e49e5b69d8..75f3d8eebf 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -599,7 +599,7 @@ fn should_retry(error: &tunnel::Error, retry_attempt: u32) -> bool { TunnelError::BypassError(_), )) => true, - #[cfg(windows)] + #[cfg(any(target_os = "windows", target_os = "macos"))] tunnel::Error::WireguardTunnelMonitoringError(Error::SetupRoutingError(error)) => { is_recoverable_routing_error(error) } @@ -624,6 +624,18 @@ fn is_recoverable_routing_error(error: &talpid_routing::Error) -> bool { matches!(error, talpid_routing::Error::AddRoutesFailed(_)) } +#[cfg(target_os = "macos")] +fn is_recoverable_routing_error(error: &talpid_routing::Error) -> bool { + // If the default route disappears while connecting but before it is caught by the offline + // monitor, then the gateway will be unreachable. In this case, just retry. + matches!( + error, + talpid_routing::Error::PlatformError(talpid_routing::PlatformError::AddRoute( + talpid_routing::RouteError::Unreachable, + )) + ) +} + impl TunnelState for ConnectingState { fn handle_event( mut self: Box<Self>, diff --git a/talpid-routing/src/lib.rs b/talpid-routing/src/lib.rs index 7bb337b127..aa43490419 100644 --- a/talpid-routing/src/lib.rs +++ b/talpid-routing/src/lib.rs @@ -23,7 +23,7 @@ mod imp; use netlink_packet_route::rtnl::constants::RT_TABLE_MAIN; #[cfg(target_os = "macos")] -pub use imp::{DefaultRouteEvent, PlatformError}; +pub use imp::{imp::RouteError, DefaultRouteEvent, PlatformError}; pub use imp::{Error, RouteManager}; diff --git a/talpid-routing/src/unix/macos/mod.rs b/talpid-routing/src/unix/macos/mod.rs index ec5da51bae..9c01b70820 100644 --- a/talpid-routing/src/unix/macos/mod.rs +++ b/talpid-routing/src/unix/macos/mod.rs @@ -23,6 +23,8 @@ mod interface; mod routing_socket; mod watch; +pub use watch::Error as RouteError; + pub type Result<T> = std::result::Result<T, Error>; const BURST_BUFFER_PERIOD: Duration = Duration::from_millis(200); @@ -36,7 +38,7 @@ pub enum Error { #[error(display = "Error occurred when interfacing with the routing table")] RoutingTable(#[error(source)] watch::Error), - /// Failed to remvoe route + /// Failed to remove route #[error(display = "Error occurred when deleting a route")] DeleteRoute(#[error(source)] watch::Error), diff --git a/talpid-routing/src/unix/macos/watch.rs b/talpid-routing/src/unix/macos/watch.rs index 9e5f6442ca..d22a262e2c 100644 --- a/talpid-routing/src/unix/macos/watch.rs +++ b/talpid-routing/src/unix/macos/watch.rs @@ -6,20 +6,28 @@ use std::io; type Result<T> = std::result::Result<T, Error>; +/// Errors that can occur for a PF_ROUTE socket #[derive(Debug, err_derive::Error)] pub enum Error { + /// Generic routing socket error #[error(display = "Routing socket error: {}", _0)] RoutingSocket(routing_socket::Error), + /// Failed to parse route message #[error(display = "Invalid message")] InvalidMessage(data::Error), + /// Failed to send route message #[error(display = "Failed to send routing message")] Send(routing_socket::Error), + /// Received unexpected response to route message #[error(display = "Unexpected message type")] UnexpectedMessageType(RouteSocketMessage, MessageType), + /// Route not found #[error(display = "Route not found")] RouteNotFound, + /// No route to destination #[error(display = "Destination unreachable")] Unreachable, + /// Failed to delete route #[error(display = "Failed to delete a route")] Deletion(RouteMessage), } |
