This commit is contained in:
anlicheng 2026-02-03 23:45:03 +08:00
parent 55ea1cd09d
commit 57e360bee2
5 changed files with 98 additions and 22 deletions

View File

@ -0,0 +1,42 @@
//
// SDLAddressResolverPool.swift
// Tun
//
// Created by on 2026/2/3.
//
import Foundation
import NIOCore
import NIOPosix
actor SDLAddressResolver {
static let shared = SDLAddressResolver(threads: System.coreCount)
private let pool: NIOThreadPool
private var cache: [String: SocketAddress] = [:]
private init(threads: Int = 2) {
self.pool = NIOThreadPool(numberOfThreads: threads)
self.pool.start()
}
func resolve(host: String, port: Int) async throws -> SocketAddress {
let key = "\(host):\(port)"
if let cached = cache[key] {
return cached
}
let address = try await pool.runIfActive {
try SocketAddress.makeAddressResolvingHost(host, port: port)
}
cache[key] = address
return address
}
deinit {
pool.shutdownGracefully { _ in }
}
}

View File

@ -78,18 +78,21 @@ actor SDLContextActor {
self.loopChildWorkers.append(spawnLoop { self.loopChildWorkers.append(spawnLoop {
let noticeClient = try self.startNoticeClient() let noticeClient = try self.startNoticeClient()
self.logger.log("[SDLContext] noticeClient running!!!!")
try await noticeClient.waitClose() try await noticeClient.waitClose()
self.logger.log("[SDLContext] noticeClient closed!!!!") self.logger.log("[SDLContext] noticeClient closed!!!!")
}) })
self.loopChildWorkers.append(spawnLoop { self.loopChildWorkers.append(spawnLoop {
let dnsClient = try await self.startDnsClient() let dnsClient = try await self.startDnsClient()
self.logger.log("[SDLContext] dns running!!!!")
try await dnsClient.waitClose() try await dnsClient.waitClose()
self.logger.log("[SDLContext] dns closed!!!!") self.logger.log("[SDLContext] dns closed!!!!")
}) })
self.loopChildWorkers.append(spawnLoop { self.loopChildWorkers.append(spawnLoop {
let udpHole = try await self.startUDPHole() let udpHole = try await self.startUDPHole()
self.logger.log("[SDLContext] udp running!!!!")
try await udpHole.waitClose() try await udpHole.waitClose()
self.logger.log("[SDLContext] udp closed!!!!") self.logger.log("[SDLContext] udp closed!!!!")
}) })
@ -98,6 +101,8 @@ actor SDLContextActor {
private func startNoticeClient() throws -> SDLNoticeClient { private func startNoticeClient() throws -> SDLNoticeClient {
// noticeClient // noticeClient
let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort, logger: self.logger) let noticeClient = try SDLNoticeClient(noticePort: self.config.noticePort, logger: self.logger)
noticeClient.start()
self.logger.log("[SDLContext] noticeClient started") self.logger.log("[SDLContext] noticeClient started")
self.noticeClient = noticeClient self.noticeClient = noticeClient
@ -114,13 +119,13 @@ actor SDLContextActor {
self.logger.log("[SDLContext] monitor started") self.logger.log("[SDLContext] monitor started")
self.monitor = monitor self.monitor = monitor
self.monitorWorker = Task { self.monitorWorker = Task.detached {
for await event in monitor.eventStream { for await event in monitor.eventStream {
switch event { switch event {
case .changed: case .changed:
// nat // nat
//self.natType = await self.getNatType() //self.natType = await self.getNatType()
self.logger.log("didNetworkPathChanged, nat type is: \(self.natType)", level: .info) self.logger.log("didNetworkPathChanged, nat type is:", level: .info)
case .unreachable: case .unreachable:
self.logger.log("didNetworkPathUnreachable", level: .warning) self.logger.log("didNetworkPathUnreachable", level: .warning)
} }
@ -138,7 +143,7 @@ actor SDLContextActor {
try dnsClient.start() try dnsClient.start()
self.logger.log("[SDLContext] dnsClient started") self.logger.log("[SDLContext] dnsClient started")
self.dnsClient = dnsClient self.dnsClient = dnsClient
self.dnsWorker = Task { self.dnsWorker = Task.detached {
// //
for await packet in dnsClient.packetFlow { for await packet in dnsClient.packetFlow {
if Task.isCancelled { if Task.isCancelled {
@ -184,17 +189,17 @@ actor SDLContextActor {
} }
// //
let dataTask = Task { let dataTask = Task.detached {
for await data in udpHole.dataStream { for await data in udpHole.dataStream {
if Task.isCancelled { if Task.isCancelled {
break break
} }
try? self.handleData(data: data) try? await self.handleData(data: data)
} }
} }
// //
let signalTask = Task { let signalTask = Task.detached {
for await(remoteAddress, signal) in udpHole.signalStream { for await(remoteAddress, signal) in udpHole.signalStream {
if Task.isCancelled { if Task.isCancelled {
break break
@ -204,17 +209,17 @@ actor SDLContextActor {
case .registerSuperAck(let registerSuperAck): case .registerSuperAck(let registerSuperAck):
await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck) await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck)
case .registerSuperNak(let registerSuperNak): case .registerSuperNak(let registerSuperNak):
self.handleRegisterSuperNak(nakPacket: registerSuperNak) await self.handleRegisterSuperNak(nakPacket: registerSuperNak)
case .peerInfo(let peerInfo): case .peerInfo(let peerInfo):
await self.puncherActor?.handlePeerInfo(peerInfo: peerInfo) await self.puncherActor?.handlePeerInfo(peerInfo: peerInfo)
case .event(let event): case .event(let event):
try? self.handleEvent(event: event) try? await self.handleEvent(event: event)
case .stunProbeReply(let probeReply): case .stunProbeReply(let probeReply):
await self.proberActor?.handleProbeReply(reply: probeReply) await self.proberActor?.handleProbeReply(reply: probeReply)
case .register(let register): case .register(let register):
try? self.handleRegister(remoteAddress: remoteAddress, register: register) try? await self.handleRegister(remoteAddress: remoteAddress, register: register)
case .registerAck(let registerAck): case .registerAck(let registerAck):
self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck) await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
} }
} }
} }
@ -305,9 +310,11 @@ actor SDLContextActor {
// tun // tun
do { do {
let ipAddress = try await self.providerAdapter.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClient.Helper.dnsServer) let ipAddress = try await self.providerAdapter.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClient.Helper.dnsServer)
self.logger.log("[SDLContext] setNetworkSettings successed")
self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress)) self.noticeClient?.send(data: NoticeMessage.ipAdress(ip: ipAddress))
self.logger.log("[SDLContext] send ip successed")
self.startReader() self.startReader()
self.logger.log("[SDLContext] reader started")
} catch let err { } catch let err {
self.logger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error) self.logger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)", level: .error)
exit(-1) exit(-1)
@ -464,7 +471,7 @@ actor SDLContextActor {
self.readTask?.cancel() self.readTask?.cancel()
// //
self.readTask = Task(priority: .high) { self.readTask = Task.detached(priority: .high) {
while true { while true {
if Task.isCancelled { if Task.isCancelled {
return return
@ -473,7 +480,7 @@ actor SDLContextActor {
let packets = await self.providerAdapter.readPackets() let packets = await self.providerAdapter.readPackets()
let ipPackets = packets.compactMap { IPPacket($0) } let ipPackets = packets.compactMap { IPPacket($0) }
for ipPacket in ipPackets { for ipPacket in ipPackets {
self.dealPacket(packet: ipPacket) await self.dealPacket(packet: ipPacket)
} }
} }
} }

View File

@ -21,6 +21,9 @@ import NIOPosix
// sn-server // sn-server
final class SDLNoticeClient { final class SDLNoticeClient {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let (writeStream, writeContinuation) = AsyncStream<Data>.makeStream(of: Data.self)
private var task: Task<Void, Never>?
private var channel: Channel private var channel: Channel
private let logger: SDLLogger private let logger: SDLLogger
private let noticePort: Int private let noticePort: Int
@ -40,15 +43,37 @@ final class SDLNoticeClient {
self.logger.log("[SDLNoticeClient] started", level: .debug) self.logger.log("[SDLNoticeClient] started", level: .debug)
} }
// func start() {
func send(data: Data) { let channel = self.channel
if let remoteAddress = try? SocketAddress(ipAddress: "127.0.0.1", port: noticePort) { self.task = Task.detached {
let buf = channel.allocator.buffer(bytes: data) self.logger.log("[SDLNoticeClient] task 11", level: .debug)
let envelope = AddressedEnvelope<ByteBuffer>(remoteAddress: remoteAddress, data: buf) guard let remoteAddress = try? await SDLAddressResolver.shared.resolve(host: "127.0.0.1", port: self.noticePort) else {
self.channel.eventLoop.execute { self.logger.log("[SDLNoticeClient] task 22", level: .debug)
self.channel.writeAndFlush(envelope, promise: nil) return
}
for await data in self.writeStream {
if Task.isCancelled {
self.logger.log("[SDLNoticeClient] task 33", level: .debug)
break
}
self.logger.log("[SDLNoticeClient] task 44", level: .debug)
self.logger.log("[SDLNoticeClient] send packet", level: .debug)
let buf = channel.allocator.buffer(bytes: data)
let envelope = AddressedEnvelope<ByteBuffer>(remoteAddress: remoteAddress, data: buf)
channel.eventLoop.execute {
channel.writeAndFlush(envelope, promise: nil)
}
} }
} }
}
//
func send(data: Data) {
self.writeContinuation.yield(data)
} }
func waitClose() async throws { func waitClose() async throws {
@ -56,6 +81,8 @@ final class SDLNoticeClient {
} }
deinit { deinit {
self.writeContinuation.finish()
self.task?.cancel()
try? self.group.syncShutdownGracefully() try? self.group.syncShutdownGracefully()
} }

View File

@ -60,7 +60,7 @@ final class SDLTunnelProviderAdapter {
dnsSettings.matchDomains = [networkDomain] dnsSettings.matchDomains = [networkDomain]
dnsSettings.matchDomainsNoSearch = false dnsSettings.matchDomainsNoSearch = false
networkSettings.dnsSettings = dnsSettings networkSettings.dnsSettings = dnsSettings
self.logger.log("[SDLContext] Tun started at network ip: \(netAddress.ipAddress), mask: \(netAddress.maskAddress)", level: .info) self.logger.log("[SDLTunnelProviderAdapter] Tun started at network ip: \(netAddress.ipAddress), mask: \(netAddress.maskAddress)", level: .info)
let ipv4Settings = NEIPv4Settings(addresses: [netAddress.ipAddress], subnetMasks: [netAddress.maskAddress]) let ipv4Settings = NEIPv4Settings(addresses: [netAddress.ipAddress], subnetMasks: [netAddress.maskAddress])
// //

View File

@ -133,7 +133,7 @@ final class SDLUDPHole: ChannelInboundHandler {
buffer.writeBytes(data) buffer.writeBytes(data)
let envelope = AddressedEnvelope<ByteBuffer>(remoteAddress: remoteAddress, data: buffer) let envelope = AddressedEnvelope<ByteBuffer>(remoteAddress: remoteAddress, data: buffer)
channel.eventLoop.execute { _ = channel.eventLoop.submit {
channel.writeAndFlush(envelope, promise: nil) channel.writeAndFlush(envelope, promise: nil)
} }
} }