Skip to content

Commit

Permalink
Reconnect if default route disappears while connecting on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
dlon committed Jan 15, 2024
1 parent fbdcaa4 commit 6f2bddd
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 3 deletions.
14 changes: 13 additions & 1 deletion talpid-core/src/tunnel_state_machine/connecting_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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>,
Expand Down
2 changes: 1 addition & 1 deletion talpid-routing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
4 changes: 3 additions & 1 deletion talpid-routing/src/unix/macos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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),

Expand Down
8 changes: 8 additions & 0 deletions talpid-routing/src/unix/macos/watch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down

0 comments on commit 6f2bddd

Please sign in to comment.