diff --git a/talpid-core/src/split_tunnel/windows/mod.rs b/talpid-core/src/split_tunnel/windows/mod.rs index ee2a4d354e64..63a428b07f86 100644 --- a/talpid-core/src/split_tunnel/windows/mod.rs +++ b/talpid-core/src/split_tunnel/windows/mod.rs @@ -783,6 +783,12 @@ impl SplitTunnel { self.send_request(Request::RegisterIps(InterfaceAddresses::default())) } + /// Returns whether connections are being redirected. + pub fn has_tunnel_addresses(&self) -> bool { + // NOTE: Relying on assumption that `set_tunnel_addresses` was used here. + self._route_change_callback.is_some() + } + /// Returns a handle used for interacting with the split tunnel module. pub fn handle(&self) -> SplitTunnelHandle { SplitTunnelHandle { diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs index ad91cb184aca..96a1c93d939a 100644 --- a/talpid-core/src/tunnel_state_machine/connecting_state.rs +++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs @@ -404,6 +404,8 @@ impl ConnectingState { AfterDisconnect::Block(ErrorStateCause::AuthFailed(reason)), ), Some((TunnelEvent::InterfaceUp(metadata, allowed_tunnel_traffic), _done_tx)) => { + // NOTE: It is crucial to set the correct tunnel IP before allowing any traffic into + // the tunnel, as leaks into the tunnel are possible otherwise. #[cfg(windows)] if let Err(error) = shared_values .split_tunnel @@ -544,18 +546,6 @@ impl TunnelState for ConnectingState { ErrorState::enter(shared_values, ErrorStateCause::TunnelParameterError(err)) } Ok(tunnel_parameters) => { - #[cfg(windows)] - if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) { - log::error!( - "{}", - error.display_chain_with_msg( - "Failed to reset addresses in split tunnel driver" - ) - ); - - return ErrorState::enter(shared_values, ErrorStateCause::SplitTunnelError); - } - if let Err(error) = Self::set_firewall_policy( shared_values, &tunnel_parameters, diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs index b6b52bbc45e5..5ebe8babfdcc 100644 --- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs +++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs @@ -51,21 +51,21 @@ impl DisconnectedState { shared_values: &mut SharedTunnelStateValues, should_reset_firewall: bool, ) { - if should_reset_firewall && !shared_values.block_when_disconnected { - if let Err(error) = shared_values.split_tunnel.clear_tunnel_addresses() { + if shared_values.block_when_disconnected { + if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) { log::error!( "{}", - error.display_chain_with_msg( - "Failed to unregister addresses with split tunnel driver" - ) + error + .display_chain_with_msg("Failed to reset addresses in split tunnel driver") ); } - } else { - if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) { + } else if should_reset_firewall { + if let Err(error) = shared_values.split_tunnel.clear_tunnel_addresses() { log::error!( "{}", - error - .display_chain_with_msg("Failed to reset addresses in split tunnel driver") + error.display_chain_with_msg( + "Failed to unregister addresses with split tunnel driver" + ) ); } } diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs index 7fe95c9f673e..706f67fc75aa 100644 --- a/talpid-core/src/tunnel_state_machine/error_state.rs +++ b/talpid-core/src/tunnel_state_machine/error_state.rs @@ -85,13 +85,17 @@ impl TunnelState for ErrorState { block_reason: Self::Bootstrap, ) -> (TunnelStateWrapper, TunnelStateTransition) { #[cfg(windows)] - if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) { - log::error!( - "{}", - error.display_chain_with_msg( - "Failed to register addresses with split tunnel driver" - ) - ); + if !block_reason.prevents_split_tunneling() + && !shared_values.split_tunnel.has_tunnel_addresses() + { + if let Err(error) = shared_values.split_tunnel.set_tunnel_addresses(None) { + log::error!( + "{}", + error.display_chain_with_msg( + "Failed to register addresses with split tunnel driver" + ) + ); + } } #[cfg(target_os = "macos")] diff --git a/talpid-types/src/tunnel.rs b/talpid-types/src/tunnel.rs index 31f78c28943b..db28dc14dd57 100644 --- a/talpid-types/src/tunnel.rs +++ b/talpid-types/src/tunnel.rs @@ -114,6 +114,11 @@ impl ErrorStateCause { _ => false, } } + + #[cfg(target_os = "windows")] + pub fn prevents_split_tunneling(&self) -> bool { + matches!(self, Self::SplitTunnelError | Self::IsOffline) + } } /// Errors that can occur when generating tunnel parameters.