Added an (unfinished) NWPathMonitor implementation for reconnecting on network changes

Signed-off-by: Eric Kuck <eric@bluelinelabs.com>
This commit is contained in:
Eric Kuck 2018-12-11 16:12:04 -06:00
parent 63e67a5e13
commit 27265fc222
3 changed files with 42 additions and 1 deletions

3
.gitignore vendored
View File

@ -38,3 +38,6 @@ fastlane/screenshots
fastlane/test_output fastlane/test_output
Preview.html Preview.html
output output
# Wireguard specific
WireGuard/WireGuard/Config/Developer.xcconfig

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// Copyright © 2018 WireGuard LLC. All Rights Reserved. // Copyright © 2018 WireGuard LLC. All Rights Reserved.
import NetworkExtension
import Foundation import Foundation
import Network
import NetworkExtension
import os.log import os.log
enum PacketTunnelProviderError: Error { enum PacketTunnelProviderError: Error {
@ -20,9 +21,15 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
// MARK: Properties // MARK: Properties
private var wgHandle: Int32? private var wgHandle: Int32?
private var networkMonitor: NWPathMonitor?
// MARK: NEPacketTunnelProvider // MARK: NEPacketTunnelProvider
deinit {
networkMonitor?.cancel()
}
/// Begin the process of establishing the tunnel. /// Begin the process of establishing the tunnel.
override func startTunnel(options: [String: NSObject]?, override func startTunnel(options: [String: NSObject]?,
completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) { completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) {
@ -106,10 +113,27 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
startTunnelCompletionHandler(nil /* No errors */) 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. /// Begin the process of stopping the tunnel.
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
networkMonitor?.cancel()
networkMonitor = nil
wg_log(.info, staticMessage: "Stopping tunnel") wg_log(.info, staticMessage: "Stopping tunnel")
if let handle = wgHandle { if let handle = wgHandle {
wgTurnOff(handle) wgTurnOff(handle)

View File

@ -15,6 +15,20 @@ class PacketTunnelSettingsGenerator {
self.resolvedEndpoints = resolvedEndpoints 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 { func generateWireGuardSettings() -> String {
var wgSettings = "" var wgSettings = ""
let privateKey = tunnelConfiguration.interface.privateKey.hexEncodedString() let privateKey = tunnelConfiguration.interface.privateKey.hexEncodedString()