fix SDLUDPHole
This commit is contained in:
parent
358e555666
commit
5b37ac2552
@ -27,6 +27,7 @@ actor SDLNATProberActor {
|
|||||||
// 建立step -> SDLStunProbeReply的映射关系
|
// 建立step -> SDLStunProbeReply的映射关系
|
||||||
var replies: [UInt32: SDLStunProbeReply]
|
var replies: [UInt32: SDLStunProbeReply]
|
||||||
var timeoutTask: Task<Void, Never>?
|
var timeoutTask: Task<Void, Never>?
|
||||||
|
var sendTask: Task<Void, Never>?
|
||||||
var continuation: CheckedContinuation<NatType, Never>
|
var continuation: CheckedContinuation<NatType, Never>
|
||||||
|
|
||||||
private var isFinished: Bool = false
|
private var isFinished: Bool = false
|
||||||
@ -46,6 +47,7 @@ actor SDLNATProberActor {
|
|||||||
self.continuation.resume(returning: type)
|
self.continuation.resume(returning: type)
|
||||||
// 取消定时器
|
// 取消定时器
|
||||||
self.timeoutTask?.cancel()
|
self.timeoutTask?.cancel()
|
||||||
|
self.sendTask?.cancel()
|
||||||
self.isFinished = true
|
self.isFinished = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +70,10 @@ actor SDLNATProberActor {
|
|||||||
// MARK: - Public API
|
// MARK: - Public API
|
||||||
|
|
||||||
func probeNatType(using udpHole: SDLUDPHole) async -> NatType {
|
func probeNatType(using udpHole: SDLUDPHole) async -> NatType {
|
||||||
|
if Task.isCancelled {
|
||||||
|
return .blocked
|
||||||
|
}
|
||||||
|
|
||||||
let cookieId = self.cookieId
|
let cookieId = self.cookieId
|
||||||
self.cookieId &+= 1
|
self.cookieId &+= 1
|
||||||
|
|
||||||
@ -83,7 +89,7 @@ actor SDLNATProberActor {
|
|||||||
continuation: continuation
|
continuation: continuation
|
||||||
)
|
)
|
||||||
self.sessions[cookieId] = session
|
self.sessions[cookieId] = session
|
||||||
Task {
|
session.sendTask = Task {
|
||||||
await self.sendProbe(using: udpHole, cookie: cookieId)
|
await self.sendProbe(using: udpHole, cookie: cookieId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,6 +138,14 @@ actor SDLNATProberActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cancelAll() {
|
||||||
|
let sessions = self.sessions
|
||||||
|
self.sessions.removeAll()
|
||||||
|
sessions.values.forEach { session in
|
||||||
|
session.finished(with: .blocked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 超时事件(由外部 Timer / Task 驱动)
|
/// 超时事件(由外部 Timer / Task 驱动)
|
||||||
private func handleTimeout(cookie: UInt32) async {
|
private func handleTimeout(cookie: UInt32) async {
|
||||||
guard let session = self.sessions[cookie] else {
|
guard let session = self.sessions[cookie] else {
|
||||||
@ -158,9 +172,21 @@ actor SDLNATProberActor {
|
|||||||
// MARK: - Internal helpers
|
// MARK: - Internal helpers
|
||||||
|
|
||||||
private func sendProbe(using udpHole: SDLUDPHole, cookie: UInt32) async {
|
private func sendProbe(using udpHole: SDLUDPHole, cookie: UInt32) async {
|
||||||
|
guard !Task.isCancelled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 1, attr: .none), remoteAddress: addressArray[0][0])
|
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 1, attr: .none), remoteAddress: addressArray[0][0])
|
||||||
|
guard !Task.isCancelled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 2, attr: .none), remoteAddress: addressArray[1][1])
|
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 2, attr: .none), remoteAddress: addressArray[1][1])
|
||||||
|
guard !Task.isCancelled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 3, attr: .peer), remoteAddress: addressArray[0][0])
|
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 3, attr: .peer), remoteAddress: addressArray[0][0])
|
||||||
|
guard !Task.isCancelled else {
|
||||||
|
return
|
||||||
|
}
|
||||||
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 4, attr: .port), remoteAddress: addressArray[0][0])
|
await udpHole.send(type: .stunProbe, data: makeProbePacket(cookieId: cookie, step: 4, attr: .port), remoteAddress: addressArray[0][0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -182,17 +182,32 @@ actor SDLContextActor {
|
|||||||
let udpHole = self.udpHole
|
let udpHole = self.udpHole
|
||||||
self.udpHole = nil
|
self.udpHole = nil
|
||||||
self.udpHoleLocalAddress = nil
|
self.udpHoleLocalAddress = nil
|
||||||
self.udpHoleMonitorTask?.cancel()
|
|
||||||
|
let udpHoleMonitorTask = self.udpHoleMonitorTask
|
||||||
self.udpHoleMonitorTask = nil
|
self.udpHoleMonitorTask = nil
|
||||||
self.natProbeTask?.cancel()
|
let natProbeTask = self.natProbeTask
|
||||||
self.natProbeTask = nil
|
self.natProbeTask = nil
|
||||||
|
|
||||||
|
udpHoleMonitorTask?.cancel()
|
||||||
|
natProbeTask?.cancel()
|
||||||
|
await self.proberActor.cancelAll()
|
||||||
await udpHole?.stop()
|
await udpHole?.stop()
|
||||||
|
if let natProbeTask {
|
||||||
|
await natProbeTask.value
|
||||||
|
}
|
||||||
|
if let udpHoleMonitorTask {
|
||||||
|
await udpHoleMonitorTask.value
|
||||||
|
}
|
||||||
|
|
||||||
let udpHoleV6 = self.udpHoleV6
|
let udpHoleV6 = self.udpHoleV6
|
||||||
self.udpHoleV6 = nil
|
self.udpHoleV6 = nil
|
||||||
self.udpHoleV6MonitorTask?.cancel()
|
let udpHoleV6MonitorTask = self.udpHoleV6MonitorTask
|
||||||
self.udpHoleV6MonitorTask = nil
|
self.udpHoleV6MonitorTask = nil
|
||||||
|
udpHoleV6MonitorTask?.cancel()
|
||||||
udpHoleV6?.stop()
|
udpHoleV6?.stop()
|
||||||
|
if let udpHoleV6MonitorTask {
|
||||||
|
await udpHoleV6MonitorTask.value
|
||||||
|
}
|
||||||
|
|
||||||
let dnsClient = self.dnsClient
|
let dnsClient = self.dnsClient
|
||||||
self.dnsClient = nil
|
self.dnsClient = nil
|
||||||
@ -680,6 +695,9 @@ extension SDLContextActor {
|
|||||||
let proberActor = self.proberActor
|
let proberActor = self.proberActor
|
||||||
self.natProbeTask = Task { [weak self] in
|
self.natProbeTask = Task { [weak self] in
|
||||||
SDLLogger.log("[SDLContext] start probeNatType")
|
SDLLogger.log("[SDLContext] start probeNatType")
|
||||||
|
if Task.isCancelled {
|
||||||
|
return
|
||||||
|
}
|
||||||
let natType = await proberActor.probeNatType(using: udpHole)
|
let natType = await proberActor.probeNatType(using: udpHole)
|
||||||
if Task.isCancelled {
|
if Task.isCancelled {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -172,8 +172,9 @@ private final class SDLUDPHoleHandler: ChannelInboundHandler {
|
|||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
self.finishMessageContinuationIfNeed(throwing: nil)
|
self.finishMessageContinuationIfNeed(throwing: nil)
|
||||||
try? self.channel?.close().wait()
|
let channel = self.channel
|
||||||
self.channel = nil
|
self.channel = nil
|
||||||
|
try? channel?.close().wait()
|
||||||
try? self.group.syncShutdownGracefully()
|
try? self.group.syncShutdownGracefully()
|
||||||
|
|
||||||
let counterActor = self.counterActor
|
let counterActor = self.counterActor
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user