解决ipv6的问题

This commit is contained in:
anlicheng 2026-04-16 20:17:49 +08:00
parent 6de2bfff27
commit 5a5fa155d3
2 changed files with 23 additions and 48 deletions

View File

@ -77,6 +77,9 @@ actor SDLContextActor {
// //
nonisolated private let proberActor: SDLNATProberActor nonisolated private let proberActor: SDLNATProberActor
// ipv6
private var ipv6AssistClient: SDLIPV6AssistClient?
// //
private var readTask: Task<(), Never>? private var readTask: Task<(), Never>?
@ -214,6 +217,9 @@ actor SDLContextActor {
SDLLogger.log("[SDLContext] quic welcome: \(welcome)") SDLLogger.log("[SDLContext] quic welcome: \(welcome)")
// //
await self.startRegisterLoop() await self.startRegisterLoop()
// stun
await self.startStunRequestTask(welcome: welcome)
case .pong: case .pong:
//SDLLogger.shared.log("[SDLContext] quic pong") //SDLLogger.shared.log("[SDLContext] quic pong")
() ()
@ -417,6 +423,9 @@ actor SDLContextActor {
self.sessionToken = nil self.sessionToken = nil
self.dataCipher = nil self.dataCipher = nil
await self.ipv6AssistClient?.stop()
self.ipv6AssistClient = nil
} }
private func publishTunnelEvent(code: Int? = nil, message: String) { private func publishTunnelEvent(code: Int? = nil, message: String) {
@ -441,27 +450,32 @@ actor SDLContextActor {
} }
// MARK: -- StunRequestTask // 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 // welcome使ipv6
// //
self.stunRequestTask = Task.detached { self.stunRequestTask = Task.detached {
let timerStream = SDLAsyncTimerStream() let timerStream = SDLAsyncTimerStream()
timerStream.start(interval: .seconds(5)) timerStream.start(interval: .seconds(8))
for await _ in timerStream.stream { for await _ in timerStream.stream {
if Task.isCancelled { let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3))
break
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") SDLLogger.log("[SDLContext] udp stunRequestTask cancel")
} }
} }
private func sendStunRequest() { private func sendStunRequest(probeReply: SDLV6AssistProbeReply?) {
guard let sessionToken = self.sessionToken else { guard let sessionToken = self.sessionToken else {
return return
} }
@ -474,7 +488,7 @@ actor SDLContextActor {
stunRequest.natType = UInt32(self.natType.rawValue) stunRequest.natType = UInt32(self.natType.rawValue)
stunRequest.sessionToken = sessionToken stunRequest.sessionToken = sessionToken
if let v6Info = self.makeCurrentV6Info() { if let v6Info = probeReply?.v6Info {
stunRequest.v6Info = v6Info stunRequest.v6Info = v6Info
} }
@ -567,20 +581,6 @@ actor SDLContextActor {
self.sendPacket(type: type, data: data, remoteAddress: remoteAddress) 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) { private func sendPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) {
switch remoteAddress { switch remoteAddress {
case .v4: case .v4:

View File

@ -32,20 +32,10 @@ actor SDLIPV6AssistClient {
private var packetId: UInt32 = 1 private var packetId: UInt32 = 1
private var pendingRequests: [UInt32: PendingRequest] = [:] private var pendingRequests: [UInt32: PendingRequest] = [:]
//
private let closeStream: AsyncStream<Void>
private let closeContinuation: AsyncStream<Void>.Continuation
private var didFinishCloseStream = false
init?(assistServerInfo: SDLV6Info) { init?(assistServerInfo: SDLV6Info) {
guard assistServerInfo.port <= UInt32(UInt16.max), let host = SDLUtil.ipv6DataToString(assistServerInfo.v6) else { guard assistServerInfo.port <= UInt32(UInt16.max), let host = SDLUtil.ipv6DataToString(assistServerInfo.v6) else {
return nil 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))) self.assistServerAddress = .hostPort(host: NWEndpoint.Host(host), port: NWEndpoint.Port(integerLiteral: UInt16(assistServerInfo.port)))
} }
@ -83,10 +73,6 @@ actor SDLIPV6AssistClient {
connection.start(queue: .global()) connection.start(queue: .global())
} }
public func waitClose() async {
for await _ in self.closeStream { }
}
/// ///
private static func makeReceiveStream(for connection: NWConnection) -> AsyncStream<Data> { private static func makeReceiveStream(for connection: NWConnection) -> AsyncStream<Data> {
return AsyncStream(bufferingPolicy: .bufferingNewest(256)) { continuation in return AsyncStream(bufferingPolicy: .bufferingNewest(256)) { continuation in
@ -115,7 +101,6 @@ actor SDLIPV6AssistClient {
} }
let pktId = self.nextPacketId() let pktId = self.nextPacketId()
let requestTimeout = self.requestTimeout
var assistProbe = SDLV6AssistProbe() var assistProbe = SDLV6AssistProbe()
assistProbe.pktID = pktId assistProbe.pktID = pktId
let data = try assistProbe.serializedData() let data = try assistProbe.serializedData()
@ -165,7 +150,6 @@ actor SDLIPV6AssistClient {
self.connection?.cancel() self.connection?.cancel()
self.connection = nil self.connection = nil
self.failAllPendingRequests(error: pendingError) self.failAllPendingRequests(error: pendingError)
self.finishCloseStreamIfNeeded()
} }
private func handleConnectionStateUpdate(_ state: NWConnection.State, for connection: NWConnection) { 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 { private func nextPacketId() -> UInt32 {
let packetId = self.packetId let packetId = self.packetId
self.packetId &+= 1 self.packetId &+= 1