修改部分状态不一致的问题

This commit is contained in:
anlicheng 2026-04-28 10:22:18 +08:00
parent 3d551a9bcf
commit 7ce880f3dc
3 changed files with 64 additions and 13 deletions

View File

@ -14,7 +14,7 @@ enum TunnelError: Error {
class PacketTunnelProvider: NEPacketTunnelProvider { class PacketTunnelProvider: NEPacketTunnelProvider {
var contextActor: SDLContextActor? var contextActor: SDLContextActor?
private var rootTask: Task<Void, Error>? private var rootTask: Task<Void, Never>?
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
// //
@ -29,17 +29,24 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
// //
let rsaCipher = try! CCRSACipher(keySize: 1024) let rsaCipher = try! CCRSACipher(keySize: 1024)
self.rootTask = Task { self.rootTask = Task {
// host: "192.168.0.101", port: 1265 do {
guard let options, let config = await SDLConfiguration.parse(options: options) else { // host: "192.168.0.101", port: 1265
completionHandler(TunnelError.invalidConfiguration) guard let options, let config = await SDLConfiguration.parse(options: options) else {
return completionHandler(TunnelError.invalidConfiguration)
return
}
let contextActor = SDLContextActor(provider: self, config: config, rsaCipher: rsaCipher)
self.contextActor = contextActor
await contextActor.start()
try await contextActor.waitForReady(timeout: .seconds(30))
completionHandler(nil)
} catch {
await self.contextActor?.stop()
self.contextActor = nil
completionHandler(error)
} }
self.contextActor = SDLContextActor(provider: self, config: config, rsaCipher: rsaCipher)
await self.contextActor?.start()
try await self.contextActor?.waitForReady()
completionHandler(nil)
} }
} }

View File

@ -185,6 +185,22 @@ actor SDLContextActor {
} }
} }
} }
public func waitForReady(timeout: Duration) async throws {
let timeoutTask = Task {
try? await Task.sleep(for: timeout)
if Task.isCancelled {
return
}
await self.handleReadyTimeout()
}
defer {
timeoutTask.cancel()
}
try await self.waitForReady()
}
// ip: 0.0.0.0 // ip: 0.0.0.0
public func updateExitNode(exitNodeIp: String) async throws { public func updateExitNode(exitNodeIp: String) async throws {
@ -417,7 +433,10 @@ actor SDLContextActor {
self.registerTask?.cancel() self.registerTask?.cancel()
self.registerTask = nil self.registerTask = nil
self.stunRequestTask?.cancel()
self.stunRequestTask = nil
self.updatePolicyTask?.cancel() self.updatePolicyTask?.cancel()
self.updatePolicyTask = nil self.updatePolicyTask = nil
@ -451,6 +470,9 @@ actor SDLContextActor {
// MARK: -- StunRequestTask // MARK: -- StunRequestTask
private func startStunRequestTask(welcome: SDLWelcome) async { private func startStunRequestTask(welcome: SDLWelcome) async {
self.stunRequestTask?.cancel()
self.stunRequestTask = nil
await self.ipv6AssistClient?.stop() await self.ipv6AssistClient?.stop()
self.ipv6AssistClient = SDLIPV6AssistClient(assistServerInfo: welcome.ipv6Assist) self.ipv6AssistClient = SDLIPV6AssistClient(assistServerInfo: welcome.ipv6Assist)
await self.ipv6AssistClient?.start() await self.ipv6AssistClient?.start()
@ -462,6 +484,10 @@ actor SDLContextActor {
timerStream.start(interval: .seconds(8)) timerStream.start(interval: .seconds(8))
for await _ in timerStream.stream { for await _ in timerStream.stream {
if Task.isCancelled {
break
}
let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3)) let probeReply = try? await self.ipv6AssistClient?.probe(requestTimeout: .seconds(3))
if let v6Info = probeReply?.v6Info, let v6Address = SDLUtil.ipv6DataToString(v6Info.v6) { if let v6Info = probeReply?.v6Info, let v6Address = SDLUtil.ipv6DataToString(v6Info.v6) {
SDLLogger.log("[SDLContext] probe ipv6 address: \(v6Address)") SDLLogger.log("[SDLContext] probe ipv6 address: \(v6Address)")
@ -644,6 +670,24 @@ actor SDLContextActor {
self.readyState = .ready self.readyState = .ready
self.resumeReadyWaiters(.success(())) self.resumeReadyWaiters(.success(()))
} }
private func handleReadyTimeout() {
switch self.readyState {
case .idle, .starting:
break
case .ready, .failed, .stopped:
return
}
let error = NSError(
domain: "com.jihe.punchnet.tun",
code: -3,
userInfo: [NSLocalizedDescriptionKey: "Tunnel startup timed out"]
)
SDLLogger.log("[SDLContext] wait ready timeout")
self.failReady(error)
self.provider.cancelTunnelWithError(error)
}
private func failReady(_ error: any Error) { private func failReady(_ error: any Error) {
switch self.readyState { switch self.readyState {

View File

@ -62,7 +62,7 @@ final class SDLSuperRegistrationStateMachine {
} }
func handleRetryableNak() { func handleRetryableNak() {
self.state = .failed self.state = .registering
} }
func handleFailure() { func handleFailure() {