summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-01-14 14:33:23 +0100
committerDavid Lönnhager <david.l@mullvad.net>2025-01-24 17:35:03 +0100
commit9987218e6d376a321ba6a4aa8da068f91f29c092 (patch)
tree98d66577e6a3106cbc7798e1619887d3a80f4038
parent81fe90fe201497d953fefc26357631ac4fd69d54 (diff)
downloadmullvadvpn-9987218e6d376a321ba6a4aa8da068f91f29c092.tar.xz
mullvadvpn-9987218e6d376a321ba6a4aa8da068f91f29c092.zip
Fix socket rebind on default route changes when using multihop
-rw-r--r--talpid-wireguard/src/wireguard_go/mod.rs33
-rw-r--r--wireguard-go-rs/libwg/libwg_windows.go21
-rw-r--r--wireguard-go-rs/src/lib.rs21
3 files changed, 14 insertions, 61 deletions
diff --git a/talpid-wireguard/src/wireguard_go/mod.rs b/talpid-wireguard/src/wireguard_go/mod.rs
index 6699b7a6ad..df2500c7be 100644
--- a/talpid-wireguard/src/wireguard_go/mod.rs
+++ b/talpid-wireguard/src/wireguard_go/mod.rs
@@ -337,37 +337,14 @@ impl WgGoTunnel {
#[cfg(target_os = "windows")]
fn default_route_changed_callback(
event_type: talpid_routing::EventType<'_>,
- address_family: talpid_windows::net::AddressFamily,
+ _family: talpid_windows::net::AddressFamily,
) {
use talpid_routing::EventType::*;
-
- let iface_idx: u32 = match event_type {
- Updated(default_route) => {
- let iface_luid = default_route.iface;
- match talpid_windows::net::index_from_luid(&iface_luid) {
- Ok(idx) => idx,
- Err(err) => {
- log::error!(
- "Failed to convert interface LUID to interface index: {}",
- err,
- );
- return;
- },
- }
- }
- // if there is no new default route, specify 0 as the interface index
- Removed => 0,
+ match event_type {
+ // if there is no new default route, or if the route was removed, update the bind
+ Updated(_) | Removed => wireguard_go_rs::update_bind(),
// ignore interface updates that don't affect the interface to use
- UpdatedDetails(_) => return,
- };
-
- match address_family {
- talpid_windows::net::AddressFamily::Ipv4 => {
- wireguard_go_rs::rebind_tunnel_socket_v4(iface_idx);
- }
- talpid_windows::net::AddressFamily::Ipv6 => {
- wireguard_go_rs::rebind_tunnel_socket_v6(iface_idx);
- }
+ UpdatedDetails(_) => (),
}
}
diff --git a/wireguard-go-rs/libwg/libwg_windows.go b/wireguard-go-rs/libwg/libwg_windows.go
index fc3d9d18a2..f384b66097 100644
--- a/wireguard-go-rs/libwg/libwg_windows.go
+++ b/wireguard-go-rs/libwg/libwg_windows.go
@@ -118,24 +118,9 @@ func wgTurnOn(cIfaceName *C.char, cIfaceNameOut *C.char, cIfaceNameOutSize C.siz
return C.int32_t(handle)
}
-//export wgRebindTunnelSocket
-func wgRebindTunnelSocket(family uint16, interfaceIndex uint32) {
+//export wgUpdateBind
+func wgUpdateBind() {
tunnels.ForEach(func(tunnel tunnelcontainer.Context) {
- blackhole := (interfaceIndex == 0)
- bind := tunnel.Device.Bind().(conn.BindSocketToInterface)
-
- if family == windows.AF_INET {
- tunnel.Logger.Verbosef("Binding v4 socket to interface %d (blackhole=%v)\n", interfaceIndex, blackhole)
- err := bind.BindSocketToInterface4(interfaceIndex, blackhole)
- if err != nil {
- tunnel.Logger.Verbosef("%s\n", err)
- }
- } else if family == windows.AF_INET6 {
- tunnel.Logger.Verbosef("Binding v6 socket to interface %d (blackhole=%v)\n", interfaceIndex, blackhole)
- err := bind.BindSocketToInterface6(interfaceIndex, blackhole)
- if err != nil {
- tunnel.Logger.Verbosef("%s\n", err)
- }
- }
+ tunnel.Device.BindUpdate()
})
}
diff --git a/wireguard-go-rs/src/lib.rs b/wireguard-go-rs/src/lib.rs
index d2f398536a..722e05c613 100644
--- a/wireguard-go-rs/src/lib.rs
+++ b/wireguard-go-rs/src/lib.rs
@@ -304,20 +304,11 @@ impl Drop for Tunnel {
}
}
-/// Rebind WireGuard IPv4 endpoint sockets to use the given interface
+/// Rebind WireGuard endpoint sockets. When the default interface changes, this needs to be called
+/// so that the UDP socket can be rebound to use the new interface
#[cfg(target_os = "windows")]
-pub fn rebind_tunnel_socket_v4(interface_index: u32) {
- use windows_sys::Win32::Networking::WinSock::AF_INET;
- // SAFETY: Passing an invalid interface is safe
- unsafe { ffi::wgRebindTunnelSocket(AF_INET, interface_index) }
-}
-
-/// Rebind WireGuard IPv6 endpoint sockets to use the given interface
-#[cfg(target_os = "windows")]
-pub fn rebind_tunnel_socket_v6(interface_index: u32) {
- use windows_sys::Win32::Networking::WinSock::AF_INET6;
- // SAFETY: Passing an invalid interface is safe
- unsafe { ffi::wgRebindTunnelSocket(AF_INET6, interface_index) }
+pub fn update_bind() {
+ unsafe { ffi::wgUpdateBind() }
}
fn result_from_code(code: i32) -> Result<(), Error> {
@@ -451,8 +442,8 @@ mod ffi {
#[cfg(target_os = "android")]
pub fn wgGetSocketV6(handle: i32) -> Fd;
- /// Rebind tunnel socket endpoint sockets
+ /// Rebind endpoint sockets
#[cfg(target_os = "windows")]
- pub fn wgRebindTunnelSocket(family: u16, index: u32);
+ pub fn wgUpdateBind();
}
}