From d05b3ea031eae3ed6af2115e22f77f08bc26db1e Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 6 Jun 2023 22:08:20 +0100 Subject: [PATCH] Update network extension --- .../PacketTunnelProvider+FileDescriptor.h | 31 ++++++++++++ .../PacketTunnelProvider+FileDescriptor.swift | 47 +++++++++++++++++ .../PacketTunnelProvider.swift | 50 +++---------------- ...ggdrasilNetworkExtension-Bridging-Header.h | 2 +- 4 files changed, 86 insertions(+), 44 deletions(-) create mode 100644 Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.h create mode 100644 Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.swift diff --git a/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.h b/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.h new file mode 100644 index 0000000..d9859ca --- /dev/null +++ b/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.h @@ -0,0 +1,31 @@ +// +// PacketTunnelProvider+FileDescriptor.h +// YggdrasilNetworkExtension +// +// Created by Neil on 05/06/2023. +// + +#ifndef BridgedResources_h +#define BridgedResources_h + +#include + +// SPDX-License-Identifier: MIT +// Copyright © 2018-2023 WireGuard LLC. All Rights Reserved. +// Original source location: https://github.com/WireGuard/wireguard-apple/blob/2fec12a6e1f6e3460b6ee483aa00ad29cddadab1/Sources/WireGuardKitC/WireGuardKitC.h + +#define CTLIOCGINFO 0xc0644e03UL +struct ctl_info { + u_int32_t ctl_id; + char ctl_name[96]; +}; +struct sockaddr_ctl { + u_char sc_len; + u_char sc_family; + u_int16_t ss_sysaddr; + u_int32_t sc_id; + u_int32_t sc_unit; + u_int32_t sc_reserved[5]; +}; + +#endif diff --git a/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.swift b/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.swift new file mode 100644 index 0000000..4349cc3 --- /dev/null +++ b/Yggdrasil Network Extension/PacketTunnelProvider+FileDescriptor.swift @@ -0,0 +1,47 @@ +// +// PacketTunnelProvider+FileDescriptor.swift +// YggdrasilNetworkExtension +// +// Created by Neil on 06/06/2023. +// + +import Foundation + +extension PacketTunnelProvider { + + // SPDX-License-Identifier: MIT + // Copyright © 2018-2023 WireGuard LLC. All Rights Reserved. + // Original source location: https://github.com/WireGuard/wireguard-apple/blob/2fec12a6e1f6e3460b6ee483aa00ad29cddadab1/Sources/WireGuardKit/WireGuardAdapter.swift#L60-L90 + internal var tunnelFileDescriptor: Int32? { + var ctlInfo = ctl_info() + withUnsafeMutablePointer(to: &ctlInfo.ctl_name) { + $0.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: $0.pointee)) { + _ = strcpy($0, "com.apple.net.utun_control") + } + } + for fd: Int32 in 0...1024 { + var addr = sockaddr_ctl() + var ret: Int32 = -1 + var len = socklen_t(MemoryLayout.size(ofValue: addr)) + withUnsafeMutablePointer(to: &addr) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { + ret = getpeername(fd, $0, &len) + } + } + if ret != 0 || addr.sc_family != AF_SYSTEM { + continue + } + if ctlInfo.ctl_id == 0 { + ret = ioctl(fd, CTLIOCGINFO, &ctlInfo) + if ret != 0 { + continue + } + } + if addr.sc_id == ctlInfo.ctl_id { + return fd + } + } + return nil + } + +} diff --git a/Yggdrasil Network Extension/PacketTunnelProvider.swift b/Yggdrasil Network Extension/PacketTunnelProvider.swift index dfdb32c..e6d8fd7 100644 --- a/Yggdrasil Network Extension/PacketTunnelProvider.swift +++ b/Yggdrasil Network Extension/PacketTunnelProvider.swift @@ -6,35 +6,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider { var yggdrasil: MobileYggdrasil = MobileYggdrasil() var yggdrasilConfig: ConfigurationProxy? - - private var readThread: Thread? - private var writeThread: Thread? - private let readBuffer = NSMutableData(length: 65535) - private let writeBuffer = Data(count: 65535) - - @objc func readPacketsFromTun() { - self.packetFlow.readPackets { (packets: [Data], protocols: [NSNumber]) in - autoreleasepool { - for packet in packets { - try? self.yggdrasil.sendBuffer(packet, length: packet.count) - } - } - self.readPacketsFromTun() - } - } - - @objc func writePacketsToTun() { - var n: Int = 0 - let readData = Data(bytesNoCopy: readBuffer!.mutableBytes, count: 65535, deallocator: .none) - while true { - autoreleasepool { - try? self.yggdrasil.recvBuffer(readBuffer as Data?, ret0_: &n) - if n > 0 { - self.packetFlow.writePackets([readData[.. Error? { var err: Error? = nil @@ -81,18 +52,13 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } else { NSLog("Yggdrasil tunnel settings set successfully") - self.readThread = Thread(target: self, selector: #selector(self.readPacketsFromTun), object: nil) - if let readThread = self.readThread { - readThread.name = "TUN Packet Reader" - readThread.qualityOfService = .utility - readThread.start() - } - - self.writeThread = Thread(target: self, selector: #selector(self.writePacketsToTun), object: nil) - if let writeThread = self.writeThread { - writeThread.name = "TUN Packet Writer" - writeThread.qualityOfService = .utility - writeThread.start() + if let fd = self.tunnelFileDescriptor { + do { + try self.yggdrasil.takeOverTUN(fd) + } catch { + NSLog("Taking over TUN produced an error: " + error.localizedDescription) + err = error + } } } } @@ -121,8 +87,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { - self.readThread?.cancel() - self.writeThread?.cancel() try? self.yggdrasil.stop() super.stopTunnel(with: reason, completionHandler: completionHandler) } diff --git a/Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h b/Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h index cab69e9..f5c9426 100644 --- a/Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h +++ b/Yggdrasil Network Extension/YggdrasilNetworkExtension-Bridging-Header.h @@ -2,4 +2,4 @@ // Use this file to import your target's public headers that you would like to expose to Swift. // -#import "GCDAsyncSocket.h" +#import "PacketTunnelProvider+FileDescriptor.h"