不尝试重复注册,失败报错

This commit is contained in:
anlicheng 2026-04-30 17:33:08 +08:00
parent 136c73ccd1
commit 9817e5a5ca
4 changed files with 54 additions and 160 deletions

View File

@ -15,6 +15,8 @@ enum TunnelError: Error {
class PacketTunnelProvider: NEPacketTunnelProvider { class PacketTunnelProvider: NEPacketTunnelProvider {
private var runtimeEnv: SDLRuntimeEnvironment? private var runtimeEnv: SDLRuntimeEnvironment?
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
// //
guard self.runtimeEnv == nil else { guard self.runtimeEnv == nil else {
@ -27,6 +29,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
return return
} }
self.runtimeEnv = SDLRuntimeEnvironment(options: options) self.runtimeEnv = SDLRuntimeEnvironment(options: options)
Task { Task {
do { do {
@ -74,10 +78,26 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
override func wake() { override func wake() {
// monitor
let monitor = SDLPathMonitor()
//
monitor.start()
SDLLogger.log("[SDLContext] monitor started")
// Add code here to wake up. // Add code here to wake up.
Task { Task {
defer {
monitor.stop()
}
//
_ = await monitor.statusStream().first {$0 == .satisfied}
SDLLogger.log("[SDLContext] network is satisfied")
//
try await self.runtimeEnv?.start(provider: self) try await self.runtimeEnv?.start(provider: self)
} }
} }
private func handleAppRequest(message: AppRequest) async throws -> Data? { private func handleAppRequest(message: AppRequest) async throws -> Data? {

View File

@ -84,10 +84,6 @@ actor SDLContextActor {
private let sessionManager = SessionManager() private let sessionManager = SessionManager()
nonisolated private let arpServer: ArpServer nonisolated private let arpServer: ArpServer
//
private var monitor: SDLPathMonitor?
private var monitorWorker: Task<Void, Never>?
// socket // socket
// App Group + Darwin Notification // App Group + Darwin Notification
@ -113,8 +109,6 @@ actor SDLContextActor {
// stunRequest // stunRequest
private var stunRequestTask: Task<Void, Never>? private var stunRequestTask: Task<Void, Never>?
private let superRegistrationStateMachine = SDLSuperRegistrationStateMachine()
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher) { public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher) {
self.provider = provider self.provider = provider
self.config = config self.config = config
@ -144,7 +138,6 @@ actor SDLContextActor {
if resetNotifier { if resetNotifier {
self.prepareTunnelNotifier() self.prepareTunnelNotifier()
} }
self.startMonitor()
// arp // arp
await self.puncherActor.start() await self.puncherActor.start()
@ -268,7 +261,24 @@ actor SDLContextActor {
case .welcome(let welcome): case .welcome(let welcome):
SDLLogger.log("[SDLContext] quic welcome: \(welcome)") SDLLogger.log("[SDLContext] quic welcome: \(welcome)")
// //
self.startRegisterLoop() await self.doRegisterSuper()
//
self.registerTask = Task {
do {
try await Task.sleep(for: .seconds(5))
try Task.checkCancellation()
// Tunnel
self.publishTunnelEvent(message: "校验失败")
// 退
let error = NSError(domain: "com.jihe.punchnet.tun", code: -3)
self.provider.cancelTunnelWithError(error)
} catch {
return
}
}
// stun // stun
await self.startStunRequestTask(welcome: welcome) await self.startStunRequestTask(welcome: welcome)
@ -276,8 +286,14 @@ actor SDLContextActor {
//SDLLogger.shared.log("[SDLContext] quic pong") //SDLLogger.shared.log("[SDLContext] quic pong")
() ()
case .registerSuperAck(let registerSuperAck): case .registerSuperAck(let registerSuperAck):
self.registerTask?.cancel()
self.registerTask = nil
await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck) await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck)
case .registerSuperNak(let registerSuperNak): case .registerSuperNak(let registerSuperNak):
self.registerTask?.cancel()
self.registerTask = nil
self.handleRegisterSuperNak(nakPacket: registerSuperNak) self.handleRegisterSuperNak(nakPacket: registerSuperNak)
case .peerInfo(let peerInfo): case .peerInfo(let peerInfo):
//SDLLogger.shared.log("[SDLContext] peer message: \(peerInfo)") //SDLLogger.shared.log("[SDLContext] peer message: \(peerInfo)")
@ -301,35 +317,6 @@ actor SDLContextActor {
SDLLogger.log("[SDLContext] tunnelAppNotifier ready") SDLLogger.log("[SDLContext] tunnelAppNotifier ready")
} }
private func startMonitor() {
self.monitorWorker?.cancel()
self.monitorWorker = nil
// monitor
let monitor = SDLPathMonitor()
monitor.start()
SDLLogger.log("[SDLContext] monitor started")
self.monitor = monitor
self.monitorWorker = Task {
for await status in monitor.statusStream() {
switch status {
case .satisfied:
SDLLogger.log("[Path] stable satisfied", for: .debug)
// await contextActor.networkPathDidBecomeSatisfied(snapshot)
case .unsatisfied:
SDLLogger.log("[Path] stable unsatisfied", for: .debug)
// await contextActor.networkPathDidBecomeUnsatisfied(snapshot)
case .requiresConnection:
SDLLogger.log("[Path] stable requiresConnection", for: .debug)
@unknown default:
SDLLogger.log("[Path] stable unknown", for: .debug)
}
}
}
}
private func startDnsClient() async { private func startDnsClient() async {
self.dnsWorker?.cancel() self.dnsWorker?.cancel()
self.dnsWorker = nil self.dnsWorker = nil
@ -430,7 +417,6 @@ actor SDLContextActor {
} }
private func stopRuntime() async { private func stopRuntime() async {
self.superRegistrationStateMachine.reset()
await self.supervisor.stop() await self.supervisor.stop()
await self.puncherActor.stop() await self.puncherActor.stop()
@ -463,12 +449,7 @@ actor SDLContextActor {
self.dnsLocalWorker?.cancel() self.dnsLocalWorker?.cancel()
self.dnsLocalWorker = nil self.dnsLocalWorker = nil
self.dnsLocalClient = nil self.dnsLocalClient = nil
self.monitor?.stop()
self.monitorWorker?.cancel()
self.monitorWorker = nil
self.monitor = nil
self.readTask?.cancel() self.readTask?.cancel()
self.readTask = nil self.readTask = nil
@ -706,43 +687,9 @@ extension SDLContextActor {
return .init(networkAddress: self.config.networkAddress) return .init(networkAddress: self.config.networkAddress)
} }
//
private func startRegisterLoop() {
guard self.registerTask == nil,
self.superRegistrationStateMachine.beginLoop() else {
return
}
self.registerTask = Task {
defer {
self.registerTask = nil
}
while !Task.isCancelled {
switch self.superRegistrationStateMachine.makeLoopAction() {
case .sendRegister:
await self.doRegisterSuper()
case .stop:
return
}
try? await Task.sleep(for: .seconds(5))
switch self.superRegistrationStateMachine.makeWaitDecision() {
case .registered:
await self.whenRegistedSuper()
return
case .retry:
SDLLogger.log("[SDLContext] register super failed, retry")
case .stop:
return
}
}
}
}
private func handleRegisterSuperAck(registerSuperAck: SDLRegisterSuperAck) async { private func handleRegisterSuperAck(registerSuperAck: SDLRegisterSuperAck) async {
// rsa // rsa
guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else { guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else {
self.superRegistrationStateMachine.handleFailure()
SDLLogger.log("[SDLContext] registerSuperAck invalid key") SDLLogger.log("[SDLContext] registerSuperAck invalid key")
let error = SDLError.invalidKey let error = SDLError.invalidKey
self.provider.cancelTunnelWithError(error) self.provider.cancelTunnelWithError(error)
@ -759,7 +706,6 @@ extension SDLContextActor {
case "chacha20": case "chacha20":
self.dataCipher = CCChaCha20Cipher(regionId: regionId, keyData: key) self.dataCipher = CCChaCha20Cipher(regionId: regionId, keyData: key)
default: default:
self.superRegistrationStateMachine.handleFailure()
SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)") SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)")
let error = SDLError.unsupportedAlgorithm(algorithm: algorithm) let error = SDLError.unsupportedAlgorithm(algorithm: algorithm)
self.provider.cancelTunnelWithError(error) self.provider.cancelTunnelWithError(error)
@ -771,10 +717,10 @@ extension SDLContextActor {
do { do {
try await self.setNetworkSettings(config: self.config, dnsServer: DNSHelper.dnsServer) try await self.setNetworkSettings(config: self.config, dnsServer: DNSHelper.dnsServer)
SDLLogger.log("[SDLContext] setNetworkSettings successed") SDLLogger.log("[SDLContext] setNetworkSettings successed")
self.superRegistrationStateMachine.handleRegisterSuperAck()
self.startReader() self.startReader()
//
await self.whenRegistedSuper()
} catch let err { } catch let err {
self.superRegistrationStateMachine.handleFailure()
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)") SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)")
self.provider.cancelTunnelWithError(err) self.provider.cancelTunnelWithError(err)
} }
@ -788,18 +734,15 @@ extension SDLContextActor {
switch errorCode { switch errorCode {
case .invalidToken, .nodeDisabled: case .invalidToken, .nodeDisabled:
self.superRegistrationStateMachine.handleFailure()
self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage) self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)
// 退 // 退
let error = NSError(domain: "com.jihe.punchnet.tun", code: -1) let error = NSError(domain: "com.jihe.punchnet.tun", code: -1)
self.provider.cancelTunnelWithError(error) self.provider.cancelTunnelWithError(error)
case .noIpAddress, .networkFault, .internalFault: case .noIpAddress, .networkFault, .internalFault:
self.superRegistrationStateMachine.handleRetryableNak()
self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage) self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)
} }
SDLLogger.log("[SDLContext] Get a SuperNak message exit") SDLLogger.log("[SDLContext] Get a SuperNak message exit")
} }
private func handleEvent(event: SDLEvent) async { private func handleEvent(event: SDLEvent) async {

View File

@ -1,76 +0,0 @@
//
// SDLSuperRegistrationStateMachine.swift
// Tun
//
// Created by on 2026/4/15.
//
import Foundation
final class SDLSuperRegistrationStateMachine {
enum State: Equatable {
case idle
case registering
case registered
case failed
}
enum LoopAction {
case sendRegister
case stop
}
enum WaitDecision {
case retry
case registered
case stop
}
private(set) var state: State = .idle
func beginLoop() -> Bool {
guard self.state != .registering else {
return false
}
self.state = .registering
return true
}
func makeLoopAction() -> LoopAction {
switch self.state {
case .registering:
return .sendRegister
case .idle, .registered, .failed:
return .stop
}
}
func makeWaitDecision() -> WaitDecision {
switch self.state {
case .registering:
return .retry
case .registered:
return .registered
case .idle, .failed:
return .stop
}
}
func handleRegisterSuperAck() {
self.state = .registered
}
func handleRetryableNak() {
self.state = .registering
}
func handleFailure() {
self.state = .failed
}
func reset() {
self.state = .idle
}
}

View File

@ -12,7 +12,14 @@ final class SDLPathMonitor {
private let queue = DispatchQueue(label: "com.sdlan.path-monitor") private let queue = DispatchQueue(label: "com.sdlan.path-monitor")
private let debouncer = SDLPathDebounceActor(delay: .seconds(2)) private let debouncer = SDLPathDebounceActor(delay: .seconds(2))
private var isStarted: Bool = false
func start() { func start() {
guard !isStarted else {
return
}
self.isStarted = true
monitor.pathUpdateHandler = { path in monitor.pathUpdateHandler = { path in
let snapshot = SDLPathSnapshot(path) let snapshot = SDLPathSnapshot(path)