summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs14
-rw-r--r--talpid-routing/src/lib.rs2
-rw-r--r--talpid-routing/src/unix/macos/mod.rs4
-rw-r--r--talpid-routing/src/unix/macos/watch.rs8
5 files changed, 27 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index efd3fa6c3b..64a2bda55e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,8 @@ Line wrap the file at 100 chars. Th
#### macOS
- Fix default route not being restored when disconnecting when the gateway was a link-local IPv6
address.
+- Fix app sometimes getting stuck in error state when the connection is unstable. This occurred
+ when the default route was removed while connecting.
### Changed
- Remove `--location` flag from `mullvad status` CLI. Location and IP will now always
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),
}