]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
Added an (unfinished) NWPathMonitor implementation for reconnecting on network changes
authorEric Kuck <eric@bluelinelabs.com>
Tue, 11 Dec 2018 22:12:04 +0000 (16:12 -0600)
committerEric Kuck <eric@bluelinelabs.com>
Tue, 11 Dec 2018 22:12:04 +0000 (16:12 -0600)
Signed-off-by: Eric Kuck <eric@bluelinelabs.com>
.gitignore
WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift
WireGuard/WireGuardNetworkExtension/PacketTunnelSettingsGenerator.swift

index 74364af6025a26a9c18cf82053b3e3cd397ac816..d203206225bd3f5db6791c3870ae9bce20496b5f 100644 (file)
@@ -38,3 +38,6 @@ fastlane/screenshots
 fastlane/test_output
 Preview.html
 output
+
+# Wireguard specific
+WireGuard/WireGuard/Config/Developer.xcconfig
index 11d8ebcd9bdf23a740952d0da8385a7596d8d5e9..1a51573ad6bf80a73d36a116e4bb8fe99561793f 100644 (file)
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: MIT
 // Copyright © 2018 WireGuard LLC. All Rights Reserved.
 
-import NetworkExtension
 import Foundation
+import Network
+import NetworkExtension
 import os.log
 
 enum PacketTunnelProviderError: Error {
@@ -20,9 +21,15 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
     // MARK: Properties
 
     private var wgHandle: Int32?
+    
+    private var networkMonitor: NWPathMonitor?
 
     // MARK: NEPacketTunnelProvider
 
+    deinit {
+        networkMonitor?.cancel()
+    }
+    
     /// Begin the process of establishing the tunnel.
     override func startTunnel(options: [String: NSObject]?,
                               completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) {
@@ -106,10 +113,27 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
                 startTunnelCompletionHandler(nil /* No errors */)
             }
         }
+        
+        networkMonitor = NWPathMonitor()
+        networkMonitor?.pathUpdateHandler = { path in
+            if path.status == .satisfied {
+                let endpointString = packetTunnelSettingsGenerator.endpointFromSettings()
+                
+                let endpointGoString = endpointString.withCString {
+                    gostring_t(p: $0, n: endpointString.utf8.count)
+                }
+                
+                wgSetConfig(handle, endpointGoString)
+            }
+        }
+        networkMonitor?.start(queue: DispatchQueue(label: "NetworkMonitor"))
     }
 
     /// Begin the process of stopping the tunnel.
     override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
+        networkMonitor?.cancel()
+        networkMonitor = nil
+        
         wg_log(.info, staticMessage: "Stopping tunnel")
         if let handle = wgHandle {
             wgTurnOff(handle)
index 40071964b65ff38021af9972954e1dc8f032bc8d..906aea911af7bbd078da02cfc574c055ab4beec9 100644 (file)
@@ -15,6 +15,20 @@ class PacketTunnelSettingsGenerator {
         self.resolvedEndpoints = resolvedEndpoints
     }
 
+    func endpointFromSettings() -> String {
+        var wgSettings = "listen_port=\(tunnelConfiguration.interface.listenPort ?? 0)\n"
+
+        for (i, peer) in tunnelConfiguration.peers.enumerated() {
+            wgSettings.append("public_key=\(peer.publicKey.hexEncodedString())\n")
+            if let endpoint = resolvedEndpoints[i] {
+                if case .name(_, _) = endpoint.host { assert(false, "Endpoint is not resolved") }
+                wgSettings.append("endpoint=\(endpoint.stringRepresentation())\n")
+            }
+        }
+        
+        return wgSettings
+    }
+    
     func generateWireGuardSettings() -> String {
         var wgSettings = ""
         let privateKey = tunnelConfiguration.interface.privateKey.hexEncodedString()