fix register fsm
This commit is contained in:
parent
a8f0bc7804
commit
5bb39c8564
@ -14,11 +14,6 @@ import NIOCore
|
||||
1. 处理rsa的加解密逻辑
|
||||
*/
|
||||
actor SDLContextActor {
|
||||
enum State {
|
||||
case unregistered
|
||||
case registered
|
||||
}
|
||||
|
||||
enum ReadyState {
|
||||
case idle
|
||||
case starting
|
||||
@ -27,7 +22,6 @@ actor SDLContextActor {
|
||||
case stopped
|
||||
}
|
||||
|
||||
private var state: State = .unregistered
|
||||
private var readyState: ReadyState = .idle
|
||||
private var readyWaiters: [CheckedContinuation<Void, Error>] = []
|
||||
|
||||
@ -96,6 +90,7 @@ actor SDLContextActor {
|
||||
|
||||
// 注册任务
|
||||
private var registerTask: Task<Void, Never>?
|
||||
private let superRegistrationStateMachine = SDLSuperRegistrationStateMachine()
|
||||
|
||||
public init(provider: NEPacketTunnelProvider, config: SDLConfiguration, rsaCipher: RSACipher) {
|
||||
self.provider = provider
|
||||
@ -347,7 +342,7 @@ actor SDLContextActor {
|
||||
public func stop() async {
|
||||
self.resumeReadyWaiters(.failure(CancellationError()))
|
||||
self.readyState = .stopped
|
||||
self.state = .unregistered
|
||||
self.superRegistrationStateMachine.reset()
|
||||
|
||||
await self.supervisor.stop()
|
||||
await self.puncherActor.stop()
|
||||
@ -631,27 +626,41 @@ extension SDLContextActor {
|
||||
|
||||
// 开启注册任务
|
||||
private func startRegisterLoop() {
|
||||
guard self.registerTask == nil else {
|
||||
guard self.registerTask == nil,
|
||||
self.superRegistrationStateMachine.beginLoop() else {
|
||||
return
|
||||
}
|
||||
|
||||
self.registerTask = Task {
|
||||
while !Task.isCancelled {
|
||||
self.doRegisterSuper()
|
||||
try? await Task.sleep(for: .seconds(5))
|
||||
if self.state == .registered {
|
||||
await self.whenRegistedSuper()
|
||||
break
|
||||
}
|
||||
SDLLogger.log("[SDLContext] register super failed, retry")
|
||||
defer {
|
||||
self.registerTask = nil
|
||||
}
|
||||
|
||||
while !Task.isCancelled {
|
||||
switch self.superRegistrationStateMachine.makeLoopAction() {
|
||||
case .sendRegister:
|
||||
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
|
||||
}
|
||||
}
|
||||
self.registerTask = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func handleRegisterSuperAck(registerSuperAck: SDLRegisterSuperAck) async {
|
||||
// 需要对数据通过rsa的私钥解码
|
||||
guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else {
|
||||
self.superRegistrationStateMachine.handleFailure()
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid key")
|
||||
let error = SDLError.invalidKey
|
||||
self.failReady(error)
|
||||
@ -669,6 +678,7 @@ extension SDLContextActor {
|
||||
case "chacha20":
|
||||
self.dataCipher = CCChaCha20Cipher(regionId: regionId, keyData: key)
|
||||
default:
|
||||
self.superRegistrationStateMachine.handleFailure()
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)")
|
||||
let error = SDLError.unsupportedAlgorithm(algorithm: algorithm)
|
||||
self.failReady(error)
|
||||
@ -681,10 +691,11 @@ extension SDLContextActor {
|
||||
do {
|
||||
try await self.setNetworkSettings(config: self.config, dnsServer: DNSHelper.dnsServer)
|
||||
SDLLogger.log("[SDLContext] setNetworkSettings successed")
|
||||
self.state = .registered
|
||||
self.superRegistrationStateMachine.handleRegisterSuperAck()
|
||||
self.startReader()
|
||||
self.markReady()
|
||||
} catch let err {
|
||||
self.superRegistrationStateMachine.handleFailure()
|
||||
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)")
|
||||
self.failReady(err)
|
||||
self.provider.cancelTunnelWithError(err)
|
||||
@ -699,6 +710,7 @@ extension SDLContextActor {
|
||||
|
||||
switch errorCode {
|
||||
case .invalidToken, .nodeDisabled:
|
||||
self.superRegistrationStateMachine.handleFailure()
|
||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||
self.noticeClient?.send(data: alertNotice)
|
||||
// 报告错误并退出
|
||||
@ -707,6 +719,7 @@ extension SDLContextActor {
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
|
||||
case .noIpAddress, .networkFault, .internalFault:
|
||||
self.superRegistrationStateMachine.handleRetryableNak()
|
||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||
self.noticeClient?.send(data: alertNotice)
|
||||
}
|
||||
|
||||
76
Tun/Punchnet/Actors/SDLSuperRegistrationStateMachine.swift
Normal file
76
Tun/Punchnet/Actors/SDLSuperRegistrationStateMachine.swift
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// 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 = .failed
|
||||
}
|
||||
|
||||
func handleFailure() {
|
||||
self.state = .failed
|
||||
}
|
||||
|
||||
func reset() {
|
||||
self.state = .idle
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user