summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--talpid-core/src/split_tunnel/windows/mod.rs16
-rw-r--r--talpid-core/src/tunnel_state_machine/connected_state.rs241
-rw-r--r--talpid-core/src/tunnel_state_machine/connecting_state.rs14
-rw-r--r--talpid-core/src/tunnel_state_machine/disconnected_state.rs25
-rw-r--r--talpid-core/src/tunnel_state_machine/error_state.rs12
-rw-r--r--talpid-core/src/tunnel_state_machine/mod.rs10
-rw-r--r--talpid-core/src/tunnel_state_machine/windows.rs209
7 files changed, 313 insertions, 214 deletions
diff --git a/talpid-core/src/split_tunnel/windows/mod.rs b/talpid-core/src/split_tunnel/windows/mod.rs
index 6bf8dbc960..7d6ec528f3 100644
--- a/talpid-core/src/split_tunnel/windows/mod.rs
+++ b/talpid-core/src/split_tunnel/windows/mod.rs
@@ -240,6 +240,22 @@ impl SplitTunnel {
internet_ipv4: Ipv4Addr,
internet_ipv6: Option<Ipv6Addr>,
) -> Result<(), Error> {
+ log::debug!(
+ "Register IPs: {} {:?} {} {:?}",
+ tunnel_ipv4,
+ tunnel_ipv6,
+ internet_ipv4,
+ internet_ipv6
+ );
+
+ // If there is no valid internet IPv4 address, ignore any tunnel addresses.
+ // This should only be the case if a reserved tunnel IP is used to keep the driver engaged.
+ let tunnel_ipv4 = if internet_ipv4.is_unspecified() {
+ Ipv4Addr::new(0, 0, 0, 0)
+ } else {
+ tunnel_ipv4
+ };
+
self.handle
.register_ips(tunnel_ipv4, tunnel_ipv6, internet_ipv4, internet_ipv6)
.map_err(Error::RegisterIps)
diff --git a/talpid-core/src/tunnel_state_machine/connected_state.rs b/talpid-core/src/tunnel_state_machine/connected_state.rs
index d7bf24b49e..2511713fc5 100644
--- a/talpid-core/src/tunnel_state_machine/connected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connected_state.rs
@@ -1,26 +1,21 @@
+#[cfg(windows)]
+use super::windows;
use super::{
AfterDisconnect, ConnectingState, DisconnectingState, ErrorState, EventConsequence,
EventResult, SharedTunnelStateValues, TunnelCommand, TunnelCommandReceiver, TunnelState,
TunnelStateTransition, TunnelStateWrapper,
};
+#[cfg(windows)]
+use crate::split_tunnel;
use crate::{
firewall::FirewallPolicy,
tunnel::{CloseHandle, TunnelEvent, TunnelMetadata},
};
-#[cfg(windows)]
-use crate::{
- split_tunnel::{self, SplitTunnel},
- winnet::{self, get_best_default_route, interface_luid_to_ip, WinNetAddrFamily},
-};
use cfg_if::cfg_if;
use futures::{channel::mpsc, stream::Fuse, StreamExt};
-use std::net::IpAddr;
#[cfg(windows)]
-use std::{
- ffi::OsStr,
- net::{Ipv4Addr, Ipv6Addr},
- sync::{Arc, Mutex},
-};
+use std::ffi::OsStr;
+use std::net::IpAddr;
use talpid_types::{
net::TunnelParameters,
tunnel::{ErrorStateCause, FirewallPolicyError},
@@ -127,137 +122,6 @@ impl ConnectedState {
}
}
- #[cfg(target_os = "windows")]
- pub unsafe extern "system" fn split_tunnel_default_route_change_handler(
- event_type: winnet::WinNetDefaultRouteChangeEventType,
- address_family: WinNetAddrFamily,
- default_route: winnet::WinNetDefaultRoute,
- ctx: *mut libc::c_void,
- ) {
- // Update the "internet interface" IP when best default route changes
- let ctx = &mut *(ctx as *mut SplitTunnelDefaultRouteChangeHandlerContext);
-
- let result = match event_type {
- winnet::WinNetDefaultRouteChangeEventType::DefaultRouteChanged => {
- let ip = interface_luid_to_ip(address_family.clone(), default_route.interface_luid);
-
- // TODO: Should we block here?
- let ip = match ip {
- Ok(Some(ip)) => ip,
- Ok(None) => {
- log::error!("Failed to obtain new default route address: none found",);
- // Early return
- return;
- }
- Err(error) => {
- log::error!(
- "{}",
- error.display_chain_with_msg(
- "Failed to obtain new default route address"
- )
- );
- // Early return
- return;
- }
- };
-
- match address_family {
- WinNetAddrFamily::IPV4 => {
- let ip = Ipv4Addr::from(ip);
- ctx.internet_ipv4 = ip;
- }
- WinNetAddrFamily::IPV6 => {
- let ip = Ipv6Addr::from(ip);
- ctx.internet_ipv6 = Some(ip);
- }
- }
-
- ctx.register_ips()
- }
- // no default route
- winnet::WinNetDefaultRouteChangeEventType::DefaultRouteRemoved => {
- match address_family {
- WinNetAddrFamily::IPV4 => {
- ctx.internet_ipv4 = Ipv4Addr::new(0, 0, 0, 0);
- }
- WinNetAddrFamily::IPV6 => {
- ctx.internet_ipv6 = None;
- }
- }
- ctx.register_ips()
- }
- };
-
- if let Err(error) = result {
- // TODO: Should we block here?
- log::error!(
- "{}",
- error.display_chain_with_msg(
- "Failed to register new addresses in split tunnel driver"
- )
- );
- }
- }
-
- #[cfg(windows)]
- fn update_split_tunnel_addresses(
- &self,
- shared_values: &mut SharedTunnelStateValues,
- ) -> Result<(), BoxedError> {
- // Identify tunnel IP addresses
- // TODO: Multiple IP addresses?
- let mut tunnel_ipv4 = None;
- let mut tunnel_ipv6 = None;
-
- for ip in &self.metadata.ips {
- match ip {
- IpAddr::V4(address) => tunnel_ipv4 = Some(address.clone()),
- IpAddr::V6(address) => tunnel_ipv6 = Some(address.clone()),
- }
- }
-
- // Identify IP address that gives us Internet access
- let internet_ipv4 = get_best_default_route(WinNetAddrFamily::IPV4)
- .map_err(BoxedError::new)?
- .map(|route| interface_luid_to_ip(WinNetAddrFamily::IPV4, route.interface_luid))
- .transpose()
- .map_err(BoxedError::new)?
- .flatten();
- let internet_ipv6 = get_best_default_route(WinNetAddrFamily::IPV6)
- .map_err(BoxedError::new)?
- .map(|route| interface_luid_to_ip(WinNetAddrFamily::IPV6, route.interface_luid))
- .transpose()
- .map_err(BoxedError::new)?
- .flatten();
-
- let tunnel_ipv4 = tunnel_ipv4.unwrap_or(Ipv4Addr::new(0, 0, 0, 0));
- let internet_ipv4 = Ipv4Addr::from(internet_ipv4.unwrap_or_default());
- let internet_ipv6 = internet_ipv6.map(|addr| Ipv6Addr::from(addr));
-
- let context = SplitTunnelDefaultRouteChangeHandlerContext::new(
- shared_values.split_tunnel.clone(),
- tunnel_ipv4,
- tunnel_ipv6,
- internet_ipv4,
- internet_ipv6,
- );
-
- shared_values
- .split_tunnel
- .lock()
- .expect("Thread unexpectedly panicked while holding the mutex")
- .register_ips(tunnel_ipv4, tunnel_ipv6, internet_ipv4, internet_ipv6)
- .map_err(BoxedError::new)?;
-
- #[cfg(target_os = "windows")]
- shared_values.route_manager.add_default_route_callback(
- Some(Self::split_tunnel_default_route_change_handler),
- context,
- );
-
- Ok(())
- }
-
fn set_dns(&self, shared_values: &mut SharedTunnelStateValues) -> Result<(), BoxedError> {
let dns_ips = self.get_dns_servers(shared_values);
shared_values
@@ -312,24 +176,6 @@ impl ConnectedState {
Self::reset_dns(shared_values);
Self::reset_routes(shared_values);
- #[cfg(windows)]
- if let Err(error) = shared_values
- .split_tunnel
- .lock()
- .expect("Thread unexpectedly panicked while holding the mutex")
- .register_ips(
- Ipv4Addr::new(0, 0, 0, 0),
- None,
- Ipv4Addr::new(0, 0, 0, 0),
- None,
- )
- {
- log::error!(
- "{}",
- error.display_chain_with_msg("Failed to unregister IP addresses")
- );
- }
-
EventConsequence::NewState(DisconnectingState::enter(
shared_values,
(self.close_handle, self.tunnel_close_event, after_disconnect),
@@ -483,6 +329,27 @@ impl TunnelState for ConnectedState {
let connected_state = ConnectedState::from(bootstrap);
let tunnel_endpoint = connected_state.tunnel_parameters.get_tunnel_endpoint();
+ #[cfg(target_os = "windows")]
+ if let Err(error) =
+ windows::update_split_tunnel_addresses(Some(&connected_state.metadata), shared_values)
+ {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to register addresses with split tunnel driver"
+ )
+ );
+
+ return DisconnectingState::enter(
+ shared_values,
+ (
+ connected_state.close_handle,
+ connected_state.tunnel_close_event,
+ AfterDisconnect::Block(ErrorStateCause::StartTunnelError),
+ ),
+ );
+ }
+
if let Err(error) = connected_state.set_firewall_policy(shared_values) {
DisconnectingState::enter(
shared_values,
@@ -503,19 +370,6 @@ impl TunnelState for ConnectedState {
),
)
} else {
- #[cfg(windows)]
- if let Err(error) = connected_state.update_split_tunnel_addresses(shared_values) {
- log::error!("{}", error.display_chain());
- return DisconnectingState::enter(
- shared_values,
- (
- connected_state.close_handle,
- connected_state.tunnel_close_event,
- AfterDisconnect::Block(ErrorStateCause::StartTunnelError),
- ),
- );
- }
-
(
TunnelStateWrapper::from(connected_state),
TunnelStateTransition::Connected(tunnel_endpoint),
@@ -550,44 +404,3 @@ impl TunnelState for ConnectedState {
}
}
}
-
-#[cfg(target_os = "windows")]
-struct SplitTunnelDefaultRouteChangeHandlerContext {
- split_tunnel: Arc<Mutex<SplitTunnel>>,
- pub tunnel_ipv4: Ipv4Addr,
- pub tunnel_ipv6: Option<Ipv6Addr>,
- pub internet_ipv4: Ipv4Addr,
- pub internet_ipv6: Option<Ipv6Addr>,
-}
-
-#[cfg(target_os = "windows")]
-impl SplitTunnelDefaultRouteChangeHandlerContext {
- pub fn new(
- split_tunnel: Arc<Mutex<SplitTunnel>>,
- tunnel_ipv4: Ipv4Addr,
- tunnel_ipv6: Option<Ipv6Addr>,
- internet_ipv4: Ipv4Addr,
- internet_ipv6: Option<Ipv6Addr>,
- ) -> Self {
- SplitTunnelDefaultRouteChangeHandlerContext {
- split_tunnel,
- tunnel_ipv4,
- tunnel_ipv6,
- internet_ipv4,
- internet_ipv6,
- }
- }
-
- pub fn register_ips(&self) -> Result<(), split_tunnel::Error> {
- let split_tunnel = self
- .split_tunnel
- .lock()
- .expect("Thread unexpectedly panicked while holding the mutex");
- split_tunnel.register_ips(
- self.tunnel_ipv4,
- self.tunnel_ipv6,
- self.internet_ipv4,
- self.internet_ipv6,
- )
- }
-}
diff --git a/talpid-core/src/tunnel_state_machine/connecting_state.rs b/talpid-core/src/tunnel_state_machine/connecting_state.rs
index 34e9eeb2be..cb337c02ab 100644
--- a/talpid-core/src/tunnel_state_machine/connecting_state.rs
+++ b/talpid-core/src/tunnel_state_machine/connecting_state.rs
@@ -33,6 +33,8 @@ use talpid_types::{
};
#[cfg(windows)]
+use super::windows;
+#[cfg(windows)]
use crate::{routing, winnet};
#[cfg(target_os = "android")]
@@ -458,6 +460,18 @@ impl TunnelState for ConnectingState {
ErrorState::enter(shared_values, ErrorStateCause::TunnelParameterError(err))
}
Ok(tunnel_parameters) => {
+ #[cfg(windows)]
+ if let Err(error) = windows::update_split_tunnel_addresses(None, shared_values) {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to register addresses with split tunnel driver"
+ )
+ );
+
+ return ErrorState::enter(shared_values, ErrorStateCause::StartTunnelError);
+ }
+
if let Err(error) =
Self::set_firewall_policy(shared_values, &tunnel_parameters, &None)
{
diff --git a/talpid-core/src/tunnel_state_machine/disconnected_state.rs b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
index cfa7794af7..e4b03bc313 100644
--- a/talpid-core/src/tunnel_state_machine/disconnected_state.rs
+++ b/talpid-core/src/tunnel_state_machine/disconnected_state.rs
@@ -1,3 +1,5 @@
+#[cfg(windows)]
+use super::windows;
use super::{
ConnectingState, ErrorState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
TunnelCommandReceiver, TunnelState, TunnelStateTransition, TunnelStateWrapper,
@@ -52,6 +54,25 @@ impl DisconnectedState {
.expect("Thread unexpectedly panicked while holding the mutex");
split_tunnel.set_paths(paths)
}
+
+ #[cfg(windows)]
+ fn register_split_tunnel_addresses(
+ shared_values: &mut SharedTunnelStateValues,
+ should_reset_firewall: bool,
+ ) {
+ if should_reset_firewall && !shared_values.block_when_disconnected {
+ windows::clear_split_tunnel_addresses(shared_values);
+ } else {
+ if let Err(error) = windows::update_split_tunnel_addresses(None, shared_values) {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to register addresses with split tunnel driver"
+ )
+ );
+ }
+ }
+ }
}
impl TunnelState for DisconnectedState {
@@ -61,6 +82,8 @@ impl TunnelState for DisconnectedState {
shared_values: &mut SharedTunnelStateValues,
should_reset_firewall: Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ #[cfg(windows)]
+ Self::register_split_tunnel_addresses(shared_values, should_reset_firewall);
Self::set_firewall_policy(shared_values, should_reset_firewall);
#[cfg(target_os = "linux")]
shared_values.reset_connectivity_check();
@@ -114,6 +137,8 @@ impl TunnelState for DisconnectedState {
Some(TunnelCommand::BlockWhenDisconnected(block_when_disconnected)) => {
if shared_values.block_when_disconnected != block_when_disconnected {
shared_values.block_when_disconnected = block_when_disconnected;
+ #[cfg(windows)]
+ Self::register_split_tunnel_addresses(shared_values, true);
Self::set_firewall_policy(shared_values, true);
}
SameState(self.into())
diff --git a/talpid-core/src/tunnel_state_machine/error_state.rs b/talpid-core/src/tunnel_state_machine/error_state.rs
index 6d772a62b8..3b2368ada8 100644
--- a/talpid-core/src/tunnel_state_machine/error_state.rs
+++ b/talpid-core/src/tunnel_state_machine/error_state.rs
@@ -1,3 +1,5 @@
+#[cfg(windows)]
+use super::windows;
use super::{
ConnectingState, DisconnectedState, EventConsequence, SharedTunnelStateValues, TunnelCommand,
TunnelCommandReceiver, TunnelState, TunnelStateTransition, TunnelStateWrapper,
@@ -86,6 +88,16 @@ impl TunnelState for ErrorState {
shared_values: &mut SharedTunnelStateValues,
block_reason: Self::Bootstrap,
) -> (TunnelStateWrapper, TunnelStateTransition) {
+ #[cfg(windows)]
+ if let Err(error) = windows::update_split_tunnel_addresses(None, shared_values) {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg(
+ "Failed to register addresses with split tunnel driver"
+ )
+ );
+ }
+
#[cfg(not(target_os = "android"))]
let block_failure = Self::set_firewall_policy(shared_values).err();
#[cfg(target_os = "android")]
diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs
index 969c2116a1..24abecf0d8 100644
--- a/talpid-core/src/tunnel_state_machine/mod.rs
+++ b/talpid-core/src/tunnel_state_machine/mod.rs
@@ -13,6 +13,8 @@ use self::{
};
#[cfg(windows)]
use crate::split_tunnel;
+#[cfg(windows)]
+use crate::winnet::WinNetCallbackHandle;
use crate::{
dns::DnsMonitor,
firewall::{Firewall, FirewallArguments},
@@ -46,6 +48,9 @@ use talpid_types::{
tunnel::{ErrorStateCause, ParameterGenerationError, TunnelStateTransition},
};
+#[cfg(target_os = "windows")]
+mod windows;
+
/// Errors that can happen when setting up or using the state machine.
#[derive(err_derive::Error, Debug)]
pub enum Error {
@@ -283,6 +288,8 @@ impl TunnelStateMachine {
connectivity_check_was_enabled: None,
#[cfg(windows)]
split_tunnel: Arc::new(Mutex::new(split_tunnel)),
+ #[cfg(windows)]
+ st_route_handler: None,
};
let (initial_state, _) = DisconnectedState::enter(&mut shared_values, reset_firewall);
@@ -367,6 +374,9 @@ struct SharedTunnelStateValues {
/// Management of excluded apps.
#[cfg(windows)]
split_tunnel: Arc<Mutex<split_tunnel::SplitTunnel>>,
+ /// Management of excluded apps.
+ #[cfg(windows)]
+ st_route_handler: Option<WinNetCallbackHandle>,
}
impl SharedTunnelStateValues {
diff --git a/talpid-core/src/tunnel_state_machine/windows.rs b/talpid-core/src/tunnel_state_machine/windows.rs
new file mode 100644
index 0000000000..3ea26bf819
--- /dev/null
+++ b/talpid-core/src/tunnel_state_machine/windows.rs
@@ -0,0 +1,209 @@
+#![cfg(windows)]
+
+use super::SharedTunnelStateValues;
+use crate::{
+ split_tunnel::{self, SplitTunnel},
+ tunnel::TunnelMetadata,
+ winnet::{self, get_best_default_route, interface_luid_to_ip, WinNetAddrFamily},
+};
+use lazy_static::lazy_static;
+use std::{
+ net::{IpAddr, Ipv4Addr, Ipv6Addr},
+ sync::{Arc, Mutex},
+};
+use talpid_types::{BoxedError, ErrorExt};
+
+lazy_static! {
+ static ref RESERVED_IP_V4: Ipv4Addr = "192.0.2.123".parse().unwrap();
+}
+
+
+pub(super) fn update_split_tunnel_addresses(
+ metadata: Option<&TunnelMetadata>,
+ shared_values: &mut SharedTunnelStateValues,
+) -> Result<(), BoxedError> {
+ let mut tunnel_ipv4 = None;
+ let mut tunnel_ipv6 = None;
+
+ if let Some(metadata) = metadata {
+ for ip in &metadata.ips {
+ match ip {
+ IpAddr::V4(address) => tunnel_ipv4 = Some(address.clone()),
+ IpAddr::V6(address) => tunnel_ipv6 = Some(address.clone()),
+ }
+ }
+ }
+
+ // Identify IP address that gives us Internet access
+ let internet_ipv4 = get_best_default_route(WinNetAddrFamily::IPV4)
+ .map_err(BoxedError::new)?
+ .map(|route| interface_luid_to_ip(WinNetAddrFamily::IPV4, route.interface_luid))
+ .transpose()
+ .map_err(BoxedError::new)?
+ .flatten();
+ let internet_ipv6 = get_best_default_route(WinNetAddrFamily::IPV6)
+ .map_err(BoxedError::new)?
+ .map(|route| interface_luid_to_ip(WinNetAddrFamily::IPV6, route.interface_luid))
+ .transpose()
+ .map_err(BoxedError::new)?
+ .flatten();
+
+ let tunnel_ipv4 = tunnel_ipv4.unwrap_or(*RESERVED_IP_V4);
+ let internet_ipv4 = Ipv4Addr::from(internet_ipv4.unwrap_or_default());
+ let internet_ipv6 = internet_ipv6.map(|addr| Ipv6Addr::from(addr));
+
+ let context = SplitTunnelDefaultRouteChangeHandlerContext::new(
+ shared_values.split_tunnel.clone(),
+ tunnel_ipv4,
+ tunnel_ipv6,
+ internet_ipv4,
+ internet_ipv6,
+ );
+
+ shared_values.st_route_handler = None;
+
+ shared_values
+ .split_tunnel
+ .lock()
+ .expect("Thread unexpectedly panicked while holding the mutex")
+ .register_ips(tunnel_ipv4, tunnel_ipv6, internet_ipv4, internet_ipv6)
+ .map_err(BoxedError::new)?;
+
+ // FIXME: Do this via the route manager
+ shared_values.st_route_handler = Some(
+ crate::winnet::add_default_route_change_callback(
+ Some(split_tunnel_default_route_change_handler),
+ context,
+ )
+ .map_err(BoxedError::new)?,
+ );
+
+ Ok(())
+}
+
+pub(super) fn clear_split_tunnel_addresses(shared_values: &mut SharedTunnelStateValues) {
+ shared_values.st_route_handler = None;
+
+ if let Err(error) = shared_values
+ .split_tunnel
+ .lock()
+ .expect("Thread unexpectedly panicked while holding the mutex")
+ .register_ips(
+ Ipv4Addr::new(0, 0, 0, 0),
+ None,
+ Ipv4Addr::new(0, 0, 0, 0),
+ None,
+ )
+ {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Failed to unregister IP addresses")
+ );
+ }
+}
+
+pub unsafe extern "system" fn split_tunnel_default_route_change_handler(
+ event_type: winnet::WinNetDefaultRouteChangeEventType,
+ address_family: WinNetAddrFamily,
+ default_route: winnet::WinNetDefaultRoute,
+ ctx: *mut libc::c_void,
+) {
+ // Update the "internet interface" IP when best default route changes
+ let ctx = &mut *(ctx as *mut SplitTunnelDefaultRouteChangeHandlerContext);
+
+ let result = match event_type {
+ winnet::WinNetDefaultRouteChangeEventType::DefaultRouteChanged => {
+ let ip = interface_luid_to_ip(address_family.clone(), default_route.interface_luid);
+
+ // TODO: Should we block here?
+ let ip = match ip {
+ Ok(Some(ip)) => ip,
+ Ok(None) => {
+ log::error!("Failed to obtain new default route address: none found",);
+ // Early return
+ return;
+ }
+ Err(error) => {
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Failed to obtain new default route address")
+ );
+ // Early return
+ return;
+ }
+ };
+
+ match address_family {
+ WinNetAddrFamily::IPV4 => {
+ let ip = Ipv4Addr::from(ip);
+ ctx.internet_ipv4 = ip;
+ }
+ WinNetAddrFamily::IPV6 => {
+ let ip = Ipv6Addr::from(ip);
+ ctx.internet_ipv6 = Some(ip);
+ }
+ }
+
+ ctx.register_ips()
+ }
+ // no default route
+ winnet::WinNetDefaultRouteChangeEventType::DefaultRouteRemoved => {
+ match address_family {
+ WinNetAddrFamily::IPV4 => {
+ ctx.internet_ipv4 = Ipv4Addr::new(0, 0, 0, 0);
+ }
+ WinNetAddrFamily::IPV6 => {
+ ctx.internet_ipv6 = None;
+ }
+ }
+ ctx.register_ips()
+ }
+ };
+
+ if let Err(error) = result {
+ // TODO: Should we block here?
+ log::error!(
+ "{}",
+ error.display_chain_with_msg("Failed to register new addresses in split tunnel driver")
+ );
+ }
+}
+
+struct SplitTunnelDefaultRouteChangeHandlerContext {
+ split_tunnel: Arc<Mutex<SplitTunnel>>,
+ pub tunnel_ipv4: Ipv4Addr,
+ pub tunnel_ipv6: Option<Ipv6Addr>,
+ pub internet_ipv4: Ipv4Addr,
+ pub internet_ipv6: Option<Ipv6Addr>,
+}
+
+impl SplitTunnelDefaultRouteChangeHandlerContext {
+ pub fn new(
+ split_tunnel: Arc<Mutex<SplitTunnel>>,
+ tunnel_ipv4: Ipv4Addr,
+ tunnel_ipv6: Option<Ipv6Addr>,
+ internet_ipv4: Ipv4Addr,
+ internet_ipv6: Option<Ipv6Addr>,
+ ) -> Self {
+ SplitTunnelDefaultRouteChangeHandlerContext {
+ split_tunnel,
+ tunnel_ipv4,
+ tunnel_ipv6,
+ internet_ipv4,
+ internet_ipv6,
+ }
+ }
+
+ pub fn register_ips(&self) -> Result<(), split_tunnel::Error> {
+ let split_tunnel = self
+ .split_tunnel
+ .lock()
+ .expect("Thread unexpectedly panicked while holding the mutex");
+ split_tunnel.register_ips(
+ self.tunnel_ipv4,
+ self.tunnel_ipv6,
+ self.internet_ipv4,
+ self.internet_ipv6,
+ )
+ }
+}