diff --git a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift index 04e9637..f5f0296 100644 --- a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift +++ b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift @@ -95,16 +95,18 @@ class PacketTunnelProvider: NEPacketTunnelProvider { networkMonitor = NWPathMonitor() networkMonitor?.pathUpdateHandler = { path in guard handle >= 0 else { return } - if path.status == .satisfied { - let endpointString = packetTunnelSettingsGenerator.endpointUapiConfiguration() - - let endpointGoString = endpointString.withCString { - gostring_t(p: $0, n: endpointString.utf8.count) + wg_log(.debug, message: "Network change detected, re-establishing sockets and IPs: \(path.availableInterfaces)") + let endpointString = packetTunnelSettingsGenerator.endpointUapiConfiguration(currentListenPort: wgGetListenPort(handle)) + let err = endpointString.withCString { + wgSetConfig(handle, gostring_t(p: $0, n: endpointString.utf8.count)) + } + if err == -EADDRINUSE { + let endpointString = packetTunnelSettingsGenerator.endpointUapiConfiguration(currentListenPort: 0) + _ = endpointString.withCString { + wgSetConfig(handle, gostring_t(p: $0, n: endpointString.utf8.count)) + } } - - wg_log(.debug, staticMessage: "Network change detected, calling wgSetConfig") - wgSetConfig(handle, endpointGoString) } } networkMonitor?.start(queue: DispatchQueue(label: "NetworkMonitor")) diff --git a/WireGuard/WireGuardNetworkExtension/PacketTunnelSettingsGenerator.swift b/WireGuard/WireGuardNetworkExtension/PacketTunnelSettingsGenerator.swift index 0eea95a..61e161e 100644 --- a/WireGuard/WireGuardNetworkExtension/PacketTunnelSettingsGenerator.swift +++ b/WireGuard/WireGuardNetworkExtension/PacketTunnelSettingsGenerator.swift @@ -15,8 +15,8 @@ class PacketTunnelSettingsGenerator { self.resolvedEndpoints = resolvedEndpoints } - func endpointUapiConfiguration() -> String { - var wgSettings = "listen_port=\(tunnelConfiguration.interface.listenPort ?? 0)\n" + func endpointUapiConfiguration(currentListenPort: UInt16) -> String { + var wgSettings = "listen_port=\(tunnelConfiguration.interface.listenPort ?? currentListenPort)\n" for (i, peer) in tunnelConfiguration.peers.enumerated() { wgSettings.append("public_key=\(peer.publicKey.hexEncodedString())\n") diff --git a/wireguard-go-bridge/src/api-ios.go b/wireguard-go-bridge/src/api-ios.go index ff7aab2..3d35d1e 100644 --- a/wireguard-go-bridge/src/api-ios.go +++ b/wireguard-go-bridge/src/api-ios.go @@ -128,16 +128,27 @@ func wgTurnOff(tunnelHandle int32) { } //export wgSetConfig -func wgSetConfig(tunnelHandle int32, settings string) { +func wgSetConfig(tunnelHandle int32, settings string) int64 { device, ok := tunnelHandles[tunnelHandle] if !ok { - return + return 0 } bufferedSettings := bufio.NewReadWriter(bufio.NewReader(strings.NewReader(settings)), bufio.NewWriter(ioutil.Discard)) err := ipcSetOperation(device, bufferedSettings) if err != nil { device.log.Error.Println(err) + return err.Code } + return 0 +} + +//export wgGetListenPort +func wgGetListenPort(tunnelHandle int32) uint16 { + device, ok := tunnelHandles[tunnelHandle] + if !ok { + return 0 + } + return device.net.port } //export wgVersion diff --git a/wireguard-go-bridge/wireguard.h b/wireguard-go-bridge/wireguard.h index 54cb928..fec352d 100644 --- a/wireguard-go-bridge/wireguard.h +++ b/wireguard-go-bridge/wireguard.h @@ -14,7 +14,8 @@ typedef void(*logger_fn_t)(int level, const char *msg); extern void wgSetLogger(logger_fn_t logger_fn); extern int wgTurnOn(gostring_t ifname, gostring_t settings, int32_t tun_fd); extern void wgTurnOff(int handle); -extern void wgSetConfig(int handle, gostring_t settings); +extern int64_t wgSetConfig(int handle, gostring_t settings); +extern uint16_t wgGetListenPort(int handle); extern char *wgVersion(); #endif