NetworkExtension: apparently the extension process is scoped properly anyway
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
813dea6902
commit
0340641c4c
|
@ -9,13 +9,17 @@ import os.log
|
||||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
|
|
||||||
private var handle: Int32?
|
private var handle: Int32?
|
||||||
|
#if os(iOS)
|
||||||
private var networkMonitor: NWPathMonitor?
|
private var networkMonitor: NWPathMonitor?
|
||||||
|
#endif
|
||||||
private var ifname: String?
|
private var ifname: String?
|
||||||
private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator?
|
private var packetTunnelSettingsGenerator: PacketTunnelSettingsGenerator?
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
deinit {
|
deinit {
|
||||||
networkMonitor?.cancel()
|
networkMonitor?.cancel()
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
override func startTunnel(options: [String: NSObject]?, completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) {
|
override func startTunnel(options: [String: NSObject]?, completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) {
|
||||||
let activationAttemptId = options?["activationAttemptId"] as? String
|
let activationAttemptId = options?["activationAttemptId"] as? String
|
||||||
|
@ -51,9 +55,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||||
startTunnelCompletionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
startTunnelCompletionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||||
} else {
|
} else {
|
||||||
|
#if os(iOS)
|
||||||
self.networkMonitor = NWPathMonitor()
|
self.networkMonitor = NWPathMonitor()
|
||||||
self.networkMonitor!.pathUpdateHandler = self.pathUpdate
|
self.networkMonitor!.pathUpdateHandler = self.pathUpdate
|
||||||
self.networkMonitor!.start(queue: DispatchQueue(label: "NetworkMonitor"))
|
self.networkMonitor!.start(queue: DispatchQueue(label: "NetworkMonitor"))
|
||||||
|
#endif
|
||||||
|
|
||||||
let fileDescriptor = (self.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32) ?? -1
|
let fileDescriptor = (self.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32) ?? -1
|
||||||
if fileDescriptor < 0 {
|
if fileDescriptor < 0 {
|
||||||
|
@ -84,8 +90,10 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||||
|
#if os(iOS)
|
||||||
networkMonitor?.cancel()
|
networkMonitor?.cancel()
|
||||||
networkMonitor = nil
|
networkMonitor = nil
|
||||||
|
#endif
|
||||||
|
|
||||||
ErrorNotifier.removeLastErrorFile()
|
ErrorNotifier.removeLastErrorFile()
|
||||||
|
|
||||||
|
@ -140,24 +148,15 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
private func pathUpdate(path: Network.NWPath) {
|
private func pathUpdate(path: Network.NWPath) {
|
||||||
guard let handle = handle else { return }
|
guard let handle = handle else { return }
|
||||||
wg_log(.debug, message: "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)")
|
|
||||||
#if os(iOS)
|
|
||||||
if let packetTunnelSettingsGenerator = packetTunnelSettingsGenerator {
|
if let packetTunnelSettingsGenerator = packetTunnelSettingsGenerator {
|
||||||
_ = packetTunnelSettingsGenerator.endpointUapiConfiguration().withGoString { return wgSetConfig(handle, $0) }
|
_ = packetTunnelSettingsGenerator.endpointUapiConfiguration().withGoString { return wgSetConfig(handle, $0) }
|
||||||
}
|
}
|
||||||
#elseif os(macOS)
|
|
||||||
var interfaces = path.availableInterfaces
|
|
||||||
if let ifname = ifname {
|
|
||||||
interfaces = interfaces.filter { $0.name != ifname }
|
|
||||||
}
|
|
||||||
if let ifscope = interfaces.first?.index {
|
|
||||||
wgBindInterfaceScope(handle, Int32(ifscope))
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
func withGoString<R>(_ call: (gostring_t) -> R) -> R {
|
func withGoString<R>(_ call: (gostring_t) -> R) -> R {
|
||||||
|
|
|
@ -97,16 +97,13 @@ class PacketTunnelSettingsGenerator {
|
||||||
|
|
||||||
let (ipv4Routes, ipv6Routes) = routes()
|
let (ipv4Routes, ipv6Routes) = routes()
|
||||||
let (ipv4IncludedRoutes, ipv6IncludedRoutes) = includedRoutes()
|
let (ipv4IncludedRoutes, ipv6IncludedRoutes) = includedRoutes()
|
||||||
let (ipv4ExcludedRoutes, ipv6ExcludedRoutes) = excludedRoutes()
|
|
||||||
|
|
||||||
let ipv4Settings = NEIPv4Settings(addresses: ipv4Routes.map { $0.destinationAddress }, subnetMasks: ipv4Routes.map { $0.destinationSubnetMask })
|
let ipv4Settings = NEIPv4Settings(addresses: ipv4Routes.map { $0.destinationAddress }, subnetMasks: ipv4Routes.map { $0.destinationSubnetMask })
|
||||||
ipv4Settings.includedRoutes = ipv4IncludedRoutes
|
ipv4Settings.includedRoutes = ipv4IncludedRoutes
|
||||||
ipv4Settings.excludedRoutes = ipv4ExcludedRoutes
|
|
||||||
networkSettings.ipv4Settings = ipv4Settings
|
networkSettings.ipv4Settings = ipv4Settings
|
||||||
|
|
||||||
let ipv6Settings = NEIPv6Settings(addresses: ipv6Routes.map { $0.destinationAddress }, networkPrefixLengths: ipv6Routes.map { $0.destinationNetworkPrefixLength })
|
let ipv6Settings = NEIPv6Settings(addresses: ipv6Routes.map { $0.destinationAddress }, networkPrefixLengths: ipv6Routes.map { $0.destinationNetworkPrefixLength })
|
||||||
ipv6Settings.includedRoutes = ipv6IncludedRoutes
|
ipv6Settings.includedRoutes = ipv6IncludedRoutes
|
||||||
ipv6Settings.excludedRoutes = ipv6ExcludedRoutes
|
|
||||||
networkSettings.ipv6Settings = ipv6Settings
|
networkSettings.ipv6Settings = ipv6Settings
|
||||||
|
|
||||||
return networkSettings
|
return networkSettings
|
||||||
|
@ -156,24 +153,4 @@ class PacketTunnelSettingsGenerator {
|
||||||
}
|
}
|
||||||
return (ipv4IncludedRoutes, ipv6IncludedRoutes)
|
return (ipv4IncludedRoutes, ipv6IncludedRoutes)
|
||||||
}
|
}
|
||||||
private func excludedRoutes() -> ([NEIPv4Route]?, [NEIPv6Route]?) {
|
|
||||||
#if os(macOS)
|
|
||||||
return (nil, nil)
|
|
||||||
#elseif os(iOS)
|
|
||||||
var ipv4ExcludedRoutes = [NEIPv4Route]()
|
|
||||||
var ipv6ExcludedRoutes = [NEIPv6Route]()
|
|
||||||
for endpoint in resolvedEndpoints {
|
|
||||||
guard let host = endpoint?.host else { continue }
|
|
||||||
switch host {
|
|
||||||
case .ipv4(let v4):
|
|
||||||
ipv4ExcludedRoutes.append(NEIPv4Route(destinationAddress: "\(v4)", subnetMask: "255.255.255.255"))
|
|
||||||
case .ipv6(let v6):
|
|
||||||
ipv6ExcludedRoutes.append(NEIPv6Route(destinationAddress: "\(v6)", networkPrefixLength: 128))
|
|
||||||
default:
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (ipv4ExcludedRoutes, ipv6ExcludedRoutes)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,23 +166,6 @@ func wgGetConfig(tunnelHandle int32) *C.char {
|
||||||
return C.CString(settings.String())
|
return C.CString(settings.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
//export wgBindInterfaceScope
|
|
||||||
func wgBindInterfaceScope(tunnelHandle int32, ifscope int32) {
|
|
||||||
device, ok := tunnelHandles[tunnelHandle]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
device.Info.Printf("Binding sockets to interface %d\n", ifscope)
|
|
||||||
err := device.BindSocketToInterface4(uint32(ifscope))
|
|
||||||
if err != nil {
|
|
||||||
device.Error.Printf("Unable to bind v4 socket to interface: %v", err)
|
|
||||||
}
|
|
||||||
err = device.BindSocketToInterface6(uint32(ifscope))
|
|
||||||
if err != nil {
|
|
||||||
device.Error.Printf("Unable to bind v6 socket to interface: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//export wgVersion
|
//export wgVersion
|
||||||
func wgVersion() *C.char {
|
func wgVersion() *C.char {
|
||||||
return versionString
|
return versionString
|
||||||
|
|
|
@ -18,7 +18,6 @@ extern int wgTurnOn(gostring_t settings, int32_t tun_fd);
|
||||||
extern void wgTurnOff(int handle);
|
extern void wgTurnOff(int handle);
|
||||||
extern int64_t wgSetConfig(int handle, gostring_t settings);
|
extern int64_t wgSetConfig(int handle, gostring_t settings);
|
||||||
extern char *wgGetConfig(int handle);
|
extern char *wgGetConfig(int handle);
|
||||||
extern void wgBindInterfaceScope(int handle, int32_t ifscope);
|
|
||||||
extern const char *wgVersion();
|
extern const char *wgVersion();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue