From d4390f5117f0c574b874a0c9d99fd0239eafe7b6 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 30 Jan 2026 13:39:58 +0800 Subject: [PATCH] fix --- Tun/Punchnet/Actors/SDLPuncherActor.swift | 23 +++++++++++++------ Tun/Punchnet/SDLContext.swift | 21 +++++++++-------- ...wTracerActor.swift => SDLFlowTracer.swift} | 13 +++++++++-- 3 files changed, 38 insertions(+), 19 deletions(-) rename Tun/Punchnet/{SDLFlowTracerActor.swift => SDLFlowTracer.swift} (81%) diff --git a/Tun/Punchnet/Actors/SDLPuncherActor.swift b/Tun/Punchnet/Actors/SDLPuncherActor.swift index d1a91ea..2c32b21 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 udpHole: SDLUDPHole? + private var udpHole: SDLUDPHole private var pktId: UInt32 = 1 // 提交后还没有响应的请求 @@ -23,22 +23,31 @@ actor SDLPuncherActor { private var logger: SDLLogger private var querySocketAddress: SocketAddress + private let(requestStream, requestContinuation) = AsyncStream.makeStream(of: RegisterRequest.self, bufferingPolicy: .unbounded) + struct RegisterRequest { let srcMac: Data let dstMac: Data let networkId: UInt32 } - init(querySocketAddress: SocketAddress, logger: SDLLogger) { + init(udpHole: SDLUDPHole, querySocketAddress: SocketAddress, logger: SDLLogger) { + self.udpHole = udpHole self.querySocketAddress = querySocketAddress self.logger = logger } - func setUDPHoleActor(udpHole: SDLUDPHole?) { - self.udpHole = udpHole + nonisolated func submitRegisterRequest(request: RegisterRequest) { + self.requestContinuation.yield(request) } - func submitRegisterRequest(request: RegisterRequest) { + func startConsuming() async { + for await request in self.requestStream { + self.submitRegisterRequest(request: request) + } + } + + private func handleRegisterRequest(request: RegisterRequest) { let dstMac = request.dstMac guard !coolingDown.contains(dstMac) else { @@ -73,7 +82,7 @@ actor SDLPuncherActor { register.srcMac = request.srcMac register.dstMac = request.dstMac - self.udpHole?.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 +104,7 @@ actor SDLPuncherActor { self.pendingRequests[pktId] = request if let queryData = try? queryInfo.serializedData() { - self.udpHole?.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress) + self.udpHole.send(type: .queryInfo, data: queryData, remoteAddress: self.querySocketAddress) } } } diff --git a/Tun/Punchnet/SDLContext.swift b/Tun/Punchnet/SDLContext.swift index 9e42b52..b98e503 100644 --- a/Tun/Punchnet/SDLContext.swift +++ b/Tun/Punchnet/SDLContext.swift @@ -45,7 +45,7 @@ public class SDLContext { // 依赖的变量 var udpHole: SDLUDPHole? var providerAdapter: SDLTunnelProviderAdapter - var puncherActor: SDLPuncherActor + var puncherActor: SDLPuncherActor? // dns的client对象 var dnsClient: SDLDNSClient? @@ -68,7 +68,7 @@ public class SDLContext { private var noticeClient: SDLNoticeClient? // 流量统计 - private var flowTracer = SDLFlowTracerActor() + private var flowTracer = SDLFlowTracer() private var flowTracerCancel: AnyCancellable? private let logger: SDLLogger @@ -83,7 +83,6 @@ public class SDLContext { self.sessionManager = SessionManager() self.arpServer = ArpServer(known_macs: [:]) self.providerAdapter = SDLTunnelProviderAdapter(provider: provider, logger: logger) - self.puncherActor = SDLPuncherActor(querySocketAddress: config.stunSocketAddress, logger: logger) } public func start() async throws { @@ -160,7 +159,7 @@ public class SDLContext { case .registerSuperNak(let registerSuperNak): await self.handleRegisterSuperNak(nakPacket: registerSuperNak) case .peerInfo(let peerInfo): - await self.puncherActor.handlePeerInfo(peerInfo: peerInfo) + await self.puncherActor?.handlePeerInfo(peerInfo: peerInfo) case .event(let event): try await self.handleEvent(event: event) case .stunProbeReply(let probeReply): @@ -214,8 +213,10 @@ public class SDLContext { } private func handleUDPHoleReady() async throws { - await self.puncherActor.setUDPHoleActor(udpHole: self.udpHole) - + if let udpHole = self.udpHole { + self.puncherActor = SDLPuncherActor(udpHole: udpHole, querySocketAddress: config.stunSocketAddress, logger: logger) + } + await withTaskGroup(of: Void.self) { group in group.addTask { // 开始探测nat的类型 @@ -369,7 +370,7 @@ public class SDLContext { let layerPacket = try LayerPacket(layerData: decyptedData) - await self.flowTracer.inc(num: decyptedData.count, type: .inbound) + self.flowTracer.inc(num: decyptedData.count, type: .inbound) // 处理arp请求 switch layerPacket.type { case .arp: @@ -507,15 +508,15 @@ public class SDLContext { if let session = self.sessionManager.getSession(toAddress: dstMac) { self.logger.log("[SDLContext] send packet by session: \(session)", level: .debug) self.udpHole?.send(type: .data, data: data, remoteAddress: session.natAddress) - await self.flowTracer.inc(num: data.count, type: .p2p) + self.flowTracer.inc(num: data.count, type: .p2p) } else { // 通过super_node进行转发 self.udpHole?.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) // 流量统计 - await self.flowTracer.inc(num: data.count, type: .forward) + self.flowTracer.inc(num: data.count, type: .forward) // 尝试打洞 - await self.puncherActor.submitRegisterRequest(request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId)) + self.puncherActor?.submitRegisterRequest(request: .init(srcMac: networkAddr.mac, dstMac: dstMac, networkId: networkAddr.networkId)) } } } diff --git a/Tun/Punchnet/SDLFlowTracerActor.swift b/Tun/Punchnet/SDLFlowTracer.swift similarity index 81% rename from Tun/Punchnet/SDLFlowTracerActor.swift rename to Tun/Punchnet/SDLFlowTracer.swift index 0b0afbe..bf187dd 100644 --- a/Tun/Punchnet/SDLFlowTracerActor.swift +++ b/Tun/Punchnet/SDLFlowTracer.swift @@ -6,9 +6,10 @@ // import Foundation +import Darwin // 流量统计器 -actor SDLFlowTracerActor { +final class SDLFlowTracer { enum FlowType { case forward case p2p @@ -19,7 +20,14 @@ actor SDLFlowTracerActor { private var p2pFlowBytes: UInt32 = 0 private var inFlowBytes: UInt32 = 0 + private let lock = NSLock() + func inc(num: Int, type: FlowType) { + lock.lock() + defer { + lock.unlock() + } + switch type { case .inbound: self.inFlowBytes += UInt32(num) @@ -31,13 +39,14 @@ actor SDLFlowTracerActor { } func reset() -> (UInt32, UInt32, UInt32) { + lock.lock() defer { self.forwardFlowBytes = 0 self.inFlowBytes = 0 self.p2pFlowBytes = 0 + lock.unlock() } return (forwardFlowBytes, p2pFlowBytes, inFlowBytes) } - }