From 5a5fa155d3c7776dc704d77f1929de024dc57336 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Thu, 16 Apr 2026 20:17:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3ipv6=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tun/Punchnet/Actors/SDLContextActor.swift | 46 +++++++++++------------ Tun/Punchnet/SDLIPV6AssistClient.swift | 25 ------------ 2 files changed, 23 insertions(+), 48 deletions(-) diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index 4c49fc0..890f8fd 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -77,6 +77,9 @@ actor SDLContextActor { // 网络探测对象 nonisolated private let proberActor: SDLNATProberActor + // 本地ipv6地址信息探测 + private var ipv6AssistClient: SDLIPV6AssistClient? + // 数据包读取任务 private var readTask: Task<(), Never>? @@ -214,6 +217,9 @@ actor SDLContextActor { SDLLogger.log("[SDLContext] quic welcome: \(welcome)") // 注册 await self.startRegisterLoop() + // 启动stun任务 + await self.startStunRequestTask(welcome: welcome) + case .pong: //SDLLogger.shared.log("[SDLContext] quic pong") () @@ -417,6 +423,9 @@ actor SDLContextActor { self.sessionToken = nil self.dataCipher = nil + + await self.ipv6AssistClient?.stop() + self.ipv6AssistClient = nil } private func publishTunnelEvent(code: Int? = nil, message: String) { @@ -441,27 +450,32 @@ actor SDLContextActor { } // MARK: -- StunRequestTask - private func startStunRequestTask(welcome: SDLWelcome) { + private func startStunRequestTask(welcome: SDLWelcome) async { + await self.ipv6AssistClient?.stop() + self.ipv6AssistClient = SDLIPV6AssistClient(assistServerInfo: welcome.ipv6Assist) + // 通过 welcome信息拿到当前可用使用的ipv6地址 - - // 处理心跳逻辑 self.stunRequestTask = Task.detached { let timerStream = SDLAsyncTimerStream() - timerStream.start(interval: .seconds(5)) + timerStream.start(interval: .seconds(8)) for await _ in timerStream.stream { - if Task.isCancelled { - break + let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3)) + + if let v6Info = probeReply.v6Info { + let v6Address = SDLUtil.ipv6DataToString(v6Info.v6) + SDLLogger.log("[SDLContext] probe ipv6 address: \(v6Address)") } - await self.sendStunRequest() + + await self.sendStunRequest(probeReply: probeReply) } SDLLogger.log("[SDLContext] udp stunRequestTask cancel") } } - private func sendStunRequest() { + private func sendStunRequest(probeReply: SDLV6AssistProbeReply?) { guard let sessionToken = self.sessionToken else { return } @@ -474,7 +488,7 @@ actor SDLContextActor { stunRequest.natType = UInt32(self.natType.rawValue) stunRequest.sessionToken = sessionToken - if let v6Info = self.makeCurrentV6Info() { + if let v6Info = probeReply?.v6Info { stunRequest.v6Info = v6Info } @@ -567,20 +581,6 @@ actor SDLContextActor { self.sendPacket(type: type, data: data, remoteAddress: remoteAddress) } - private func makeCurrentV6Info() -> SDLV6Info? { - guard let port = self.udpHoleV6LocalAddress?.port, - let ip = NetworkInterfaceManager.getPublicIPv6Address(), - let ipData = SDLUtil.ipv6StrToData(ip) else { - return nil - } - - var v6Info = SDLV6Info() - v6Info.port = UInt32(port) - v6Info.v6 = ipData - - return v6Info - } - private func sendPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) { switch remoteAddress { case .v4: diff --git a/Tun/Punchnet/SDLIPV6AssistClient.swift b/Tun/Punchnet/SDLIPV6AssistClient.swift index 1d50cf5..66d7fa9 100644 --- a/Tun/Punchnet/SDLIPV6AssistClient.swift +++ b/Tun/Punchnet/SDLIPV6AssistClient.swift @@ -32,20 +32,10 @@ actor SDLIPV6AssistClient { private var packetId: UInt32 = 1 private var pendingRequests: [UInt32: PendingRequest] = [:] - // 用来处理关闭事件 - private let closeStream: AsyncStream - private let closeContinuation: AsyncStream.Continuation - private var didFinishCloseStream = false - init?(assistServerInfo: SDLV6Info) { guard assistServerInfo.port <= UInt32(UInt16.max), let host = SDLUtil.ipv6DataToString(assistServerInfo.v6) else { return nil } - - let (closeStream, closeContinuation) = AsyncStream.makeStream(of: Void.self, bufferingPolicy: .bufferingNewest(1)) - self.closeStream = closeStream - self.closeContinuation = closeContinuation - self.assistServerAddress = .hostPort(host: NWEndpoint.Host(host), port: NWEndpoint.Port(integerLiteral: UInt16(assistServerInfo.port))) } @@ -83,10 +73,6 @@ actor SDLIPV6AssistClient { connection.start(queue: .global()) } - public func waitClose() async { - for await _ in self.closeStream { } - } - /// 接收数据的递归循环 private static func makeReceiveStream(for connection: NWConnection) -> AsyncStream { return AsyncStream(bufferingPolicy: .bufferingNewest(256)) { continuation in @@ -115,7 +101,6 @@ actor SDLIPV6AssistClient { } let pktId = self.nextPacketId() - let requestTimeout = self.requestTimeout var assistProbe = SDLV6AssistProbe() assistProbe.pktID = pktId let data = try assistProbe.serializedData() @@ -165,7 +150,6 @@ actor SDLIPV6AssistClient { self.connection?.cancel() self.connection = nil self.failAllPendingRequests(error: pendingError) - self.finishCloseStreamIfNeeded() } private func handleConnectionStateUpdate(_ state: NWConnection.State, for connection: NWConnection) { @@ -229,15 +213,6 @@ actor SDLIPV6AssistClient { } } - private func finishCloseStreamIfNeeded() { - guard !self.didFinishCloseStream else { - return - } - - self.didFinishCloseStream = true - self.closeContinuation.finish() - } - private func nextPacketId() -> UInt32 { let packetId = self.packetId self.packetId &+= 1