解决系统的异常退出问题
This commit is contained in:
parent
3283c2ae61
commit
8c8006bc69
37
Tun/Punchnet/Actors/ArpServerActor.swift
Normal file
37
Tun/Punchnet/Actors/ArpServerActor.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// ArpServer.swift
|
||||||
|
// sdlan
|
||||||
|
//
|
||||||
|
// Created by 安礼成 on 2025/7/14.
|
||||||
|
//
|
||||||
|
import Foundation
|
||||||
|
import Darwin
|
||||||
|
|
||||||
|
actor ArpServerActor {
|
||||||
|
private var known_macs: [UInt32:Data] = [:]
|
||||||
|
|
||||||
|
init(known_macs: [UInt32:Data]) {
|
||||||
|
self.known_macs = known_macs
|
||||||
|
}
|
||||||
|
|
||||||
|
func query(ip: UInt32) -> Data? {
|
||||||
|
return self.known_macs[ip]
|
||||||
|
}
|
||||||
|
|
||||||
|
func append(ip: UInt32, mac: Data) {
|
||||||
|
self.known_macs[ip] = mac
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(ip: UInt32) {
|
||||||
|
self.known_macs.removeValue(forKey: ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dropMacs(macs: [Data]) {
|
||||||
|
self.known_macs = self.known_macs.filter { !macs.contains($0.value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
func clear() {
|
||||||
|
self.known_macs = [:]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,51 +0,0 @@
|
|||||||
//
|
|
||||||
// ArpServer.swift
|
|
||||||
// sdlan
|
|
||||||
//
|
|
||||||
// Created by 安礼成 on 2025/7/14.
|
|
||||||
//
|
|
||||||
import Foundation
|
|
||||||
import Darwin
|
|
||||||
|
|
||||||
final class ArpServer {
|
|
||||||
private var known_macs: [UInt32:Data] = [:]
|
|
||||||
private var lock = os_unfair_lock()
|
|
||||||
|
|
||||||
init(known_macs: [UInt32:Data]) {
|
|
||||||
self.known_macs = known_macs
|
|
||||||
}
|
|
||||||
|
|
||||||
func query(ip: UInt32) -> Data? {
|
|
||||||
return withLock {
|
|
||||||
return self.known_macs[ip]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func append(ip: UInt32, mac: Data) {
|
|
||||||
withLock {
|
|
||||||
self.known_macs[ip] = mac
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func remove(ip: UInt32) {
|
|
||||||
withLock {
|
|
||||||
_ = self.known_macs.removeValue(forKey: ip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func clear() {
|
|
||||||
withLock {
|
|
||||||
self.known_macs = [:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func withLock<T>(_ body: () throws -> T) rethrows -> T {
|
|
||||||
os_unfair_lock_lock(&lock)
|
|
||||||
defer{
|
|
||||||
os_unfair_lock_unlock(&lock)
|
|
||||||
}
|
|
||||||
|
|
||||||
return try body()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -25,6 +25,27 @@ public class SDLConfiguration {
|
|||||||
public let maskLen: UInt8
|
public let maskLen: UInt8
|
||||||
public let mac: Data
|
public let mac: Data
|
||||||
public let networkDomain: String
|
public let networkDomain: String
|
||||||
|
|
||||||
|
// ip地址
|
||||||
|
var ipAddress: String {
|
||||||
|
return SDLUtil.int32ToIp(self.ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 掩码
|
||||||
|
var maskAddress: String {
|
||||||
|
let len0 = 32 - maskLen
|
||||||
|
let num: UInt32 = (0xFFFFFFFF >> len0) << len0
|
||||||
|
|
||||||
|
return SDLUtil.int32ToIp(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 网络地址
|
||||||
|
var netAddress: String {
|
||||||
|
let len0 = 32 - maskLen
|
||||||
|
let mask: UInt32 = (0xFFFFFFFF >> len0) << len0
|
||||||
|
|
||||||
|
return SDLUtil.int32ToIp(self.ip & mask)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前的客户端版本
|
// 当前的客户端版本
|
||||||
|
|||||||
@ -35,7 +35,6 @@ actor SDLContextActor {
|
|||||||
private var udpHole: SDLUDPHole?
|
private var udpHole: SDLUDPHole?
|
||||||
private var udpHoleWorkers: [Task<Void, Never>]?
|
private var udpHoleWorkers: [Task<Void, Never>]?
|
||||||
|
|
||||||
nonisolated let providerAdapter: SDLTunnelProviderAdapter
|
|
||||||
// dns的client对象
|
// dns的client对象
|
||||||
private var dnsClient: SDLDNSClient?
|
private var dnsClient: SDLDNSClient?
|
||||||
private var dnsWorker: Task<Void, Never>?
|
private var dnsWorker: Task<Void, Never>?
|
||||||
@ -48,7 +47,7 @@ actor SDLContextActor {
|
|||||||
private var readTask: Task<(), Never>?
|
private var readTask: Task<(), Never>?
|
||||||
|
|
||||||
private var sessionManager: SessionManager
|
private var sessionManager: SessionManager
|
||||||
private var arpServer: ArpServer
|
private var arpServer: ArpServerActor
|
||||||
|
|
||||||
// 网络状态变化的健康
|
// 网络状态变化的健康
|
||||||
private var monitor: SDLNetworkMonitor?
|
private var monitor: SDLNetworkMonitor?
|
||||||
@ -63,14 +62,16 @@ actor SDLContextActor {
|
|||||||
// 处理内部的需要长时间运行的任务
|
// 处理内部的需要长时间运行的任务
|
||||||
private var loopChildWorkers: [Task<Void, Never>] = []
|
private var loopChildWorkers: [Task<Void, Never>] = []
|
||||||
|
|
||||||
|
private let provider: NEPacketTunnelProvider
|
||||||
|
|
||||||
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
|
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher, aesCipher: AESCipher) {
|
||||||
|
self.provider = provider
|
||||||
self.config = config
|
self.config = config
|
||||||
self.rsaCipher = rsaCipher
|
self.rsaCipher = rsaCipher
|
||||||
self.aesCipher = aesCipher
|
self.aesCipher = aesCipher
|
||||||
|
|
||||||
self.sessionManager = SessionManager()
|
self.sessionManager = SessionManager()
|
||||||
self.arpServer = ArpServer(known_macs: [:])
|
self.arpServer = ArpServerActor(known_macs: [:])
|
||||||
self.providerAdapter = SDLTunnelProviderAdapter(provider: provider)
|
|
||||||
|
|
||||||
self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress)
|
self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress)
|
||||||
self.proberActor = SDLNATProberActor(addressArray: config.stunProbeSocketAddressArray)
|
self.proberActor = SDLNATProberActor(addressArray: config.stunProbeSocketAddressArray)
|
||||||
@ -153,7 +154,7 @@ actor SDLContextActor {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
let nePacket = NEPacket(data: packet, protocolFamily: 2)
|
let nePacket = NEPacket(data: packet, protocolFamily: 2)
|
||||||
self.providerAdapter.writePackets(packets: [nePacket])
|
self.provider.packetFlow.writePacketObjects([nePacket])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +189,7 @@ actor SDLContextActor {
|
|||||||
await self.sendStunRequest()
|
await self.sendStunRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLLogger.shared.log("[SDLContext] pingTask cancel")
|
SDLLogger.shared.log("[SDLContext] udp pingTask cancel")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理数据流
|
// 处理数据流
|
||||||
@ -199,6 +200,8 @@ actor SDLContextActor {
|
|||||||
}
|
}
|
||||||
try? await self.handleData(data: data)
|
try? await self.handleData(data: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDLLogger.shared.log("[SDLContext] udp dataTask cancel")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理控制信号
|
// 处理控制信号
|
||||||
@ -225,6 +228,8 @@ actor SDLContextActor {
|
|||||||
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
|
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDLLogger.shared.log("[SDLContext] udp signalTask cancel")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.udpHole = udpHole
|
self.udpHole = udpHole
|
||||||
@ -293,13 +298,12 @@ actor SDLContextActor {
|
|||||||
SDLLogger.shared.log("[SDLContext] get registerSuperAck, aes_key len: \(self.aesKey!.count)", level: .info)
|
SDLLogger.shared.log("[SDLContext] get registerSuperAck, aes_key len: \(self.aesKey!.count)", level: .info)
|
||||||
// 服务器分配的tun网卡信息
|
// 服务器分配的tun网卡信息
|
||||||
do {
|
do {
|
||||||
let ipAddress = try await self.providerAdapter.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClient.Helper.dnsServer)
|
try await self.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClient.Helper.dnsServer)
|
||||||
SDLLogger.shared.log("[SDLContext] setNetworkSettings successed")
|
SDLLogger.shared.log("[SDLContext] setNetworkSettings successed")
|
||||||
self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress))
|
|
||||||
self.startReader()
|
self.startReader()
|
||||||
} catch let err {
|
} catch let err {
|
||||||
SDLLogger.shared.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error)
|
SDLLogger.shared.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error)
|
||||||
exit(-1)
|
self.provider.cancelTunnelWithError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +317,10 @@ actor SDLContextActor {
|
|||||||
case .invalidToken, .nodeDisabled:
|
case .invalidToken, .nodeDisabled:
|
||||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||||
self.noticeClient?.send(data: alertNotice)
|
self.noticeClient?.send(data: alertNotice)
|
||||||
exit(-1)
|
// 报告错误并退出
|
||||||
|
let error = NSError(domain: "com.jihe.punchnet.tun", code: -1)
|
||||||
|
self.provider.cancelTunnelWithError(error)
|
||||||
|
|
||||||
case .noIpAddress, .networkFault, .internalFault:
|
case .noIpAddress, .networkFault, .internalFault:
|
||||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||||
self.noticeClient?.send(data: alertNotice)
|
self.noticeClient?.send(data: alertNotice)
|
||||||
@ -322,12 +329,11 @@ actor SDLContextActor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleEvent(event: SDLEvent) throws {
|
private func handleEvent(event: SDLEvent) async throws {
|
||||||
switch event {
|
switch event {
|
||||||
case .dropMacs(let dropMacsEvent):
|
case .dropMacs(let dropMacsEvent):
|
||||||
// TODO
|
|
||||||
SDLLogger.shared.log("[SDLContext] drop macs", level: .info)
|
SDLLogger.shared.log("[SDLContext] drop macs", level: .info)
|
||||||
()
|
await self.arpServer.dropMacs(macs: dropMacsEvent.macs)
|
||||||
case .natChanged(let natChangedEvent):
|
case .natChanged(let natChangedEvent):
|
||||||
let dstMac = natChangedEvent.mac
|
let dstMac = natChangedEvent.mac
|
||||||
SDLLogger.shared.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)", level: .info)
|
SDLLogger.shared.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)", level: .info)
|
||||||
@ -349,7 +355,10 @@ actor SDLContextActor {
|
|||||||
case .networkShutdown(let shutdownEvent):
|
case .networkShutdown(let shutdownEvent):
|
||||||
let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message)
|
let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message)
|
||||||
self.noticeClient?.send(data: alertNotice)
|
self.noticeClient?.send(data: alertNotice)
|
||||||
exit(-1)
|
|
||||||
|
// 报告错误并退出
|
||||||
|
let error = NSError(domain: "com.jihe.punchnet.tun", code: -2)
|
||||||
|
self.provider.cancelTunnelWithError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +445,7 @@ actor SDLContextActor {
|
|||||||
await self.routeLayerPacket(dstMac: arpPacket.senderMAC, type: .arp, data: response.marshal())
|
await self.routeLayerPacket(dstMac: arpPacket.senderMAC, type: .arp, data: response.marshal())
|
||||||
case .response:
|
case .response:
|
||||||
SDLLogger.shared.log("[SDLContext] get arp response packet", level: .debug)
|
SDLLogger.shared.log("[SDLContext] get arp response packet", level: .debug)
|
||||||
self.arpServer.append(ip: arpPacket.senderIP, mac: arpPacket.senderMAC)
|
await self.arpServer.append(ip: arpPacket.senderIP, mac: arpPacket.senderMAC)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDLLogger.shared.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(networkAddr.ip))", level: .debug)
|
SDLLogger.shared.log("[SDLContext] get invalid arp packet: \(arpPacket), target_ip: \(SDLUtil.int32ToIp(arpPacket.targetIP)), net ip: \(SDLUtil.int32ToIp(networkAddr.ip))", level: .debug)
|
||||||
@ -449,7 +458,7 @@ actor SDLContextActor {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
let packet = NEPacket(data: ipPacket.data, protocolFamily: 2)
|
let packet = NEPacket(data: ipPacket.data, protocolFamily: 2)
|
||||||
self.providerAdapter.writePackets(packets: [packet])
|
self.provider.packetFlow.writePacketObjects([packet])
|
||||||
default:
|
default:
|
||||||
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
|
SDLLogger.shared.log("[SDLContext] get invalid packet", level: .debug)
|
||||||
}
|
}
|
||||||
@ -482,10 +491,11 @@ actor SDLContextActor {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let packets = await self.providerAdapter.readPackets()
|
let (packets, numbers) = await self.provider.packetFlow.readPackets()
|
||||||
let ipPackets = packets.compactMap { IPPacket($0) }
|
for (data, number) in zip(packets, numbers) where number == 2 {
|
||||||
for ipPacket in ipPackets {
|
if let ipPacket = IPPacket(data) {
|
||||||
await self.dealPacket(packet: ipPacket)
|
await self.dealPacket(packet: ipPacket)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -505,12 +515,12 @@ actor SDLContextActor {
|
|||||||
// 本地通讯, 目标地址是本地服务器的ip地址
|
// 本地通讯, 目标地址是本地服务器的ip地址
|
||||||
if dstIp == networkAddr.ip {
|
if dstIp == networkAddr.ip {
|
||||||
let nePacket = NEPacket(data: packet.data, protocolFamily: 2)
|
let nePacket = NEPacket(data: packet.data, protocolFamily: 2)
|
||||||
self.providerAdapter.writePackets(packets: [nePacket])
|
self.provider.packetFlow.writePacketObjects([nePacket])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找arp缓存中是否有目标mac地址
|
// 查找arp缓存中是否有目标mac地址
|
||||||
if let dstMac = self.arpServer.query(ip: dstIp) {
|
if let dstMac = await self.arpServer.query(ip: dstIp) {
|
||||||
await self.routeLayerPacket(dstMac: dstMac, type: .ipv4, data: packet.data)
|
await self.routeLayerPacket(dstMac: dstMac, type: .ipv4, data: packet.data)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -564,6 +574,43 @@ actor SDLContextActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 网络改变时需要重新配置网络信息
|
||||||
|
private func setNetworkSettings(networkAddress: SDLConfiguration.NetworkAddress, dnsServer: String) async throws {
|
||||||
|
let routes: [NEIPv4Route] = [
|
||||||
|
NEIPv4Route(destinationAddress: networkAddress.netAddress, subnetMask: networkAddress.maskAddress),
|
||||||
|
NEIPv4Route(destinationAddress: dnsServer, subnetMask: "255.255.255.255"),
|
||||||
|
]
|
||||||
|
|
||||||
|
// Add code here to start the process of connecting the tunnel.
|
||||||
|
let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8")
|
||||||
|
networkSettings.mtu = 1250
|
||||||
|
|
||||||
|
// 设置网卡的DNS解析
|
||||||
|
let networkDomain = networkAddress.networkDomain
|
||||||
|
let dnsSettings = NEDNSSettings(servers: [dnsServer])
|
||||||
|
dnsSettings.searchDomains = [networkDomain]
|
||||||
|
dnsSettings.matchDomains = [networkDomain]
|
||||||
|
dnsSettings.matchDomainsNoSearch = false
|
||||||
|
networkSettings.dnsSettings = dnsSettings
|
||||||
|
|
||||||
|
let ipv4Settings = NEIPv4Settings(addresses: [networkAddress.ipAddress], subnetMasks: [networkAddress.maskAddress])
|
||||||
|
// 设置路由表
|
||||||
|
//NEIPv4Route.default()
|
||||||
|
ipv4Settings.includedRoutes = routes
|
||||||
|
networkSettings.ipv4Settings = ipv4Settings
|
||||||
|
// 网卡配置设置必须成功
|
||||||
|
try await self.provider.setTunnelNetworkSettings(networkSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始读取数据, 用单独的线程处理packetFlow
|
||||||
|
func readPackets() async -> [Data] {
|
||||||
|
let (packets, numbers) = await self.provider.packetFlow.readPackets()
|
||||||
|
return zip(packets, numbers).compactMap { (data, number) in
|
||||||
|
return number == 2 ? data : nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> {
|
private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> {
|
||||||
return Task.detached {
|
return Task.detached {
|
||||||
while !Task.isCancelled {
|
while !Task.isCancelled {
|
||||||
|
|||||||
@ -1,49 +0,0 @@
|
|||||||
//
|
|
||||||
// SDLIPAddress.swift
|
|
||||||
// Tun
|
|
||||||
//
|
|
||||||
// Created by 安礼成 on 2024/3/4.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
struct SDLNetAddress {
|
|
||||||
let ip: UInt32
|
|
||||||
let maskLen: UInt8
|
|
||||||
|
|
||||||
// ip地址
|
|
||||||
var ipAddress: String {
|
|
||||||
return intToIpAddress(self.ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 掩码
|
|
||||||
var maskAddress: String {
|
|
||||||
let len0 = 32 - maskLen
|
|
||||||
let num: UInt32 = (0xFFFFFFFF >> len0) << len0
|
|
||||||
|
|
||||||
return intToIpAddress(num)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 网络地址
|
|
||||||
var networkAddress: String {
|
|
||||||
let len0 = 32 - maskLen
|
|
||||||
let mask: UInt32 = (0xFFFFFFFF >> len0) << len0
|
|
||||||
|
|
||||||
return intToIpAddress(self.ip & mask)
|
|
||||||
}
|
|
||||||
|
|
||||||
init(ip: UInt32, maskLen: UInt8) {
|
|
||||||
self.ip = ip
|
|
||||||
self.maskLen = maskLen
|
|
||||||
}
|
|
||||||
|
|
||||||
private func intToIpAddress(_ num: UInt32) -> String {
|
|
||||||
let ip0 = (UInt8) (num >> 24 & 0xFF)
|
|
||||||
let ip1 = (UInt8) (num >> 16 & 0xFF)
|
|
||||||
let ip2 = (UInt8) (num >> 8 & 0xFF)
|
|
||||||
let ip3 = (UInt8) (num & 0xFF)
|
|
||||||
|
|
||||||
return "\(ip0).\(ip1).\(ip2).\(ip3)"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
//
|
|
||||||
// SDLContext.swift
|
|
||||||
// Tun
|
|
||||||
//
|
|
||||||
// Created by 安礼成 on 2024/2/29.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import NetworkExtension
|
|
||||||
import NIOCore
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
// 上下文环境变量,全局共享
|
|
||||||
/*
|
|
||||||
1. 处理rsa的加解密逻辑
|
|
||||||
*/
|
|
||||||
|
|
||||||
final class SDLTunnelProviderAdapter {
|
|
||||||
|
|
||||||
// 路由信息
|
|
||||||
struct Route {
|
|
||||||
let dstAddress: String
|
|
||||||
let subnetMask: String
|
|
||||||
|
|
||||||
var debugInfo: String {
|
|
||||||
return "\(dstAddress):\(subnetMask)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let provider: NEPacketTunnelProvider
|
|
||||||
|
|
||||||
public init(provider: NEPacketTunnelProvider) {
|
|
||||||
self.provider = provider
|
|
||||||
}
|
|
||||||
|
|
||||||
func writePackets(packets: [NEPacket]) {
|
|
||||||
//let packet = NEPacket(data: ipPacket.data, protocolFamily: 2)
|
|
||||||
self.provider.packetFlow.writePacketObjects(packets)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 网络改变时需要重新配置网络信息
|
|
||||||
func setNetworkSettings(networkAddress: SDLConfiguration.NetworkAddress, dnsServer: String) async throws -> String {
|
|
||||||
let netAddress = SDLNetAddress(ip: networkAddress.ip, maskLen: networkAddress.maskLen)
|
|
||||||
let routes = [
|
|
||||||
Route(dstAddress: netAddress.networkAddress, subnetMask: netAddress.maskAddress),
|
|
||||||
Route(dstAddress: dnsServer, subnetMask: "255.255.255.255")
|
|
||||||
]
|
|
||||||
|
|
||||||
// Add code here to start the process of connecting the tunnel.
|
|
||||||
let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8")
|
|
||||||
networkSettings.mtu = 1250
|
|
||||||
|
|
||||||
// 设置网卡的DNS解析
|
|
||||||
|
|
||||||
let networkDomain = networkAddress.networkDomain
|
|
||||||
let dnsSettings = NEDNSSettings(servers: [dnsServer])
|
|
||||||
dnsSettings.searchDomains = [networkDomain]
|
|
||||||
dnsSettings.matchDomains = [networkDomain]
|
|
||||||
dnsSettings.matchDomainsNoSearch = false
|
|
||||||
networkSettings.dnsSettings = dnsSettings
|
|
||||||
SDLLogger.shared.log("[SDLTunnelProviderAdapter] Tun started at network ip: \(netAddress.ipAddress), mask: \(netAddress.maskAddress)", level: .info)
|
|
||||||
|
|
||||||
let ipv4Settings = NEIPv4Settings(addresses: [netAddress.ipAddress], subnetMasks: [netAddress.maskAddress])
|
|
||||||
// 设置路由表
|
|
||||||
//NEIPv4Route.default()
|
|
||||||
ipv4Settings.includedRoutes = routes.map { route in
|
|
||||||
NEIPv4Route(destinationAddress: route.dstAddress, subnetMask: route.subnetMask)
|
|
||||||
}
|
|
||||||
networkSettings.ipv4Settings = ipv4Settings
|
|
||||||
// 网卡配置设置必须成功
|
|
||||||
try await self.provider.setTunnelNetworkSettings(networkSettings)
|
|
||||||
|
|
||||||
return netAddress.ipAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
// 开始读取数据, 用单独的线程处理packetFlow
|
|
||||||
func readPackets() async -> [Data] {
|
|
||||||
let (packets, numbers) = await self.provider.packetFlow.readPackets()
|
|
||||||
return zip(packets, numbers).compactMap { (data, number) in
|
|
||||||
return number == 2 ? data : nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -11,9 +11,7 @@ import NIOCore
|
|||||||
struct NoticeMessage {
|
struct NoticeMessage {
|
||||||
enum InboundMessage {
|
enum InboundMessage {
|
||||||
case none
|
case none
|
||||||
case upgradeMessage(prompt: String, address: String)
|
|
||||||
case alertMessage(alert: String)
|
case alertMessage(alert: String)
|
||||||
case ip(ip: String)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static func decodeMessage(buffer: inout ByteBuffer) -> InboundMessage {
|
static func decodeMessage(buffer: inout ByteBuffer) -> InboundMessage {
|
||||||
@ -23,23 +21,10 @@ struct NoticeMessage {
|
|||||||
|
|
||||||
switch type {
|
switch type {
|
||||||
case 0x01:
|
case 0x01:
|
||||||
if let len0 = buffer.readInteger(as: UInt16.self),
|
|
||||||
let prompt = buffer.readString(length: Int(len0)),
|
|
||||||
let len1 = buffer.readInteger(as: UInt16.self),
|
|
||||||
let address = buffer.readString(length: Int(len1)) {
|
|
||||||
return .upgradeMessage(prompt: prompt, address: address)
|
|
||||||
}
|
|
||||||
case 0x02:
|
|
||||||
if let len0 = buffer.readInteger(as: UInt16.self),
|
if let len0 = buffer.readInteger(as: UInt16.self),
|
||||||
let alert = buffer.readString(length: Int(len0)) {
|
let alert = buffer.readString(length: Int(len0)) {
|
||||||
return .alertMessage(alert: alert)
|
return .alertMessage(alert: alert)
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x03:
|
|
||||||
if let len0 = buffer.readInteger(as: UInt16.self),
|
|
||||||
let ipAddress = buffer.readString(length: Int(len0)) {
|
|
||||||
return .ip(ip: ipAddress)
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
@ -47,39 +32,16 @@ struct NoticeMessage {
|
|||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
|
|
||||||
static func upgrade(prompt: String, address: String) -> Data {
|
static func alert(alert: String) -> Data {
|
||||||
var data = Data()
|
var data = Data()
|
||||||
data.append(contentsOf: [0x01])
|
data.append(contentsOf: [0x01])
|
||||||
|
|
||||||
data.append(contentsOf: lenBytes(UInt16(prompt.count)))
|
|
||||||
data.append(prompt.data(using: .utf8)!)
|
|
||||||
|
|
||||||
data.append(contentsOf: lenBytes(UInt16(address.count)))
|
|
||||||
data.append(address.data(using: .utf8)!)
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
static func alert(alert: String) -> Data {
|
|
||||||
var data = Data()
|
|
||||||
data.append(contentsOf: [0x02])
|
|
||||||
|
|
||||||
data.append(contentsOf: lenBytes(UInt16(alert.count)))
|
data.append(contentsOf: lenBytes(UInt16(alert.count)))
|
||||||
data.append(alert.data(using: .utf8)!)
|
data.append(alert.data(using: .utf8)!)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ipAdress(ip: String) -> Data {
|
|
||||||
var data = Data()
|
|
||||||
data.append(contentsOf: [0x03])
|
|
||||||
|
|
||||||
data.append(contentsOf: lenBytes(UInt16(ip.count)))
|
|
||||||
data.append(ip.data(using: .utf8)!)
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func lenBytes(_ value: UInt16) -> [UInt8] {
|
private static func lenBytes(_ value: UInt16) -> [UInt8] {
|
||||||
let byte1 = UInt8((value >> 8) & 0xFF)
|
let byte1 = UInt8((value >> 8) & 0xFF)
|
||||||
let bytes2 = UInt8(value & 0xFF)
|
let bytes2 = UInt8(value & 0xFF)
|
||||||
|
|||||||
@ -222,8 +222,6 @@ struct IndexView: View {
|
|||||||
}
|
}
|
||||||
.alert(isPresented: $showStunAlert) {
|
.alert(isPresented: $showStunAlert) {
|
||||||
switch self.message {
|
switch self.message {
|
||||||
case .upgradeMessage(let prompt, _):
|
|
||||||
Alert(title: Text(prompt))
|
|
||||||
case .alertMessage(let alert):
|
case .alertMessage(let alert):
|
||||||
Alert(title: Text(alert))
|
Alert(title: Text(alert))
|
||||||
default:
|
default:
|
||||||
@ -250,9 +248,6 @@ struct IndexView: View {
|
|||||||
switch message {
|
switch message {
|
||||||
case .none:
|
case .none:
|
||||||
()
|
()
|
||||||
case .ip(let ip):
|
|
||||||
self.showIpAdress = true
|
|
||||||
self.ipAddress = ip
|
|
||||||
default:
|
default:
|
||||||
self.message = message
|
self.message = message
|
||||||
self.showStunAlert = true
|
self.showStunAlert = true
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user