fix register fsm
This commit is contained in:
parent
a8f0bc7804
commit
5bb39c8564
@ -14,11 +14,6 @@ import NIOCore
|
|||||||
1. 处理rsa的加解密逻辑
|
1. 处理rsa的加解密逻辑
|
||||||
*/
|
*/
|
||||||
actor SDLContextActor {
|
actor SDLContextActor {
|
||||||
enum State {
|
|
||||||
case unregistered
|
|
||||||
case registered
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ReadyState {
|
enum ReadyState {
|
||||||
case idle
|
case idle
|
||||||
case starting
|
case starting
|
||||||
@ -27,7 +22,6 @@ actor SDLContextActor {
|
|||||||
case stopped
|
case stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
private var state: State = .unregistered
|
|
||||||
private var readyState: ReadyState = .idle
|
private var readyState: ReadyState = .idle
|
||||||
private var readyWaiters: [CheckedContinuation<Void, Error>] = []
|
private var readyWaiters: [CheckedContinuation<Void, Error>] = []
|
||||||
|
|
||||||
@ -96,6 +90,7 @@ actor SDLContextActor {
|
|||||||
|
|
||||||
// 注册任务
|
// 注册任务
|
||||||
private var registerTask: Task<Void, Never>?
|
private var registerTask: 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
|
||||||
@ -347,7 +342,7 @@ actor SDLContextActor {
|
|||||||
public func stop() async {
|
public func stop() async {
|
||||||
self.resumeReadyWaiters(.failure(CancellationError()))
|
self.resumeReadyWaiters(.failure(CancellationError()))
|
||||||
self.readyState = .stopped
|
self.readyState = .stopped
|
||||||
self.state = .unregistered
|
self.superRegistrationStateMachine.reset()
|
||||||
|
|
||||||
await self.supervisor.stop()
|
await self.supervisor.stop()
|
||||||
await self.puncherActor.stop()
|
await self.puncherActor.stop()
|
||||||
@ -631,27 +626,41 @@ extension SDLContextActor {
|
|||||||
|
|
||||||
// 开启注册任务
|
// 开启注册任务
|
||||||
private func startRegisterLoop() {
|
private func startRegisterLoop() {
|
||||||
guard self.registerTask == nil else {
|
guard self.registerTask == nil,
|
||||||
|
self.superRegistrationStateMachine.beginLoop() else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.registerTask = Task {
|
self.registerTask = Task {
|
||||||
while !Task.isCancelled {
|
defer {
|
||||||
self.doRegisterSuper()
|
|
||||||
try? await Task.sleep(for: .seconds(5))
|
|
||||||
if self.state == .registered {
|
|
||||||
await self.whenRegistedSuper()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
SDLLogger.log("[SDLContext] register super failed, retry")
|
|
||||||
}
|
|
||||||
self.registerTask = nil
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.failReady(error)
|
self.failReady(error)
|
||||||
@ -669,6 +678,7 @@ 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.failReady(error)
|
self.failReady(error)
|
||||||
@ -681,10 +691,11 @@ 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.state = .registered
|
self.superRegistrationStateMachine.handleRegisterSuperAck()
|
||||||
self.startReader()
|
self.startReader()
|
||||||
self.markReady()
|
self.markReady()
|
||||||
} catch let err {
|
} catch let err {
|
||||||
|
self.superRegistrationStateMachine.handleFailure()
|
||||||
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)")
|
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)")
|
||||||
self.failReady(err)
|
self.failReady(err)
|
||||||
self.provider.cancelTunnelWithError(err)
|
self.provider.cancelTunnelWithError(err)
|
||||||
@ -699,6 +710,7 @@ extension SDLContextActor {
|
|||||||
|
|
||||||
switch errorCode {
|
switch errorCode {
|
||||||
case .invalidToken, .nodeDisabled:
|
case .invalidToken, .nodeDisabled:
|
||||||
|
self.superRegistrationStateMachine.handleFailure()
|
||||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||||
self.noticeClient?.send(data: alertNotice)
|
self.noticeClient?.send(data: alertNotice)
|
||||||
// 报告错误并退出
|
// 报告错误并退出
|
||||||
@ -707,6 +719,7 @@ extension SDLContextActor {
|
|||||||
self.provider.cancelTunnelWithError(error)
|
self.provider.cancelTunnelWithError(error)
|
||||||
|
|
||||||
case .noIpAddress, .networkFault, .internalFault:
|
case .noIpAddress, .networkFault, .internalFault:
|
||||||
|
self.superRegistrationStateMachine.handleRetryableNak()
|
||||||
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
let alertNotice = NoticeMessage.alert(alert: errorMessage)
|
||||||
self.noticeClient?.send(data: alertNotice)
|
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