fix superControlPlane
This commit is contained in:
parent
83bd5dce7e
commit
eca022cae0
@ -22,9 +22,6 @@ actor SDLContextActor {
|
||||
// AES加密,授权通过后,对象才会被创建
|
||||
private var dataCipher: CCDataCipher?
|
||||
|
||||
// session token
|
||||
private var sessionToken: Data?
|
||||
|
||||
// rsa的相关配置, public_key是本地生成的
|
||||
// 加密算法相关
|
||||
nonisolated let rsaCipher: RSACipher
|
||||
@ -32,6 +29,7 @@ actor SDLContextActor {
|
||||
private let dnsCloudService: DNSCloudService
|
||||
private let dnsLocalService: DNSLocalService
|
||||
private let superService: SDLSuperService
|
||||
private let superControlPlane: SDLSuperControlPlane
|
||||
private let udpHoleService: SDLUDPHoleService
|
||||
private let udpHoleV6Service: SDLUDPHoleV6Service
|
||||
private let packetOutboundActor: PacketOutboundActor
|
||||
@ -77,6 +75,7 @@ actor SDLContextActor {
|
||||
let udpHoleV6Service = SDLUDPHoleV6Service()
|
||||
let dnsCloudService = DNSCloudService(serverIP: config.serverEndpoint.ip)
|
||||
let dnsLocalService = DNSLocalService(publicDnsServers: Self.publicDnsServers)
|
||||
let superControlPlane = SDLSuperControlPlane(config: config, rsaCipher: rsaCipher)
|
||||
let tunNetworkManager = SDLTunNetworkManager(provider: provider)
|
||||
let ipv6AssistPair = AsyncStream.makeStream(of: Optional<SDLV6Info>.self, bufferingPolicy: .bufferingNewest(1))
|
||||
let packetOutboundActor = PacketOutboundActor(
|
||||
@ -122,6 +121,7 @@ actor SDLContextActor {
|
||||
self.dnsCloudService = dnsCloudService
|
||||
self.dnsLocalService = dnsLocalService
|
||||
self.superService = superService
|
||||
self.superControlPlane = superControlPlane
|
||||
self.udpHoleService = udpHoleService
|
||||
self.udpHoleV6Service = udpHoleV6Service
|
||||
self.packetOutboundActor = packetOutboundActor
|
||||
@ -138,7 +138,17 @@ actor SDLContextActor {
|
||||
}
|
||||
|
||||
let rootTask = Task {
|
||||
try await self.runRoot()
|
||||
do {
|
||||
try await self.runRootBody()
|
||||
await self.cleanupRoot()
|
||||
} catch is CancellationError {
|
||||
await self.cleanupRoot()
|
||||
throw CancellationError()
|
||||
} catch {
|
||||
await self.readySignal.fail(error)
|
||||
await self.cleanupRoot()
|
||||
throw error
|
||||
}
|
||||
}
|
||||
self.rootTask = rootTask
|
||||
|
||||
@ -163,20 +173,6 @@ actor SDLContextActor {
|
||||
await self.cleanupRoot()
|
||||
}
|
||||
|
||||
private func runRoot() async throws {
|
||||
do {
|
||||
try await self.runRootBody()
|
||||
await self.cleanupRoot()
|
||||
} catch is CancellationError {
|
||||
await self.cleanupRoot()
|
||||
throw CancellationError()
|
||||
} catch {
|
||||
await self.readySignal.fail(error)
|
||||
await self.cleanupRoot()
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
private func runRootBody() async throws {
|
||||
self.prepareTunnelNotifier()
|
||||
|
||||
@ -188,8 +184,13 @@ actor SDLContextActor {
|
||||
await self?.handleDNSEvent(event)
|
||||
}
|
||||
|
||||
await self.superService.updateMessageHandler { [weak self] message in
|
||||
await self?.handleSuperMessage(message: message)
|
||||
await self.superControlPlane.updateDecisionHandler { [weak self] decision in
|
||||
await self?.handleSuperDecision(decision)
|
||||
}
|
||||
|
||||
let superControlPlane = self.superControlPlane
|
||||
await self.superService.updateMessageHandler { message in
|
||||
await superControlPlane.handle(message)
|
||||
}
|
||||
|
||||
let packetInboundActor = self.packetInboundActor
|
||||
@ -392,8 +393,8 @@ actor SDLContextActor {
|
||||
await self.dnsLocalService.stop()
|
||||
|
||||
await self.superService.stop()
|
||||
await self.superControlPlane.reset()
|
||||
|
||||
self.sessionToken = nil
|
||||
self.dataCipher = nil
|
||||
self.natType = .blocked
|
||||
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: nil)
|
||||
@ -436,11 +437,6 @@ extension SDLContextActor {
|
||||
// MARK: 数据发送
|
||||
extension SDLContextActor {
|
||||
|
||||
// 发送给super/stun节点的数据
|
||||
private func sendSuperPacket(type: SDLPacketType, data: Data) async {
|
||||
await self.sendPacket(type: type, data: data, remoteAddress: self.config.stunSocketAddress)
|
||||
}
|
||||
|
||||
// 发送给peer的数据
|
||||
private func sendPeerPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async {
|
||||
await self.sendPacket(type: type, data: data, remoteAddress: remoteAddress)
|
||||
@ -460,160 +456,64 @@ extension SDLContextActor {
|
||||
|
||||
// MARK: 处理和Super之间的通讯
|
||||
extension SDLContextActor {
|
||||
|
||||
private func handleSuperMessage(message: SDLSuperMessage) async {
|
||||
switch message {
|
||||
case .welcome(let welcome):
|
||||
SDLLogger.log("[SDLContext] quic welcome: \(welcome)")
|
||||
|
||||
|
||||
private func handleSuperDecision(_ decision: SuperDecision) async {
|
||||
switch decision {
|
||||
case .updateIPv6Assist(let assistInfo):
|
||||
await self.stopCurrentIPv6AssistClient()
|
||||
// 尝试创建v6地址的辅助探测器
|
||||
if welcome.hasIpv6Assist {
|
||||
self.ipv6AssistContinuation.yield(welcome.ipv6Assist)
|
||||
} else {
|
||||
self.ipv6AssistContinuation.yield(nil)
|
||||
}
|
||||
|
||||
// 注册
|
||||
await self.doRegisterSuper()
|
||||
SDLLogger.log("[SDLContext] quic doRegisterSuper")
|
||||
case .pong:
|
||||
//SDLLogger.shared.log("[SDLContext] quic pong")
|
||||
()
|
||||
case .registerSuperAck(let registerSuperAck):
|
||||
await self.handleRegisterSuperAck(registerSuperAck: registerSuperAck)
|
||||
case .registerSuperNak(let registerSuperNak):
|
||||
await self.handleRegisterSuperNak(nakPacket: registerSuperNak)
|
||||
case .peerInfo(let peerInfo):
|
||||
SDLLogger.log("[SDLContext] peer message: \(peerInfo)")
|
||||
self.ipv6AssistContinuation.yield(assistInfo)
|
||||
case .completeRegistration(let cipher):
|
||||
await self.completeSuperRegistration(cipher: cipher)
|
||||
case .failTunnel(let error):
|
||||
await self.failTunnel(error)
|
||||
case .publishTunnelEvent(let code, let message):
|
||||
self.publishTunnelEvent(code: code, message: message)
|
||||
case .sendSuper(let type, let data):
|
||||
await self.superService.send(type: type, data: data)
|
||||
case .sendPacket(let type, let data, let remoteAddress):
|
||||
await self.sendPacket(type: type, data: data, remoteAddress: remoteAddress)
|
||||
case .resolvePeerInfo(let peerInfo):
|
||||
let packets = await self.puncherActor.makeRegisterPackets(peerInfo: peerInfo)
|
||||
for packet in packets {
|
||||
await self.sendPacket(type: .register, data: packet.data, remoteAddress: packet.remoteAddress)
|
||||
}
|
||||
case .event(let event):
|
||||
await self.handleEvent(event: event)
|
||||
case .policyReponse(let policyResponse):
|
||||
// 处理权限的请求问题
|
||||
await self.policyService.applyPolicyResponse(policyResponse)
|
||||
case .exposedServiceResponse(let response):
|
||||
await self.applyExposedServiceResponse(response)
|
||||
case .arpResponse(let arpResponse):
|
||||
SDLLogger.log("[SDLContext] get arp response: \(arpResponse)")
|
||||
await self.arpResolver.handleArpResponse(arpResponse: arpResponse)
|
||||
}
|
||||
}
|
||||
|
||||
private func makeSuperEventProcessor() -> SDLSuperEventProcessor {
|
||||
return .init(networkAddress: self.config.networkAddress)
|
||||
}
|
||||
|
||||
private func handleRegisterSuperAck(registerSuperAck: SDLRegisterSuperAck) async {
|
||||
// 需要对数据通过rsa的私钥解码
|
||||
guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else {
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid key")
|
||||
let error = SDLError.invalidKey
|
||||
await self.readySignal.fail(error)
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
return
|
||||
}
|
||||
|
||||
let algorithm = registerSuperAck.algorithm.lowercased()
|
||||
let regionId = registerSuperAck.regionID
|
||||
self.sessionToken = registerSuperAck.sessionToken
|
||||
|
||||
switch algorithm {
|
||||
case "aes":
|
||||
self.dataCipher = CCAESChiper(key: key)
|
||||
case "chacha20":
|
||||
self.dataCipher = CCChaCha20Cipher(regionId: regionId, keyData: key)
|
||||
default:
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)")
|
||||
let error = SDLError.unsupportedAlgorithm(algorithm: algorithm)
|
||||
await self.readySignal.fail(error)
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
return
|
||||
}
|
||||
|
||||
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: self.dataCipher)
|
||||
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: self.dataCipher)
|
||||
SDLLogger.log("[SDLContext] registerSuperAck, use algorithm \(algorithm), key len: \(key.count)")
|
||||
// 服务器分配的tun网卡信息
|
||||
do {
|
||||
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
|
||||
SDLLogger.log("[SDLContext] setNetworkSettings successed")
|
||||
await self.readySignal.succeed(())
|
||||
} catch let err {
|
||||
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(err)")
|
||||
await self.readySignal.fail(err)
|
||||
self.provider.cancelTunnelWithError(err)
|
||||
}
|
||||
}
|
||||
|
||||
private func handleRegisterSuperNak(nakPacket: SDLRegisterSuperNak) async {
|
||||
let errorMessage = nakPacket.errorMessage
|
||||
guard let errorCode = SDLNAKErrorCode(rawValue: UInt8(nakPacket.errorCode)) else {
|
||||
return
|
||||
}
|
||||
|
||||
switch errorCode {
|
||||
case .invalidToken, .nodeDisabled:
|
||||
self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)
|
||||
// 报告错误并退出
|
||||
let error = NSError(domain: "com.jihe.punchnet.tun", code: -1)
|
||||
await self.readySignal.fail(error)
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
|
||||
case .noIpAddress, .networkFault, .internalFault:
|
||||
self.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage)
|
||||
}
|
||||
SDLLogger.log("[SDLContext] Get a SuperNak message exit")
|
||||
}
|
||||
|
||||
private func handleEvent(event: SDLEvent) async {
|
||||
let processor = self.makeSuperEventProcessor()
|
||||
let plan = await processor.makeProcessingPlan(event: event)
|
||||
if let logMessage = plan.logMessage {
|
||||
SDLLogger.log(logMessage)
|
||||
}
|
||||
|
||||
switch plan.action {
|
||||
case .removeSession(let dstMac):
|
||||
await self.sessionManager.removeSession(dstMac: dstMac)
|
||||
case .sendRegister(let registerData, let remoteAddresses):
|
||||
for remoteAddress in remoteAddresses {
|
||||
await self.sendPeerPacket(type: .register, data: registerData, remoteAddress: remoteAddress)
|
||||
}
|
||||
case .requestExposedService:
|
||||
await self.requestExposedService()
|
||||
case .shutdown(let message):
|
||||
self.publishTunnelEvent(message: message)
|
||||
|
||||
// 报告错误并退出
|
||||
let error = NSError(domain: "com.jihe.punchnet.tun", code: -2)
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
case .none:
|
||||
()
|
||||
case .applyPolicyResponse(let policyResponse):
|
||||
await self.policyService.applyPolicyResponse(policyResponse)
|
||||
case .applyExposedServiceResponse(let response):
|
||||
await self.applyExposedServiceResponse(response)
|
||||
case .handleARPResponse(let arpResponse):
|
||||
await self.arpResolver.handleArpResponse(arpResponse: arpResponse)
|
||||
}
|
||||
}
|
||||
|
||||
private func doRegisterSuper() async {
|
||||
// 注册
|
||||
var registerSuper = SDLRegisterSuper()
|
||||
registerSuper.clientID = self.config.clientId
|
||||
registerSuper.networkID = self.config.networkAddress.networkId
|
||||
registerSuper.mac = self.config.networkAddress.mac
|
||||
registerSuper.ip = self.config.networkAddress.ip
|
||||
registerSuper.maskLen = UInt32(self.config.networkAddress.maskLen)
|
||||
registerSuper.hostname = self.config.hostname
|
||||
registerSuper.pubKey = self.rsaCipher.pubKey
|
||||
registerSuper.accessToken = self.config.accessToken
|
||||
|
||||
if let registerSuperData = try? registerSuper.serializedData() {
|
||||
SDLLogger.log("[SDLContext] will send register super")
|
||||
await self.superService.send(type: .registerSuper, data: registerSuperData)
|
||||
|
||||
private func completeSuperRegistration(cipher: CCDataCipher) async {
|
||||
self.dataCipher = cipher
|
||||
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: cipher)
|
||||
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: cipher)
|
||||
|
||||
do {
|
||||
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
|
||||
SDLLogger.log("[SDLContext] setNetworkSettings successed")
|
||||
await self.readySignal.succeed(())
|
||||
} catch {
|
||||
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(error)")
|
||||
await self.failTunnel(error)
|
||||
}
|
||||
}
|
||||
|
||||
private func failTunnel(_ error: Error) async {
|
||||
await self.readySignal.fail(error)
|
||||
self.provider.cancelTunnelWithError(error)
|
||||
}
|
||||
|
||||
private func requestExposedService() async {
|
||||
guard let requestData = await self.policyService.makeExposedServiceRequest() else {
|
||||
return
|
||||
@ -735,29 +635,7 @@ extension SDLContextActor {
|
||||
SDLLogger.log("[SDLContext] probe ipv6 address: empty")
|
||||
}
|
||||
|
||||
await self.sendStunRequest(v6Info: probeReply?.v6Info)
|
||||
}
|
||||
|
||||
private func sendStunRequest(v6Info: SDLV6Info?) async {
|
||||
guard let sessionToken = self.sessionToken else {
|
||||
return
|
||||
}
|
||||
|
||||
var stunRequest = SDLStunRequest()
|
||||
stunRequest.clientID = self.config.clientId
|
||||
stunRequest.networkID = self.config.networkAddress.networkId
|
||||
stunRequest.ip = self.config.networkAddress.ip
|
||||
stunRequest.mac = self.config.networkAddress.mac
|
||||
stunRequest.natType = UInt32(self.natType.rawValue)
|
||||
stunRequest.sessionToken = sessionToken
|
||||
|
||||
if let v6Info {
|
||||
stunRequest.v6Info = v6Info
|
||||
}
|
||||
|
||||
if let stunData = try? stunRequest.serializedData() {
|
||||
await self.sendSuperPacket(type: .stunRequest, data: stunData)
|
||||
}
|
||||
await self.superControlPlane.sendStunRequest(natType: self.natType, v6Info: probeReply?.v6Info)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
210
Tun/Context/SDLSuperControlPlane.swift
Normal file
210
Tun/Context/SDLSuperControlPlane.swift
Normal file
@ -0,0 +1,210 @@
|
||||
//
|
||||
// SDLSuperControlPlane.swift
|
||||
// Tun
|
||||
//
|
||||
// Created by Codex on 2026/5/28.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import NIOCore
|
||||
|
||||
enum SuperDecision {
|
||||
case updateIPv6Assist(SDLV6Info?)
|
||||
case completeRegistration(cipher: CCDataCipher)
|
||||
case failTunnel(Error)
|
||||
case publishTunnelEvent(code: Int?, message: String)
|
||||
case sendSuper(type: SDLPacketType, data: Data)
|
||||
case sendPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress)
|
||||
case resolvePeerInfo(SDLPeerInfo)
|
||||
case removeSession(dstMac: Data)
|
||||
case requestExposedService
|
||||
case shutdown(message: String)
|
||||
case applyPolicyResponse(SDLPolicyResponse)
|
||||
case applyExposedServiceResponse(SDLExposedServiceResponse)
|
||||
case handleARPResponse(SDLArpResponse)
|
||||
}
|
||||
|
||||
actor SDLSuperControlPlane {
|
||||
typealias DecisionHandler = @Sendable (SuperDecision) async -> Void
|
||||
|
||||
private let config: SDLConfiguration
|
||||
private let rsaCipher: RSACipher
|
||||
private var sessionToken: Data?
|
||||
private var onDecision: DecisionHandler = { _ in }
|
||||
|
||||
init(config: SDLConfiguration, rsaCipher: RSACipher) {
|
||||
self.config = config
|
||||
self.rsaCipher = rsaCipher
|
||||
}
|
||||
|
||||
func updateDecisionHandler(_ onDecision: @escaping DecisionHandler) {
|
||||
self.onDecision = onDecision
|
||||
}
|
||||
|
||||
func reset() {
|
||||
self.sessionToken = nil
|
||||
}
|
||||
|
||||
func handle(_ message: SDLSuperMessage) async {
|
||||
switch message {
|
||||
case .welcome(let welcome):
|
||||
await self.handleWelcome(welcome)
|
||||
case .pong:
|
||||
()
|
||||
case .registerSuperAck(let registerSuperAck):
|
||||
await self.handleRegisterSuperAck(registerSuperAck)
|
||||
case .registerSuperNak(let registerSuperNak):
|
||||
await self.handleRegisterSuperNak(registerSuperNak)
|
||||
case .peerInfo(let peerInfo):
|
||||
SDLLogger.log("[SDLContext] peer message: \(peerInfo)")
|
||||
await self.onDecision(.resolvePeerInfo(peerInfo))
|
||||
case .event(let event):
|
||||
await self.handleEvent(event)
|
||||
case .policyReponse(let policyResponse):
|
||||
await self.onDecision(.applyPolicyResponse(policyResponse))
|
||||
case .exposedServiceResponse(let response):
|
||||
await self.onDecision(.applyExposedServiceResponse(response))
|
||||
case .arpResponse(let arpResponse):
|
||||
SDLLogger.log("[SDLContext] get arp response: \(arpResponse)")
|
||||
await self.onDecision(.handleARPResponse(arpResponse))
|
||||
}
|
||||
}
|
||||
|
||||
func sendStunRequest(natType: SDLNATProberActor.NatType, v6Info: SDLV6Info?) async {
|
||||
guard let sessionToken else {
|
||||
return
|
||||
}
|
||||
|
||||
var stunRequest = SDLStunRequest()
|
||||
stunRequest.clientID = self.config.clientId
|
||||
stunRequest.networkID = self.config.networkAddress.networkId
|
||||
stunRequest.ip = self.config.networkAddress.ip
|
||||
stunRequest.mac = self.config.networkAddress.mac
|
||||
stunRequest.natType = UInt32(natType.rawValue)
|
||||
stunRequest.sessionToken = sessionToken
|
||||
|
||||
if let v6Info {
|
||||
stunRequest.v6Info = v6Info
|
||||
}
|
||||
|
||||
if let stunData = try? stunRequest.serializedData() {
|
||||
await self.onDecision(.sendPacket(type: .stunRequest, data: stunData, remoteAddress: self.config.stunSocketAddress))
|
||||
}
|
||||
}
|
||||
|
||||
private func handleWelcome(_ welcome: SDLWelcome) async {
|
||||
SDLLogger.log("[SDLContext] quic welcome: \(welcome)")
|
||||
|
||||
if welcome.hasIpv6Assist {
|
||||
await self.onDecision(.updateIPv6Assist(welcome.ipv6Assist))
|
||||
} else {
|
||||
await self.onDecision(.updateIPv6Assist(nil))
|
||||
}
|
||||
|
||||
await self.doRegisterSuper()
|
||||
SDLLogger.log("[SDLContext] quic doRegisterSuper")
|
||||
}
|
||||
|
||||
private func handleRegisterSuperAck(_ registerSuperAck: SDLRegisterSuperAck) async {
|
||||
guard let key = try? self.rsaCipher.decode(data: Data(registerSuperAck.key)) else {
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid key")
|
||||
await self.onDecision(.failTunnel(SDLError.invalidKey))
|
||||
return
|
||||
}
|
||||
|
||||
let algorithm = registerSuperAck.algorithm.lowercased()
|
||||
let regionId = registerSuperAck.regionID
|
||||
self.sessionToken = registerSuperAck.sessionToken
|
||||
|
||||
let cipher: CCDataCipher
|
||||
switch algorithm {
|
||||
case "aes":
|
||||
cipher = CCAESChiper(key: key)
|
||||
case "chacha20":
|
||||
cipher = CCChaCha20Cipher(regionId: regionId, keyData: key)
|
||||
default:
|
||||
SDLLogger.log("[SDLContext] registerSuperAck invalid algorithm \(algorithm)")
|
||||
await self.onDecision(.failTunnel(SDLError.unsupportedAlgorithm(algorithm: algorithm)))
|
||||
return
|
||||
}
|
||||
|
||||
SDLLogger.log("[SDLContext] registerSuperAck, use algorithm \(algorithm), key len: \(key.count)")
|
||||
await self.onDecision(.completeRegistration(cipher: cipher))
|
||||
}
|
||||
|
||||
private func handleRegisterSuperNak(_ nakPacket: SDLRegisterSuperNak) async {
|
||||
let errorMessage = nakPacket.errorMessage
|
||||
guard let errorCode = SDLNAKErrorCode(rawValue: UInt8(nakPacket.errorCode)) else {
|
||||
return
|
||||
}
|
||||
|
||||
switch errorCode {
|
||||
case .invalidToken, .nodeDisabled:
|
||||
await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage))
|
||||
await self.onDecision(.failTunnel(NSError(domain: "com.jihe.punchnet.tun", code: -1)))
|
||||
case .noIpAddress, .networkFault, .internalFault:
|
||||
await self.onDecision(.publishTunnelEvent(code: Int(errorCode.rawValue), message: errorMessage))
|
||||
}
|
||||
|
||||
SDLLogger.log("[SDLContext] Get a SuperNak message exit")
|
||||
}
|
||||
|
||||
private func handleEvent(_ event: SDLEvent) async {
|
||||
switch event.event {
|
||||
case .natChanged(let natChangedEvent):
|
||||
let dstMac = natChangedEvent.mac
|
||||
SDLLogger.log("[SDLContext] natChangedEvent, dstMac: \(dstMac)")
|
||||
await self.onDecision(.removeSession(dstMac: dstMac))
|
||||
case .sendRegister(let sendRegisterEvent):
|
||||
await self.handleSendRegisterEvent(sendRegisterEvent)
|
||||
case .exposedServiceChanged:
|
||||
SDLLogger.log("[SDLContext] exposedServiceChanged event")
|
||||
await self.onDecision(.requestExposedService)
|
||||
case .shutdown(let shutdownEvent):
|
||||
await self.onDecision(.shutdown(message: shutdownEvent.message))
|
||||
case .none:
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
private func handleSendRegisterEvent(_ event: SDLEvent.SendRegister) async {
|
||||
var register = SDLRegister()
|
||||
register.networkID = self.config.networkAddress.networkId
|
||||
register.srcMac = self.config.networkAddress.mac
|
||||
register.dstMac = event.dstMac
|
||||
|
||||
guard let registerData = try? register.serializedData() else {
|
||||
return
|
||||
}
|
||||
|
||||
SDLLogger.log("[SDLContext] sendRegisterEvent, ip: \(event)")
|
||||
|
||||
if event.natIp > 0 && event.natPort > 0 {
|
||||
let address = SDLUtil.int32ToIp(event.natIp)
|
||||
if let remoteAddress = try? SocketAddress(ipAddress: address, port: Int(event.natPort)) {
|
||||
await self.onDecision(.sendPacket(type: .register, data: registerData, remoteAddress: remoteAddress))
|
||||
}
|
||||
}
|
||||
|
||||
if event.hasV6Info, let remoteAddress = try? await event.v6Info.socketAddress() {
|
||||
await self.onDecision(.sendPacket(type: .register, data: registerData, remoteAddress: remoteAddress))
|
||||
}
|
||||
}
|
||||
|
||||
private func doRegisterSuper() async {
|
||||
var registerSuper = SDLRegisterSuper()
|
||||
registerSuper.clientID = self.config.clientId
|
||||
registerSuper.networkID = self.config.networkAddress.networkId
|
||||
registerSuper.mac = self.config.networkAddress.mac
|
||||
registerSuper.ip = self.config.networkAddress.ip
|
||||
registerSuper.maskLen = UInt32(self.config.networkAddress.maskLen)
|
||||
registerSuper.hostname = self.config.hostname
|
||||
registerSuper.pubKey = self.rsaCipher.pubKey
|
||||
registerSuper.accessToken = self.config.accessToken
|
||||
|
||||
if let registerSuperData = try? registerSuper.serializedData() {
|
||||
SDLLogger.log("[SDLContext] will send register super")
|
||||
await self.onDecision(.sendSuper(type: .registerSuper, data: registerSuperData))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,78 +0,0 @@
|
||||
//
|
||||
// SDLSuperEventProcessor.swift
|
||||
// Tun
|
||||
//
|
||||
// Created by 安礼成 on 2026/4/15.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import NIOCore
|
||||
|
||||
final class SDLSuperEventProcessor {
|
||||
enum ProcessingAction {
|
||||
case removeSession(dstMac: Data)
|
||||
case sendRegister(data: Data, remoteAddresses: [SocketAddress])
|
||||
case requestExposedService
|
||||
case shutdown(message: String)
|
||||
case none
|
||||
}
|
||||
|
||||
struct ProcessingPlan {
|
||||
let logMessage: String?
|
||||
let action: ProcessingAction
|
||||
}
|
||||
|
||||
private let networkAddress: SDLConfiguration.NetworkAddress
|
||||
|
||||
init(networkAddress: SDLConfiguration.NetworkAddress) {
|
||||
self.networkAddress = networkAddress
|
||||
}
|
||||
|
||||
func makeProcessingPlan(event: SDLEvent) async -> ProcessingPlan {
|
||||
switch event.event {
|
||||
case .natChanged(let natChangedEvent):
|
||||
let dstMac = natChangedEvent.mac
|
||||
return .init(
|
||||
logMessage: "[SDLContext] natChangedEvent, dstMac: \(dstMac)",
|
||||
action: .removeSession(dstMac: dstMac)
|
||||
)
|
||||
case .sendRegister(let sendRegisterEvent):
|
||||
return await self.makeSendRegisterPlan(sendRegisterEvent)
|
||||
case .exposedServiceChanged:
|
||||
return .init(
|
||||
logMessage: "[SDLContext] exposedServiceChanged event",
|
||||
action: .requestExposedService
|
||||
)
|
||||
case .shutdown(let shutdownEvent):
|
||||
return .init(logMessage: nil, action: .shutdown(message: shutdownEvent.message))
|
||||
case .none:
|
||||
return .init(logMessage: nil, action: .none)
|
||||
}
|
||||
}
|
||||
|
||||
private func makeSendRegisterPlan(_ event: SDLEvent.SendRegister) async -> ProcessingPlan {
|
||||
// 发送register包
|
||||
var register = SDLRegister()
|
||||
register.networkID = self.networkAddress.networkId
|
||||
register.srcMac = self.networkAddress.mac
|
||||
register.dstMac = event.dstMac
|
||||
let registerData = try! register.serializedData()
|
||||
|
||||
var remoteAddresses: [SocketAddress] = []
|
||||
if event.natIp > 0 && event.natPort > 0 {
|
||||
let address = SDLUtil.int32ToIp(event.natIp)
|
||||
if let remoteAddress = try? SocketAddress(ipAddress: address, port: Int(event.natPort)) {
|
||||
remoteAddresses.append(remoteAddress)
|
||||
}
|
||||
}
|
||||
|
||||
if event.hasV6Info, let remoteAddress = try? await event.v6Info.socketAddress() {
|
||||
remoteAddresses.append(remoteAddress)
|
||||
}
|
||||
|
||||
return .init(
|
||||
logMessage: "[SDLContext] sendRegisterEvent, ip: \(event)",
|
||||
action: .sendRegister(data: registerData, remoteAddresses: remoteAddresses)
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user