Update network extension

This commit is contained in:
Neil Alexander 2023-06-06 22:08:20 +01:00
parent b4f01781f5
commit d05b3ea031
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
4 changed files with 86 additions and 44 deletions

View file

@ -0,0 +1,31 @@
//
// PacketTunnelProvider+FileDescriptor.h
// YggdrasilNetworkExtension
//
// Created by Neil on 05/06/2023.
//
#ifndef BridgedResources_h
#define BridgedResources_h
#include <stdint.h>
// 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

View file

@ -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
}
}

View file

@ -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[..<n]], withProtocols: [NSNumber](repeating: AF_INET6 as NSNumber, count: 1))
}
}
}
}
func startYggdrasil() -> 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)
}

View file

@ -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"