diff --git a/WireGuard/Shared/PacketTunnelOptionKey.swift b/WireGuard/Shared/PacketTunnelOptionKey.swift new file mode 100644 index 0000000..7208307 --- /dev/null +++ b/WireGuard/Shared/PacketTunnelOptionKey.swift @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018 WireGuard LLC. All rights reserved. + +import Foundation + +enum PacketTunnelOptionKey: String { + + case interfaceName, wireguardSettings, remoteAddress, dnsServers, mtu, + + // IPv4 settings + ipv4Addresses, ipv4SubnetMasks, + ipv4IncludedRouteAddresses, ipv4IncludedRouteSubnetMasks, + ipv4ExcludedRouteAddresses, ipv4ExcludedRouteSubnetMasks, + + // IPv6 settings + ipv6Addresses, ipv6NetworkPrefixLengths, + ipv6IncludedRouteAddresses, ipv6IncludedRouteNetworkPrefixLengths, + ipv6ExcludedRouteAddresses, ipv6ExcludedRouteNetworkPrefixLengths +} + +extension Dictionary where Key == String { + subscript(key: PacketTunnelOptionKey) -> Value? { + get { + return self[key.rawValue] + } + set(value) { + self[key.rawValue] = value + } + } +} diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj index c7288dd..3c96642 100644 --- a/WireGuard/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj @@ -10,6 +10,9 @@ 6F5D0C1521832391000F85AD /* DNSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1421832391000F85AD /* DNSResolver.swift */; }; 6F5D0C1D218352EF000F85AD /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C1C218352EF000F85AD /* PacketTunnelProvider.swift */; }; 6F5D0C22218352EF000F85AD /* WireGuardNetworkExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 6F5D0C452183BCDA000F85AD /* PacketTunnelOptionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C442183BCDA000F85AD /* PacketTunnelOptionKey.swift */; }; + 6F5D0C462183C0B4000F85AD /* PacketTunnelOptionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C442183BCDA000F85AD /* PacketTunnelOptionKey.swift */; }; + 6F5D0C482183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5D0C472183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift */; }; 6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */; }; 6F628C3F217F3413003482A3 /* DNSServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3E217F3413003482A3 /* DNSServer.swift */; }; 6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */; }; @@ -69,6 +72,8 @@ 6F5D0C1E218352EF000F85AD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6F5D0C1F218352EF000F85AD /* WireGuardNetworkExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WireGuardNetworkExtension.entitlements; sourceTree = ""; }; 6F5D0C3421839E37000F85AD /* WireGuardNetworkExtension-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuardNetworkExtension-Bridging-Header.h"; sourceTree = ""; }; + 6F5D0C442183BCDA000F85AD /* PacketTunnelOptionKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelOptionKey.swift; sourceTree = ""; }; + 6F5D0C472183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelOptionsGenerator.swift; sourceTree = ""; }; 6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelViewModel.swift; sourceTree = ""; }; 6F628C3E217F3413003482A3 /* DNSServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSServer.swift; sourceTree = ""; }; 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelDetailTableViewController.swift; sourceTree = ""; }; @@ -127,6 +132,14 @@ path = WireGuardNetworkExtension; sourceTree = ""; }; + 6F5D0C432183B4A4000F85AD /* Shared */ = { + isa = PBXGroup; + children = ( + 6F5D0C442183BCDA000F85AD /* PacketTunnelOptionKey.swift */, + ); + path = Shared; + sourceTree = ""; + }; 6F6899A32180445A0012E523 /* Crypto */ = { isa = PBXGroup; children = ( @@ -183,6 +196,7 @@ children = ( 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */, 6F5D0C1421832391000F85AD /* DNSResolver.swift */, + 6F5D0C472183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift */, ); path = VPN; sourceTree = ""; @@ -190,6 +204,7 @@ 6FF4AC0B211EC46F002C96EB = { isa = PBXGroup; children = ( + 6F5D0C432183B4A4000F85AD /* Shared */, 6FF4AC16211EC46F002C96EB /* WireGuard */, 6F5D0C1B218352EF000F85AD /* WireGuardNetworkExtension */, 6FF4AC15211EC46F002C96EB /* Products */, @@ -362,6 +377,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6F5D0C462183C0B4000F85AD /* PacketTunnelOptionKey.swift in Sources */, 6F5D0C1D218352EF000F85AD /* PacketTunnelProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -374,8 +390,10 @@ 6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */, 6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */, 6F5D0C1521832391000F85AD /* DNSResolver.swift in Sources */, + 6F5D0C482183C6A3000F85AD /* PacketTunnelOptionsGenerator.swift in Sources */, 6F693A562179E556008551C1 /* Endpoint.swift in Sources */, 6F6899A62180447E0012E523 /* x25519.c in Sources */, + 6F5D0C452183BCDA000F85AD /* PacketTunnelOptionKey.swift in Sources */, 6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */, 6F628C3F217F3413003482A3 /* DNSServer.swift in Sources */, 6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */, diff --git a/WireGuard/WireGuard/VPN/PacketTunnelOptionsGenerator.swift b/WireGuard/WireGuard/VPN/PacketTunnelOptionsGenerator.swift new file mode 100644 index 0000000..e3ecb3c --- /dev/null +++ b/WireGuard/WireGuard/VPN/PacketTunnelOptionsGenerator.swift @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018 WireGuard LLC. All rights reserved. + +import Foundation +import Network + +class PacketTunnelOptionsGenerator { + static func generateOptions(from tc: TunnelConfiguration, + withResolvedEndpoints resolvedEndpoints: [Endpoint?]) -> [String:NSObject] { + var options: [String:NSObject] = [:] + + // Interface name + + options[.interfaceName] = tc.interface.name as NSObject + + // WireGuard settings + + var wgSettings = "" + let privateKey = tc.interface.privateKey.hexEncodedString() + wgSettings.append("private_key=\(privateKey)\n") + if let listenPort = tc.interface.listenPort { + wgSettings.append("listen_port=\(listenPort)\n") + } + if (tc.peers.count > 0) { + wgSettings.append("replace_peers=true\n") + } + assert(tc.peers.count == resolvedEndpoints.count) + for (i, peer) in tc.peers.enumerated() { + wgSettings.append("public_key=\(peer.publicKey.hexEncodedString())\n") + if let preSharedKey = peer.preSharedKey { + wgSettings.append("preshared_key=\(preSharedKey.hexEncodedString())\n") + } + if let endpoint = resolvedEndpoints[i] { + if case .name(_, _) = endpoint.host { assert(false, "Endpoint is not resolved") } + wgSettings.append("endpoint=\(endpoint.stringRepresentation())\n") + } + let persistentKeepAlive = peer.persistentKeepAlive ?? 0 + wgSettings.append("persistent_keepalive_interval=\(persistentKeepAlive)\n") + if (!peer.allowedIPs.isEmpty) { + wgSettings.append("replace_allowed_ips=true\n") + for ip in peer.allowedIPs { + wgSettings.append("allowed_ip=\(ip.stringRepresentation())\n") + } + } + } + + options[.wireguardSettings] = wgSettings as NSObject + + // Remote address + + let remoteAddress: String + if let firstEndpoint = resolvedEndpoints.compactMap({ $0 }).first { + switch (firstEndpoint.host) { + case .ipv4(let address): + remoteAddress = "\(address)" + case .ipv6(let address): + remoteAddress = "\(address)" + default: + fatalError("Endpoint must be resolved") + } + } else { + // We don't have any peer with an endpoint + remoteAddress = "" + } + + options[.remoteAddress] = remoteAddress as NSObject + + // DNS + + options[.dnsServers] = tc.interface.dns.map { $0.stringRepresentation() } as NSObject + + // MTU + + options[.mtu] = NSNumber(value: tc.interface.mtu ?? 0) // 0 implies auto-MTU + + // Addresses from interface addresses + + var ipv4Addresses: [String] = [] + var ipv4SubnetMasks: [String] = [] + + var ipv6Addresses: [String] = [] + var ipv6NetworkPrefixLengths: [NSNumber] = [] + + for addressRange in tc.interface.addresses { + if (addressRange.address is IPv4Address) { + ipv4Addresses.append("\(addressRange.address)") + ipv4SubnetMasks.append(ipv4SubnetMaskString(of: addressRange)) + } else if (addressRange.address is IPv6Address) { + ipv6Addresses.append("\(addressRange.address)") + ipv6NetworkPrefixLengths.append(NSNumber(value: addressRange.networkPrefixLength)) + } + } + + options[.ipv4Addresses] = ipv4Addresses as NSObject + options[.ipv4SubnetMasks] = ipv4SubnetMasks as NSObject + + options[.ipv6Addresses] = ipv6Addresses as NSObject + options[.ipv6NetworkPrefixLengths] = ipv6NetworkPrefixLengths as NSObject + + // Included routes from AllowedIPs + + var ipv4IncludedRouteAddresses: [String] = [] + var ipv4IncludedRouteSubnetMasks: [String] = [] + + var ipv6IncludedRouteAddresses: [String] = [] + var ipv6IncludedRouteNetworkPrefixLengths: [NSNumber] = [] + + for peer in tc.peers { + for addressRange in peer.allowedIPs { + if (addressRange.address is IPv4Address) { + ipv4IncludedRouteAddresses.append("\(addressRange.address)") + ipv4IncludedRouteSubnetMasks.append(ipv4SubnetMaskString(of: addressRange)) + } else if (addressRange.address is IPv6Address) { + ipv6IncludedRouteAddresses.append("\(addressRange.address)") + ipv6IncludedRouteNetworkPrefixLengths.append(NSNumber(value: addressRange.networkPrefixLength)) + } + } + } + + options[.ipv4IncludedRouteAddresses] = ipv4IncludedRouteAddresses as NSObject + options[.ipv4IncludedRouteSubnetMasks] = ipv4IncludedRouteSubnetMasks as NSObject + + options[.ipv6IncludedRouteAddresses] = ipv6IncludedRouteAddresses as NSObject + options[.ipv6IncludedRouteNetworkPrefixLengths] = ipv6IncludedRouteNetworkPrefixLengths as NSObject + + // Excluded routes from endpoints + + var ipv4ExcludedRouteAddresses: [String] = [] + var ipv4ExcludedRouteSubnetMasks: [String] = [] + + var ipv6ExcludedRouteAddresses: [String] = [] + var ipv6ExcludedRouteNetworkPrefixLengths: [NSNumber] = [] + + for endpoint in resolvedEndpoints { + guard let endpoint = endpoint else { continue } + switch (endpoint.host) { + case .ipv4(let address): + ipv4ExcludedRouteAddresses.append("\(address)") + ipv4ExcludedRouteSubnetMasks.append("255.255.255.255") // A single IPv4 address + case .ipv6(let address): + ipv6ExcludedRouteAddresses.append("\(address)") + ipv6ExcludedRouteNetworkPrefixLengths.append(NSNumber(value: UInt8(128))) // A single IPv6 address + default: + fatalError() + } + } + + options[.ipv4ExcludedRouteAddresses] = ipv4ExcludedRouteAddresses as NSObject + options[.ipv4ExcludedRouteSubnetMasks] = ipv4ExcludedRouteSubnetMasks as NSObject + + options[.ipv6ExcludedRouteAddresses] = ipv6ExcludedRouteAddresses as NSObject + options[.ipv6ExcludedRouteNetworkPrefixLengths] = ipv6ExcludedRouteNetworkPrefixLengths as NSObject + + return options + } + + static func ipv4SubnetMaskString(of addressRange: IPAddressRange) -> String { + var n: UInt8 = addressRange.networkPrefixLength + assert(n <= 32) + var components: [UInt8] = [] + while (n >= 8) { + components.append(255) + n = n - 8 + } + if (n > 0) { + components.append(((1 << n) - 1) << (8 - n)) + } + while (components.count < 4) { + components.append(0) + } + assert(components.count == 4) + return components.map { String($0) }.joined(separator: ".") + } +} + +private extension Data { + func hexEncodedString() -> String { + return self.map { String(format: "%02x", $0) }.joined() + } +} diff --git a/WireGuard/WireGuard/VPN/TunnelsManager.swift b/WireGuard/WireGuard/VPN/TunnelsManager.swift index 039862d..b4e8231 100644 --- a/WireGuard/WireGuard/VPN/TunnelsManager.swift +++ b/WireGuard/WireGuard/VPN/TunnelsManager.swift @@ -277,7 +277,9 @@ class TunnelContainer: NSObject { s.startObservingTunnelStatus() let session = (s.tunnelProvider.connection as! NETunnelProviderSession) do { - try session.startTunnel(options: [:]) // TODO: Provide options + let tunnelOptions = PacketTunnelOptionsGenerator.generateOptions( + from: tunnelConfiguration, withResolvedEndpoints: endpoints) + try session.startTunnel(options: tunnelOptions) } catch (let error) { os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)") s.onActive = nil diff --git a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift index 1480abc..c5ad766 100644 --- a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift +++ b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift @@ -6,7 +6,9 @@ import NetworkExtension import os.log enum PacketTunnelProviderError: Error { - case tunnelSetupFailed + case invalidOptions + case couldNotStartWireGuard + case coultNotSetNetworkSettings } /// A packet tunnel provider object. @@ -17,81 +19,100 @@ class PacketTunnelProvider: NEPacketTunnelProvider { private var wgHandle: Int32? private var wgContext: WireGuardContext? - private var config: NETunnelProviderProtocol { - return self.protocolConfiguration as! NETunnelProviderProtocol // swiftlint:disable:this force_cast - } - - private var interfaceName: String { - return config.providerConfiguration![PCKeys.title.rawValue]! as! String // swiftlint:disable:this force_cast - } - - private var settings: String { - return config.providerConfiguration![PCKeys.settings.rawValue]! as! String // swiftlint:disable:this force_cast - } - // MARK: NEPacketTunnelProvider /// Begin the process of establishing the tunnel. - override func startTunnel(options: [String: NSObject]?, completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) { - os_log("Starting tunnel", log: Log.general, type: .info) + override func startTunnel(options: [String: NSObject]?, + completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) { + os_log("Starting tunnel", log: OSLog.default, type: .info) - let validatedEndpoints = (config.providerConfiguration?[PCKeys.endpoints.rawValue] as? String ?? "").commaSeparatedToArray().compactMap { try? Endpoint(endpointString: String($0)) }.compactMap {$0} - let validatedAddresses = (config.providerConfiguration?[PCKeys.addresses.rawValue] as? String ?? "").commaSeparatedToArray().compactMap { try? CIDRAddress(stringRepresentation: String($0)) }.compactMap { $0 } - - guard let firstEndpoint = validatedEndpoints.first else { - startTunnelCompletionHandler(PacketTunnelProviderError.tunnelSetupFailed) + guard let options = options else { + startTunnelCompletionHandler(PacketTunnelProviderError.invalidOptions) return } + guard let interfaceName = options[.interfaceName] as? String, + let wireguardSettings = options[.wireguardSettings] as? String, + let remoteAddress = options[.remoteAddress] as? String, + let dnsServers = options[.dnsServers] as? [String], + let mtu = options[.mtu] as? NSNumber, + + // IPv4 settings + let ipv4Addresses = options[.ipv4Addresses] as? [String], + let ipv4SubnetMasks = options[.ipv4SubnetMasks] as? [String], + let ipv4IncludedRouteAddresses = options[.ipv4IncludedRouteAddresses] as? [String], + let ipv4IncludedRouteSubnetMasks = options[.ipv4IncludedRouteSubnetMasks] as? [String], + let ipv4ExcludedRouteAddresses = options[.ipv4ExcludedRouteAddresses] as? [String], + let ipv4ExcludedRouteSubnetMasks = options[.ipv4ExcludedRouteSubnetMasks] as? [String], + + // IPv6 settings + let ipv6Addresses = options[.ipv6Addresses] as? [String], + let ipv6NetworkPrefixLengths = options[.ipv6NetworkPrefixLengths] as? [NSNumber], + let ipv6IncludedRouteAddresses = options[.ipv6IncludedRouteAddresses] as? [String], + let ipv6IncludedRouteNetworkPrefixLengths = options[.ipv6IncludedRouteNetworkPrefixLengths] as? [NSNumber], + let ipv6ExcludedRouteAddresses = options[.ipv6ExcludedRouteAddresses] as? [String], + let ipv6ExcludedRouteNetworkPrefixLengths = options[.ipv6ExcludedRouteNetworkPrefixLengths] as? [NSNumber] + + else { + startTunnelCompletionHandler(PacketTunnelProviderError.invalidOptions) + return + } + configureLogger() wgContext = WireGuardContext(packetFlow: self.packetFlow) - let handle = connect(interfaceName: interfaceName, settings: settings) + let handle = connect(interfaceName: interfaceName, settings: wireguardSettings, mtu: mtu.uint16Value) if handle < 0 { - startTunnelCompletionHandler(PacketTunnelProviderError.tunnelSetupFailed) + startTunnelCompletionHandler(PacketTunnelProviderError.couldNotStartWireGuard) return } wgHandle = handle - // We use the first endpoint for the ipAddress - let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: firstEndpoint.ipAddress) - newSettings.tunnelOverheadBytes = 80 + // Network settings + let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: remoteAddress) // IPv4 settings - let validatedIPv4Addresses = validatedAddresses.filter { $0.addressType == .IPv4} - if validatedIPv4Addresses.count > 0 { - let ipv4Settings = NEIPv4Settings(addresses: validatedIPv4Addresses.map { $0.ipAddress }, subnetMasks: validatedIPv4Addresses.map { $0.subnetString }) - ipv4Settings.includedRoutes = [NEIPv4Route.default()] - ipv4Settings.excludedRoutes = validatedEndpoints.filter { $0.addressType == .IPv4}.map { - NEIPv4Route(destinationAddress: $0.ipAddress, subnetMask: "255.255.255.255")} - - newSettings.ipv4Settings = ipv4Settings + let ipv4Settings = NEIPv4Settings(addresses: ipv4Addresses, subnetMasks: ipv4SubnetMasks) + assert(ipv4IncludedRouteAddresses.count == ipv4IncludedRouteSubnetMasks.count) + ipv4Settings.includedRoutes = zip(ipv4IncludedRouteAddresses, ipv4IncludedRouteSubnetMasks).map { + NEIPv4Route(destinationAddress: $0.0, subnetMask: $0.1) } + assert(ipv4ExcludedRouteAddresses.count == ipv4ExcludedRouteSubnetMasks.count) + ipv4Settings.excludedRoutes = zip(ipv4ExcludedRouteAddresses, ipv4ExcludedRouteSubnetMasks).map { + NEIPv4Route(destinationAddress: $0.0, subnetMask: $0.1) + } + networkSettings.ipv4Settings = ipv4Settings // IPv6 settings - let validatedIPv6Addresses = validatedAddresses.filter { $0.addressType == .IPv6} - if validatedIPv6Addresses.count > 0 { - let ipv6Settings = NEIPv6Settings(addresses: validatedIPv6Addresses.map { $0.ipAddress }, networkPrefixLengths: validatedIPv6Addresses.map { NSNumber(value: $0.subnet) }) - ipv6Settings.includedRoutes = [NEIPv6Route.default()] - ipv6Settings.excludedRoutes = validatedEndpoints.filter { $0.addressType == .IPv6 }.map { NEIPv6Route(destinationAddress: $0.ipAddress, networkPrefixLength: 128) } + let ipv6Settings = NEIPv6Settings(addresses: ipv6Addresses, networkPrefixLengths: ipv6NetworkPrefixLengths) + assert(ipv6IncludedRouteAddresses.count == ipv6IncludedRouteNetworkPrefixLengths.count) + ipv6Settings.includedRoutes = zip(ipv6IncludedRouteAddresses, ipv6IncludedRouteNetworkPrefixLengths).map { + NEIPv6Route(destinationAddress: $0.0, networkPrefixLength: $0.1) + } + assert(ipv6ExcludedRouteAddresses.count == ipv6ExcludedRouteNetworkPrefixLengths.count) + ipv6Settings.excludedRoutes = zip(ipv6ExcludedRouteAddresses, ipv6ExcludedRouteNetworkPrefixLengths).map { + NEIPv6Route(destinationAddress: $0.0, networkPrefixLength: $0.1) + } + networkSettings.ipv6Settings = ipv6Settings - newSettings.ipv6Settings = ipv6Settings + // DNS + networkSettings.dnsSettings = NEDNSSettings(servers: dnsServers) + + // MTU + if (mtu == 0) { + // 0 imples automatic MTU, where we set overhead as 95 bytes, + // 80 for WireGuard and the 15 to make sure WireGuard's padding will work. + networkSettings.tunnelOverheadBytes = 95 + } else { + networkSettings.mtu = mtu } - if let dns = config.providerConfiguration?[PCKeys.dns.rawValue] as? String { - newSettings.dnsSettings = NEDNSSettings(servers: dns.commaSeparatedToArray()) - } - - if let mtu = config.providerConfiguration![PCKeys.mtu.rawValue] as? NSNumber, mtu.intValue > 0 { - newSettings.mtu = mtu - } - - setTunnelNetworkSettings(newSettings) { (error) in + setTunnelNetworkSettings(networkSettings) { (error) in if let error = error { - os_log("Error setting network settings: %s", log: Log.general, type: .error, error.localizedDescription) - startTunnelCompletionHandler(PacketTunnelProviderError.tunnelSetupFailed) + os_log("Error setting network settings: %s", log: OSLog.default, type: .error, error.localizedDescription) + startTunnelCompletionHandler(PacketTunnelProviderError.coultNotSetNetworkSettings) } else { startTunnelCompletionHandler(nil /* No errors */) } @@ -100,7 +121,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { /// Begin the process of stopping the tunnel. override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { - os_log("Stopping tunnel", log: Log.general, type: .info) + os_log("Stopping tunnel", log: OSLog.default, type: .info) if let handle = wgHandle { wgTurnOff(handle) } @@ -108,22 +129,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider { completionHandler() } - /// Handle IPC messages from the app. - override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { - let responseData: Data? - - let message = ExtensionMessage(messageData) - - switch message { - case ExtensionMessage.requestVersion: - responseData = (wgVersion().flatMap { String(cString: $0) } ?? "").data(using: .utf8) - default: - responseData = nil - } - - completionHandler?(responseData) - } - private func configureLogger() { wgSetLogger { (level, tagCStr, msgCStr) in let logType: OSLogType @@ -139,14 +144,14 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } let tag = (tagCStr != nil) ? String(cString: tagCStr!) : "" let msg = (msgCStr != nil) ? String(cString: msgCStr!) : "" - os_log("wg log: %{public}s: %{public}s", log: Log.general, type: logType, tag, msg) + os_log("wg log: %{public}s: %{public}s", log: OSLog.default, type: logType, tag, msg) } } - private func connect(interfaceName: String, settings: String) -> Int32 { // swiftlint:disable:this cyclomatic_complexity + private func connect(interfaceName: String, settings: String, mtu: UInt16) -> Int32 { // swiftlint:disable:this cyclomatic_complexity return withStringsAsGoStrings(interfaceName, settings) { (nameGoStr, settingsGoStr) -> Int32 in return withUnsafeMutablePointer(to: &wgContext) { (wgCtxPtr) -> Int32 in - return wgTurnOn(nameGoStr, settingsGoStr, { (wgCtxPtr, buf, len) -> Int in + return wgTurnOn(nameGoStr, settingsGoStr, mtu, { (wgCtxPtr, buf, len) -> Int in autoreleasepool { // read_fn: Read from the TUN interface and pass it on to WireGuard guard let wgCtxPtr = wgCtxPtr else { return 0 }