fix superControlPlane
This commit is contained in:
parent
83bd5dce7e
commit
eca022cae0
@ -22,9 +22,6 @@ actor SDLContextActor {
|
|||||||
// AES加密,授权通过后,对象才会被创建
|
// AES加密,授权通过后,对象才会被创建
|
||||||
private var dataCipher: CCDataCipher?
|
private var dataCipher: CCDataCipher?
|
||||||
|
|
||||||
// session token
|
|
||||||
private var sessionToken: Data?
|
|
||||||
|
|
||||||
// rsa的相关配置, public_key是本地生成的
|
// rsa的相关配置, public_key是本地生成的
|
||||||
// 加密算法相关
|
// 加密算法相关
|
||||||
nonisolated let rsaCipher: RSACipher
|
nonisolated let rsaCipher: RSACipher
|
||||||
@ -32,6 +29,7 @@ actor SDLContextActor {
|
|||||||
private let dnsCloudService: DNSCloudService
|
private let dnsCloudService: DNSCloudService
|
||||||
private let dnsLocalService: DNSLocalService
|
private let dnsLocalService: DNSLocalService
|
||||||
private let superService: SDLSuperService
|
private let superService: SDLSuperService
|
||||||
|
private let superControlPlane: SDLSuperControlPlane
|
||||||
private let udpHoleService: SDLUDPHoleService
|
private let udpHoleService: SDLUDPHoleService
|
||||||
private let udpHoleV6Service: SDLUDPHoleV6Service
|
private let udpHoleV6Service: SDLUDPHoleV6Service
|
||||||
private let packetOutboundActor: PacketOutboundActor
|
private let packetOutboundActor: PacketOutboundActor
|
||||||
@ -77,6 +75,7 @@ actor SDLContextActor {
|
|||||||
let udpHoleV6Service = SDLUDPHoleV6Service()
|
let udpHoleV6Service = SDLUDPHoleV6Service()
|
||||||
let dnsCloudService = DNSCloudService(serverIP: config.serverEndpoint.ip)
|
let dnsCloudService = DNSCloudService(serverIP: config.serverEndpoint.ip)
|
||||||
let dnsLocalService = DNSLocalService(publicDnsServers: Self.publicDnsServers)
|
let dnsLocalService = DNSLocalService(publicDnsServers: Self.publicDnsServers)
|
||||||
|
let superControlPlane = SDLSuperControlPlane(config: config, rsaCipher: rsaCipher)
|
||||||
let tunNetworkManager = SDLTunNetworkManager(provider: provider)
|
let tunNetworkManager = SDLTunNetworkManager(provider: provider)
|
||||||
let ipv6AssistPair = AsyncStream.makeStream(of: Optional<SDLV6Info>.self, bufferingPolicy: .bufferingNewest(1))
|
let ipv6AssistPair = AsyncStream.makeStream(of: Optional<SDLV6Info>.self, bufferingPolicy: .bufferingNewest(1))
|
||||||
let packetOutboundActor = PacketOutboundActor(
|
let packetOutboundActor = PacketOutboundActor(
|
||||||
@ -122,6 +121,7 @@ actor SDLContextActor {
|
|||||||
self.dnsCloudService = dnsCloudService
|
self.dnsCloudService = dnsCloudService
|
||||||
self.dnsLocalService = dnsLocalService
|
self.dnsLocalService = dnsLocalService
|
||||||
self.superService = superService
|
self.superService = superService
|
||||||
|
self.superControlPlane = superControlPlane
|
||||||
self.udpHoleService = udpHoleService
|
self.udpHoleService = udpHoleService
|
||||||
self.udpHoleV6Service = udpHoleV6Service
|
self.udpHoleV6Service = udpHoleV6Service
|
||||||
self.packetOutboundActor = packetOutboundActor
|
self.packetOutboundActor = packetOutboundActor
|
||||||
@ -138,7 +138,17 @@ actor SDLContextActor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let rootTask = Task {
|
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
|
self.rootTask = rootTask
|
||||||
|
|
||||||
@ -163,20 +173,6 @@ actor SDLContextActor {
|
|||||||
await self.cleanupRoot()
|
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 {
|
private func runRootBody() async throws {
|
||||||
self.prepareTunnelNotifier()
|
self.prepareTunnelNotifier()
|
||||||
|
|
||||||
@ -188,8 +184,13 @@ actor SDLContextActor {
|
|||||||
await self?.handleDNSEvent(event)
|
await self?.handleDNSEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
await self.superService.updateMessageHandler { [weak self] message in
|
await self.superControlPlane.updateDecisionHandler { [weak self] decision in
|
||||||
await self?.handleSuperMessage(message: message)
|
await self?.handleSuperDecision(decision)
|
||||||
|
}
|
||||||
|
|
||||||
|
let superControlPlane = self.superControlPlane
|
||||||
|
await self.superService.updateMessageHandler { message in
|
||||||
|
await superControlPlane.handle(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
let packetInboundActor = self.packetInboundActor
|
let packetInboundActor = self.packetInboundActor
|
||||||
@ -392,8 +393,8 @@ actor SDLContextActor {
|
|||||||
await self.dnsLocalService.stop()
|
await self.dnsLocalService.stop()
|
||||||
|
|
||||||
await self.superService.stop()
|
await self.superService.stop()
|
||||||
|
await self.superControlPlane.reset()
|
||||||
|
|
||||||
self.sessionToken = nil
|
|
||||||
self.dataCipher = nil
|
self.dataCipher = nil
|
||||||
self.natType = .blocked
|
self.natType = .blocked
|
||||||
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: nil)
|
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: nil)
|
||||||
@ -436,11 +437,6 @@ extension SDLContextActor {
|
|||||||
// MARK: 数据发送
|
// MARK: 数据发送
|
||||||
extension SDLContextActor {
|
extension SDLContextActor {
|
||||||
|
|
||||||
// 发送给super/stun节点的数据
|
|
||||||
private func sendSuperPacket(type: SDLPacketType, data: Data) async {
|
|
||||||
await self.sendPacket(type: type, data: data, remoteAddress: self.config.stunSocketAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发送给peer的数据
|
// 发送给peer的数据
|
||||||
private func sendPeerPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async {
|
private func sendPeerPacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) async {
|
||||||
await self.sendPacket(type: type, data: data, remoteAddress: remoteAddress)
|
await self.sendPacket(type: type, data: data, remoteAddress: remoteAddress)
|
||||||
@ -460,160 +456,64 @@ extension SDLContextActor {
|
|||||||
|
|
||||||
// MARK: 处理和Super之间的通讯
|
// MARK: 处理和Super之间的通讯
|
||||||
extension SDLContextActor {
|
extension SDLContextActor {
|
||||||
|
|
||||||
private func handleSuperMessage(message: SDLSuperMessage) async {
|
private func handleSuperDecision(_ decision: SuperDecision) async {
|
||||||
switch message {
|
switch decision {
|
||||||
case .welcome(let welcome):
|
case .updateIPv6Assist(let assistInfo):
|
||||||
SDLLogger.log("[SDLContext] quic welcome: \(welcome)")
|
|
||||||
|
|
||||||
await self.stopCurrentIPv6AssistClient()
|
await self.stopCurrentIPv6AssistClient()
|
||||||
// 尝试创建v6地址的辅助探测器
|
self.ipv6AssistContinuation.yield(assistInfo)
|
||||||
if welcome.hasIpv6Assist {
|
case .completeRegistration(let cipher):
|
||||||
self.ipv6AssistContinuation.yield(welcome.ipv6Assist)
|
await self.completeSuperRegistration(cipher: cipher)
|
||||||
} else {
|
case .failTunnel(let error):
|
||||||
self.ipv6AssistContinuation.yield(nil)
|
await self.failTunnel(error)
|
||||||
}
|
case .publishTunnelEvent(let code, let message):
|
||||||
|
self.publishTunnelEvent(code: code, message: message)
|
||||||
// 注册
|
case .sendSuper(let type, let data):
|
||||||
await self.doRegisterSuper()
|
await self.superService.send(type: type, data: data)
|
||||||
SDLLogger.log("[SDLContext] quic doRegisterSuper")
|
case .sendPacket(let type, let data, let remoteAddress):
|
||||||
case .pong:
|
await self.sendPacket(type: type, data: data, remoteAddress: remoteAddress)
|
||||||
//SDLLogger.shared.log("[SDLContext] quic pong")
|
case .resolvePeerInfo(let peerInfo):
|
||||||
()
|
|
||||||
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)")
|
|
||||||
let packets = await self.puncherActor.makeRegisterPackets(peerInfo: peerInfo)
|
let packets = await self.puncherActor.makeRegisterPackets(peerInfo: peerInfo)
|
||||||
for packet in packets {
|
for packet in packets {
|
||||||
await self.sendPacket(type: .register, data: packet.data, remoteAddress: packet.remoteAddress)
|
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):
|
case .removeSession(let dstMac):
|
||||||
await self.sessionManager.removeSession(dstMac: 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:
|
case .requestExposedService:
|
||||||
await self.requestExposedService()
|
await self.requestExposedService()
|
||||||
case .shutdown(let message):
|
case .shutdown(let message):
|
||||||
self.publishTunnelEvent(message: message)
|
self.publishTunnelEvent(message: message)
|
||||||
|
|
||||||
// 报告错误并退出
|
|
||||||
let error = NSError(domain: "com.jihe.punchnet.tun", code: -2)
|
let error = NSError(domain: "com.jihe.punchnet.tun", code: -2)
|
||||||
self.provider.cancelTunnelWithError(error)
|
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 {
|
private func completeSuperRegistration(cipher: CCDataCipher) async {
|
||||||
// 注册
|
self.dataCipher = cipher
|
||||||
var registerSuper = SDLRegisterSuper()
|
await self.packetOutboundActor.updateRuntime(config: self.config, dataCipher: cipher)
|
||||||
registerSuper.clientID = self.config.clientId
|
await self.packetInboundActor.updateRuntime(config: self.config, dataCipher: cipher)
|
||||||
registerSuper.networkID = self.config.networkAddress.networkId
|
|
||||||
registerSuper.mac = self.config.networkAddress.mac
|
do {
|
||||||
registerSuper.ip = self.config.networkAddress.ip
|
try await self.tunNetworkManager.apply(settings: .init(config: self.config), dnsServer: DNSHelper.dnsServer)
|
||||||
registerSuper.maskLen = UInt32(self.config.networkAddress.maskLen)
|
SDLLogger.log("[SDLContext] setNetworkSettings successed")
|
||||||
registerSuper.hostname = self.config.hostname
|
await self.readySignal.succeed(())
|
||||||
registerSuper.pubKey = self.rsaCipher.pubKey
|
} catch {
|
||||||
registerSuper.accessToken = self.config.accessToken
|
SDLLogger.log("[SDLContext] setTunnelNetworkSettings get error: \(error)")
|
||||||
|
await self.failTunnel(error)
|
||||||
if let registerSuperData = try? registerSuper.serializedData() {
|
|
||||||
SDLLogger.log("[SDLContext] will send register super")
|
|
||||||
await self.superService.send(type: .registerSuper, data: registerSuperData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func failTunnel(_ error: Error) async {
|
||||||
|
await self.readySignal.fail(error)
|
||||||
|
self.provider.cancelTunnelWithError(error)
|
||||||
|
}
|
||||||
|
|
||||||
private func requestExposedService() async {
|
private func requestExposedService() async {
|
||||||
guard let requestData = await self.policyService.makeExposedServiceRequest() else {
|
guard let requestData = await self.policyService.makeExposedServiceRequest() else {
|
||||||
return
|
return
|
||||||
@ -735,29 +635,7 @@ extension SDLContextActor {
|
|||||||
SDLLogger.log("[SDLContext] probe ipv6 address: empty")
|
SDLLogger.log("[SDLContext] probe ipv6 address: empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
await self.sendStunRequest(v6Info: probeReply?.v6Info)
|
await self.superControlPlane.sendStunRequest(natType: self.natType, 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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