diff --git a/Tun/Punchnet/Actors/SDLNATProberActor.swift b/Tun/Punchnet/Actors/SDLNATProberActor.swift index 8fe78ac..9ec1d07 100644 --- a/Tun/Punchnet/Actors/SDLNATProberActor.swift +++ b/Tun/Punchnet/Actors/SDLNATProberActor.swift @@ -52,7 +52,7 @@ actor SDLNATProberActor { // MARK: - Dependencies - private let udpHole: SDLUDPHoleActor + private let udpHole: SDLUDPHole private let addressArray: [[SocketAddress]] private let logger: SDLLogger @@ -63,7 +63,7 @@ actor SDLNATProberActor { // MARK: - Init - init(udpHole: SDLUDPHoleActor, addressArray: [[SocketAddress]], logger: SDLLogger) { + init(udpHole: SDLUDPHole, addressArray: [[SocketAddress]], logger: SDLLogger) { self.udpHole = udpHole self.addressArray = addressArray self.logger = logger diff --git a/Tun/Punchnet/Actors/SDLPuncherActor.swift b/Tun/Punchnet/Actors/SDLPuncherActor.swift index e1b1bdb..d1a91ea 100644 --- a/Tun/Punchnet/Actors/SDLPuncherActor.swift +++ b/Tun/Punchnet/Actors/SDLPuncherActor.swift @@ -13,7 +13,7 @@ actor SDLPuncherActor { private var coolingDown: Set = [] private let cooldown: Duration = .seconds(5) - private var udpHoleActor: SDLUDPHoleActor? + private var udpHole: SDLUDPHole? private var pktId: UInt32 = 1 // 提交后还没有响应的请求 @@ -34,8 +34,8 @@ actor SDLPuncherActor { self.logger = logger } - func setUDPHoleActor(udpHoleActor: SDLUDPHoleActor?) { - self.udpHoleActor = udpHoleActor + func setUDPHoleActor(udpHole: SDLUDPHole?) { + self.udpHole = udpHole } func submitRegisterRequest(request: RegisterRequest) { @@ -73,7 +73,7 @@ actor SDLPuncherActor { register.srcMac = request.srcMac register.dstMac = request.dstMac - await self.udpHoleActor?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) + self.udpHole?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) } else { self.logger.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning) } @@ -95,7 +95,7 @@ actor SDLPuncherActor { self.pendingRequests[pktId] = request if let queryData = try? queryInfo.serializedData() { - await self.udpHoleActor?.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress) + self.udpHole?.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress) } } } diff --git a/Tun/Punchnet/Actors/SDLUDPHoleActor.swift b/Tun/Punchnet/Actors/SDLUDPHole.swift similarity index 99% rename from Tun/Punchnet/Actors/SDLUDPHoleActor.swift rename to Tun/Punchnet/Actors/SDLUDPHole.swift index 73a8d8f..c81ad2e 100644 --- a/Tun/Punchnet/Actors/SDLUDPHoleActor.swift +++ b/Tun/Punchnet/Actors/SDLUDPHole.swift @@ -19,7 +19,7 @@ import NIOPosix import SwiftProtobuf // 处理和sn-server服务器之间的通讯 -actor SDLUDPHoleActor { +final class SDLUDPHole { private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) private var channel: Channel? @@ -77,7 +77,7 @@ actor SDLUDPHoleActor { } -extension SDLUDPHoleActor { +extension SDLUDPHole { final class SDLUDPHoleHandler: ChannelInboundHandler { typealias InboundIn = AddressedEnvelope diff --git a/Tun/Punchnet/SDLContext.swift b/Tun/Punchnet/SDLContext.swift index 371e0d7..b8a8717 100644 --- a/Tun/Punchnet/SDLContext.swift +++ b/Tun/Punchnet/SDLContext.swift @@ -43,7 +43,7 @@ public class SDLContext { let rsaCipher: RSACipher // 依赖的变量 - var udpHoleActor: SDLUDPHoleActor? + var udpHole: SDLUDPHole? var providerActor: SDLTunnelProviderActor var puncherActor: SDLPuncherActor // dns的client对象 @@ -88,8 +88,8 @@ public class SDLContext { public func start() async throws { // 启动udp服务器 - self.udpHoleActor = try SDLUDPHoleActor(logger: self.logger) - try await self.udpHoleActor?.start() + self.udpHole = try SDLUDPHole(logger: self.logger) + try self.udpHole?.start() self.logger.log("[SDLContext] udpHole started") // 启动dns服务 @@ -120,10 +120,12 @@ public class SDLContext { } group.addTask { - if let eventStream = self.udpHoleActor?.eventStream { + if let eventStream = self.udpHole?.eventStream { for try await event in eventStream { try Task.checkCancellation() - try? await self.dispatchEvent(event: event) + Task { + try await self.dispatchEvent(event: event) + } } } } @@ -160,35 +162,43 @@ public class SDLContext { } public func stop() async { - self.udpHoleActor = nil + self.udpHole = nil self.noticeClientActor = nil self.readTask?.cancel() } private func handleUDPHoleReady() async throws { - await self.puncherActor.setUDPHoleActor(udpHoleActor: self.udpHoleActor) + await self.puncherActor.setUDPHoleActor(udpHole: self.udpHole) - // 开始探测nat的类型 - if let udpHoleActor = self.udpHoleActor { - self.proberActor = SDLNATProberActor(udpHole: udpHoleActor, addressArray: self.config.stunProbeSocketAddressArray, logger: self.logger) - self.natType = await self.proberActor!.probeNatType() + await withTaskGroup(of: Void.self) { group in + group.addTask { + // 开始探测nat的类型 + if let udpHoleActor = self.udpHole { + self.proberActor = SDLNATProberActor(udpHole: udpHoleActor, addressArray: self.config.stunProbeSocketAddressArray, logger: self.logger) + self.natType = await self.proberActor!.probeNatType() + self.logger.log("[SDLContext] nat_type is: \(self.natType)") + } + } + + group.addTask { + var registerSuper = SDLRegisterSuper() + registerSuper.pktID = 0 + registerSuper.clientID = self.config.clientId + registerSuper.networkID = self.config.networkAddress.networkId + registerSuper.mac = self.config.networkAddress.mac + registerSuper.ip = self.config.networkAddress.ip + registerSuper.maskLen = UInt32(self.config.networkAddress.maskLen) + registerSuper.hostname = self.config.hostname + registerSuper.pubKey = self.rsaCipher.pubKey + registerSuper.accessToken = self.config.accessToken + + if let registerSuperData = try? registerSuper.serializedData() { + self.logger.log("[SDLContext] will send register super") + self.udpHole?.send(type: .registerSuper, data: registerSuperData, remoteAddress: self.config.stunSocketAddress) + } + } } - - var registerSuper = SDLRegisterSuper() - registerSuper.pktID = 0 - registerSuper.clientID = self.config.clientId - registerSuper.networkID = self.config.networkAddress.networkId - registerSuper.mac = self.config.networkAddress.mac - registerSuper.ip = self.config.networkAddress.ip - registerSuper.maskLen = UInt32(self.config.networkAddress.maskLen) - registerSuper.hostname = self.config.hostname - registerSuper.pubKey = self.rsaCipher.pubKey - registerSuper.accessToken = self.config.accessToken - - self.logger.log("will send register super") - - await self.udpHoleActor?.send(type: .registerSuper, data: try registerSuper.serializedData(), remoteAddress: self.config.stunSocketAddress) } private func sendStunRequest() async { @@ -201,11 +211,11 @@ public class SDLContext { if let stunData = try? stunRequest.serializedData() { let remoteAddress = self.config.stunSocketAddress - await self.udpHoleActor?.send(type: .stunRequest, data: stunData, remoteAddress: remoteAddress) + self.udpHole?.send(type: .stunRequest, data: stunData, remoteAddress: remoteAddress) } } - private func dispatchEvent(event: SDLUDPHoleActor.UDPHoleEvent) async throws { + private func dispatchEvent(event: SDLUDPHole.UDPHoleEvent) async throws { switch event { case .ready: try await self.handleUDPHoleReady() @@ -284,7 +294,7 @@ public class SDLContext { register.networkID = self.config.networkAddress.networkId register.srcMac = self.config.networkAddress.mac register.dstMac = sendRegisterEvent.dstMac - await self.udpHoleActor?.send(type: .register, data: try register.serializedData(), remoteAddress: remoteAddress) + self.udpHole?.send(type: .register, data: try register.serializedData(), remoteAddress: remoteAddress) } case .networkShutdown(let shutdownEvent): @@ -306,7 +316,7 @@ public class SDLContext { registerAck.srcMac = networkAddr.mac registerAck.dstMac = register.srcMac - await self.udpHoleActor?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) + self.udpHole?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) // 这里需要建立到来源的会话, 在复杂网络下,通过super-node查询到的nat地址不一定靠谱,需要通过udp包的来源地址作为nat地址 let session = Session(dstMac: register.srcMac, natAddress: remoteAddress) await self.sessionManager.addSession(session: session) @@ -397,8 +407,10 @@ public class SDLContext { self.readTask = Task(priority: .high) { repeat { let packets = await self.providerActor.readPackets() - let ipPackets = packets.compactMap { IPPacket($0) } - await self.batchProcessPackets(batchSize: 20, packets: ipPackets) + Task { + let ipPackets = packets.compactMap { IPPacket($0) } + await self.batchProcessPackets(batchSize: 20, packets: ipPackets) + } } while true } } @@ -469,18 +481,18 @@ public class SDLContext { // 广播地址不要去尝试打洞 if ARPPacket.isBroadcastMac(dstMac) { // 通过super_node进行转发 - await self.udpHoleActor?.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) + self.udpHole?.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) } else { // 通过session发送到对端 if let session = await self.sessionManager.getSession(toAddress: dstMac) { self.logger.log("[SDLContext] send packet by session: \(session)", level: .debug) - await self.udpHoleActor?.send(type: .data, data: data, remoteAddress: session.natAddress) + self.udpHole?.send(type: .data, data: data, remoteAddress: session.natAddress) await self.flowTracer.inc(num: data.count, type: .p2p) } else { // 通过super_node进行转发 - await self.udpHoleActor?.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) + self.udpHole?.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) // 流量统计 await self.flowTracer.inc(num: data.count, type: .forward) // 尝试打洞 @@ -490,7 +502,7 @@ public class SDLContext { } deinit { - self.udpHoleActor = nil + self.udpHole = nil self.dnsClientActor = nil } }