From 168ba2da8ad9876f8a7602352fa0e7e4c180d325 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 30 May 2019 15:31:09 +0200 Subject: [PATCH] NetworkExtension: bump sockets on path change Signed-off-by: Jason A. Donenfeld --- .../PacketTunnelProvider.swift | 22 ++++++++++--------- wireguard-go-bridge/api-ios.go | 9 ++++++++ wireguard-go-bridge/go.mod | 4 ++-- wireguard-go-bridge/go.sum | 10 +++++++++ wireguard-go-bridge/wireguard.h | 1 + 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift index 46d5c33..0618b19 100644 --- a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift +++ b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift @@ -9,17 +9,14 @@ import os.log class PacketTunnelProvider: NEPacketTunnelProvider { private var handle: Int32? - #if os(iOS) private var networkMonitor: NWPathMonitor? - #endif private var ifname: String? + private var lastSeenInterfaces: [String] = [] private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator? - #if os(iOS) deinit { networkMonitor?.cancel() } - #endif override func startTunnel(options: [String: NSObject]?, completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) { let activationAttemptId = options?["activationAttemptId"] as? String @@ -55,11 +52,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider { errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings) startTunnelCompletionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings) } else { - #if os(iOS) self.networkMonitor = NWPathMonitor() self.networkMonitor!.pathUpdateHandler = self.pathUpdate self.networkMonitor!.start(queue: DispatchQueue(label: "NetworkMonitor")) - #endif let fileDescriptor = (self.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32) ?? -1 if fileDescriptor < 0 { @@ -90,10 +85,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { - #if os(iOS) networkMonitor?.cancel() networkMonitor = nil - #endif ErrorNotifier.removeLastErrorFile() @@ -148,14 +141,23 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } } - #if os(iOS) private func pathUpdate(path: Network.NWPath) { guard let handle = handle else { return } + guard let ifname = ifname else { return } + wg_log(.debug, message: "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)") + guard path.status == .satisfied else { return } + + #if os(iOS) if let packetTunnelSettingsGenerator = packetTunnelSettingsGenerator { _ = packetTunnelSettingsGenerator.endpointUapiConfiguration().withGoString { return wgSetConfig(handle, $0) } } + #endif + let interfaces = path.availableInterfaces.filter { $0.name != ifname }.compactMap { $0.name } + if !interfaces.elementsEqual(lastSeenInterfaces) { + lastSeenInterfaces = interfaces + wgBumpSockets(handle) + } } - #endif } extension String { diff --git a/wireguard-go-bridge/api-ios.go b/wireguard-go-bridge/api-ios.go index dfe4fbd..c98e3d5 100644 --- a/wireguard-go-bridge/api-ios.go +++ b/wireguard-go-bridge/api-ios.go @@ -165,6 +165,15 @@ func wgGetConfig(tunnelHandle int32) *C.char { writer.Flush() return C.CString(settings.String()) } +//export wgBumpSockets +func wgBumpSockets(tunnelHandle int32) { + device, ok := tunnelHandles[tunnelHandle] + if !ok { + return + } + device.BindUpdate() + device.SendKeepalivesToPeersWithCurrentKeypair() +} //export wgVersion func wgVersion() *C.char { diff --git a/wireguard-go-bridge/go.mod b/wireguard-go-bridge/go.mod index 23bc75b..124bddf 100644 --- a/wireguard-go-bridge/go.mod +++ b/wireguard-go-bridge/go.mod @@ -3,6 +3,6 @@ module golang.zx2c4.com/wireguard/ios go 1.12 require ( - golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 - golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265 + golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5 + golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c ) diff --git a/wireguard-go-bridge/go.sum b/wireguard-go-bridge/go.sum index 46c4197..a0ccbea 100644 --- a/wireguard-go-bridge/go.sum +++ b/wireguard-go-bridge/go.sum @@ -2,12 +2,22 @@ github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f h1:R423Cnkcp5JABoeemiGEPlt9tHXFfw5kvc0yqlxRPWo= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998= golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5 h1:f005F/Jl5JLP036x7QIvUVhNTqxvSYwFIiyOh2q12iU= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265 h1:ujM5BaP4MD/2MJZ1n7pmw6IIsyyS7SyPl0fDefnx/2o= golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265/go.mod h1:u0Cl3X+pyWdXaax3S583DQrnGDuTASO0QdlKFrs8r/8= +golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c h1:nUKiRKxUjK8Zghs+JBZZYXo0g51BlXVqkr6mDfm22ow= +golang.zx2c4.com/wireguard v0.0.20190518-0.20190530131616-d9f995209c3c/go.mod h1:8X7vp4RrsvM83bde6vQ94DsL4ZpjUViVUym8aa8zGhs= diff --git a/wireguard-go-bridge/wireguard.h b/wireguard-go-bridge/wireguard.h index 58e688b..e8e451b 100644 --- a/wireguard-go-bridge/wireguard.h +++ b/wireguard-go-bridge/wireguard.h @@ -18,6 +18,7 @@ extern int wgTurnOn(gostring_t settings, int32_t tun_fd); extern void wgTurnOff(int handle); extern int64_t wgSetConfig(int handle, gostring_t settings); extern char *wgGetConfig(int handle); +extern void wgBumpSockets(int handle); extern const char *wgVersion(); #endif