diff options
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 6 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/windows.rs | 26 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/windows.rs | 16 |
3 files changed, 45 insertions, 3 deletions
diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs index 22d9147adc..dd9fdd0e63 100644 --- a/talpid-core/src/tunnel/openvpn/mod.rs +++ b/talpid-core/src/tunnel/openvpn/mod.rs @@ -275,6 +275,7 @@ trait WintunContext: Send + Sync { fn luid(&self) -> NET_LUID; fn ipv6(&self) -> bool; async fn wait_for_interfaces(&self) -> io::Result<()>; + fn disable_unused_features(&self) {} } #[cfg(windows)] @@ -312,6 +313,10 @@ impl WintunContext for WintunContextImpl { let luid = self.adapter.adapter().luid(); super::windows::wait_for_interfaces(luid, true, self.wait_v6_interface).await } + + fn disable_unused_features(&self) { + self.adapter.adapter().try_disable_unused_features(); + } } @@ -580,6 +585,7 @@ impl<C: OpenVpnBuilder + Send + 'static> OpenVpnMonitor<C> { { log::debug!("Wait for IP interfaces"); wintun.wait_for_interfaces().await?; + wintun.disable_unused_features(); } cmd.start() } diff --git a/talpid-core/src/tunnel/openvpn/windows.rs b/talpid-core/src/tunnel/openvpn/windows.rs index 9b907e101a..16869cb20c 100644 --- a/talpid-core/src/tunnel/openvpn/windows.rs +++ b/talpid-core/src/tunnel/openvpn/windows.rs @@ -1,3 +1,4 @@ +use crate::tunnel::windows::{get_ip_interface_entry, set_ip_interface_entry}; use std::{ ffi::CStr, fmt, io, iter, mem, @@ -14,7 +15,10 @@ use winapi::{ ifdef::NET_LUID, minwindef::{BOOL, FARPROC, HINSTANCE, HMODULE}, netioapi::ConvertInterfaceLuidToGuid, + nldef::RouterDiscoveryDisabled, + ntdef::FALSE, winerror::NO_ERROR, + ws2def::{AF_INET, AF_INET6}, }, um::{ libloaderapi::{ @@ -154,6 +158,28 @@ impl WintunAdapter { Ok((Self { dll_handle, handle }, restart_required)) } + pub fn try_disable_unused_features(&self) { + // Disable DAD, DHCP, and router discovery + let luid = self.luid(); + for family in &[AF_INET, AF_INET6] { + if let Ok(mut row) = get_ip_interface_entry(*family as u16, &luid) { + row.SitePrefixLength = 0; + row.RouterDiscoveryBehavior = RouterDiscoveryDisabled; + row.DadTransmits = 0; + row.ManagedAddressConfigurationSupported = FALSE; + row.OtherStatefulConfigurationSupported = FALSE; + + if let Err(error) = set_ip_interface_entry(&row) { + log::error!( + "{} (family: {})", + error.display_chain_with_msg("Failed to update Wintun interface"), + family, + ); + } + } + } + } + pub fn delete(self, force_close_sessions: bool) -> io::Result<RebootRequired> { unsafe { self.dll_handle diff --git a/talpid-core/src/tunnel/windows.rs b/talpid-core/src/tunnel/windows.rs index 53fac1bca4..bf56b5b168 100644 --- a/talpid-core/src/tunnel/windows.rs +++ b/talpid-core/src/tunnel/windows.rs @@ -8,8 +8,8 @@ use winapi::shared::{ ifdef::NET_LUID, netioapi::{ CancelMibChangeNotify2, ConvertInterfaceAliasToLuid, FreeMibTable, GetIpInterfaceEntry, - GetUnicastIpAddressTable, MibAddInstance, NotifyIpInterfaceChange, MIB_IPINTERFACE_ROW, - MIB_UNICASTIPADDRESS_ROW, MIB_UNICASTIPADDRESS_TABLE, + GetUnicastIpAddressTable, MibAddInstance, NotifyIpInterfaceChange, SetIpInterfaceEntry, + MIB_IPINTERFACE_ROW, MIB_UNICASTIPADDRESS_ROW, MIB_UNICASTIPADDRESS_TABLE, }, ntdef::FALSE, winerror::{ERROR_NOT_FOUND, NO_ERROR}, @@ -77,7 +77,7 @@ pub fn get_ip_interface_entry(family: u16, luid: &NET_LUID) -> io::Result<MIB_IP row.Family = family; row.InterfaceLuid = *luid; - let result = unsafe { GetIpInterfaceEntry(&mut row as *mut _) }; + let result = unsafe { GetIpInterfaceEntry(&mut row) }; if result == NO_ERROR { Ok(row) } else { @@ -85,6 +85,16 @@ pub fn get_ip_interface_entry(family: u16, luid: &NET_LUID) -> io::Result<MIB_IP } } +/// Set the properties of an IP interface. +pub fn set_ip_interface_entry(row: &MIB_IPINTERFACE_ROW) -> io::Result<()> { + let result = unsafe { SetIpInterfaceEntry(row as *const _ as *mut _) }; + if result == NO_ERROR { + Ok(()) + } else { + Err(io::Error::from_raw_os_error(result as i32)) + } +} + fn ip_interface_entry_exists(family: u16, luid: &NET_LUID) -> io::Result<bool> { match get_ip_interface_entry(family, luid) { Ok(_) => Ok(true), |
