diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-01-14 14:33:23 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-01-24 17:35:03 +0100 |
| commit | 9987218e6d376a321ba6a4aa8da068f91f29c092 (patch) | |
| tree | 98d66577e6a3106cbc7798e1619887d3a80f4038 | |
| parent | 81fe90fe201497d953fefc26357631ac4fd69d54 (diff) | |
| download | mullvadvpn-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.rs | 33 | ||||
| -rw-r--r-- | wireguard-go-rs/libwg/libwg_windows.go | 21 | ||||
| -rw-r--r-- | wireguard-go-rs/src/lib.rs | 21 |
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(); } } |
