From ee913b937af6999a00148437c54ceb25987dea7b Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Wed, 11 Mar 2026 12:55:09 +0800 Subject: [PATCH] fix --- Tun/Punchnet/Actors/SDLContextActor.swift | 5 +- Tun/Punchnet/Actors/SDLPuncherActor.swift | 71 +++++++++++++---------- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index 37ff6b9..02eae84 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -102,6 +102,9 @@ actor SDLContextActor { public func start() async { self.startMonitor() + // 启动puncher的定期扫描任务 + await self.puncherActor.start() + await self.supervisor.addWorker(name: "quicClient") { SDLLogger.shared.log("[SDLContext] try start quicClient") let quicClient = try await self.startQUICClient() @@ -161,7 +164,7 @@ actor SDLContextActor { await self.handleRegisterSuperNak(nakPacket: registerSuperNak) case .peerInfo(let peerInfo): SDLLogger.shared.log("[SDLContext] peer message: \(peerInfo)") - self.puncherActor.handlePeerInfo(using: self.udpHole, peerInfo: peerInfo) + await self.puncherActor.handlePeerInfo(using: self.udpHole, peerInfo: peerInfo) case .event(let event): await self.handleEvent(event: event) case .policyReponse(let policyResponse): diff --git a/Tun/Punchnet/Actors/SDLPuncherActor.swift b/Tun/Punchnet/Actors/SDLPuncherActor.swift index 6a4f1cb..9c565eb 100644 --- a/Tun/Punchnet/Actors/SDLPuncherActor.swift +++ b/Tun/Punchnet/Actors/SDLPuncherActor.swift @@ -9,13 +9,14 @@ import Foundation import NIOCore actor SDLPuncherActor { - nonisolated private let cooldown: Duration = .seconds(5) + nonisolated private let cooldownInterval: TimeInterval = 5 // dstMac - private var coolingDown: Set = [] + private var coolingDown: [Data: (UInt32, Date)] = [:] private var pktId: UInt32 = 1 // 提交后还没有响应的请求 private var pendingRequests: [UInt32: RegisterRequest] = [:] + private var cleanupTask: Task? struct RegisterRequest { let srcMac: Data @@ -23,23 +24,35 @@ actor SDLPuncherActor { let networkId: UInt32 } + // 启动定时清理任务 + func start() { + self.cleanupTask?.cancel() + + self.cleanupTask = Task { + while !Task.isCancelled { + try? await Task.sleep(for: .seconds(cooldownInterval)) + self.cleanExpiredCoolingDown() + } + } + } + func submitRegisterRequest(quicClient: SDLQUICClient?, request: RegisterRequest) { let dstMac = request.dstMac - guard let quicClient, !coolingDown.contains(dstMac) else { + guard let quicClient, coolingDown[dstMac] == nil else { return } - // 触发一次打洞 - coolingDown.insert(dstMac) - let pktId = self.nextPacketId() - self.tryHole(using: quicClient, pktId: pktId, request: request) + coolingDown[dstMac] = (pktId, Date().addingTimeInterval(cooldownInterval)) + + // 触发一次打洞 + var queryInfo = SDLQueryInfo() + queryInfo.pktID = pktId + queryInfo.dstMac = request.dstMac + self.pendingRequests[pktId] = request - Task { - // 启动冷却期 - try? await Task.sleep(for: cooldown) - self.endCooldown(for: dstMac) - self.removePendingRequest(for: pktId) + if let queryData = try? queryInfo.serializedData() { + quicClient.send(type: .queryInfo, data: queryData) } } @@ -61,25 +74,6 @@ actor SDLPuncherActor { } } - private func endCooldown(for key: Data) { - self.coolingDown.remove(key) - } - - private func removePendingRequest(for pktId: UInt32) { - self.pendingRequests.removeValue(forKey: pktId) - } - - private func tryHole(using quicClient: SDLQUICClient, pktId: UInt32, request: RegisterRequest) { - var queryInfo = SDLQueryInfo() - queryInfo.pktID = pktId - queryInfo.dstMac = request.dstMac - self.pendingRequests[pktId] = request - - if let queryData = try? queryInfo.serializedData() { - quicClient.send(type: .queryInfo, data: queryData) - } - } - private func nextPacketId() -> UInt32 { let pktId = self.pktId self.pktId &+= 1 @@ -89,4 +83,19 @@ actor SDLPuncherActor { return pktId } + private func cleanExpiredCoolingDown() { + let date = Date() + for (key, (pktId, expireAt)) in coolingDown { + if expireAt < date { + self.coolingDown.removeValue(forKey: key) + self.pendingRequests.removeValue(forKey: pktId) + } + } + } + + deinit { + self.cleanupTask?.cancel() + self.cleanupTask = nil + } + }