This commit is contained in:
anlicheng 2026-04-14 16:49:03 +08:00
parent 6b7e02a65b
commit 969921c438

View File

@ -50,6 +50,7 @@ actor SDLContextActor {
private var udpHoleWorkers: [Task<Void, Never>]? private var udpHoleWorkers: [Task<Void, Never>]?
private var udpHoleV6: SDLUDPHoleV6? private var udpHoleV6: SDLUDPHoleV6?
private var udpHoleV6Workers: [Task<Void, Never>]? private var udpHoleV6Workers: [Task<Void, Never>]?
private var udpHoleV6LocalAddress: SocketAddress?
// dnsclient // dnsclient
private var dnsClient: DNSCloudClient? private var dnsClient: DNSCloudClient?
@ -213,7 +214,7 @@ actor SDLContextActor {
await self.handleRegisterSuperNak(nakPacket: registerSuperNak) await 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)")
await self.puncherActor.handlePeerInfo(using: self.udpHole, peerInfo: peerInfo) await self.puncherActor.handlePeerInfo(using: self.udpHole, udpHoleV6: self.udpHoleV6, peerInfo: peerInfo)
case .event(let event): case .event(let event):
await self.handleEvent(event: event) await self.handleEvent(event: event)
case .policyReponse(let policyResponse): case .policyReponse(let policyResponse):
@ -360,7 +361,6 @@ actor SDLContextActor {
() ()
} }
} }
SDLLogger.log("[SDLContext] udp signalTask cancel")
} }
self.udpHole = udpHole self.udpHole = udpHole
@ -381,8 +381,29 @@ actor SDLContextActor {
let localAddress = try udpHoleV6.start() let localAddress = try udpHoleV6.start()
SDLLogger.log("[SDLContext] udpHoleV6 started, on address: \(localAddress)") SDLLogger.log("[SDLContext] udpHoleV6 started, on address: \(localAddress)")
// ip register:registerAck | data
let messageTask = Task.detached {
for await (remoteAddress, message) in udpHoleV6.messageStream {
if Task.isCancelled {
break
}
switch message {
case .register(let register):
try? await self.handleRegister(remoteAddress: remoteAddress, register: register)
case .registerAck(let registerAck):
await self.handleRegisterAck(remoteAddress: remoteAddress, registerAck: registerAck)
case .data(let data):
try? await self.handleHoleData(data: data)
default:
()
}
}
}
self.udpHoleV6 = udpHoleV6 self.udpHoleV6 = udpHoleV6
self.udpHoleV6Workers = [] self.udpHoleV6LocalAddress = localAddress
self.udpHoleV6Workers = [messageTask]
return udpHoleV6 return udpHoleV6
} }
@ -405,6 +426,7 @@ actor SDLContextActor {
self.udpHoleV6Workers = nil self.udpHoleV6Workers = nil
self.udpHoleV6?.stop() self.udpHoleV6?.stop()
self.udpHoleV6 = nil self.udpHoleV6 = nil
self.udpHoleV6LocalAddress = nil
self.quicWorker?.cancel() self.quicWorker?.cancel()
self.quicWorker = nil self.quicWorker = nil
@ -494,10 +516,13 @@ actor SDLContextActor {
stunRequest.mac = self.config.networkAddress.mac stunRequest.mac = self.config.networkAddress.mac
stunRequest.natType = UInt32(self.natType.rawValue) stunRequest.natType = UInt32(self.natType.rawValue)
stunRequest.sessionToken = sessionToken stunRequest.sessionToken = sessionToken
if let v6Info = self.makeUDPHoleV6Info() {
stunRequest.v6Info = v6Info
}
if let stunData = try? stunRequest.serializedData() { if let stunData = try? stunRequest.serializedData() {
let remoteAddress = self.config.stunSocketAddress let remoteAddress = self.config.stunSocketAddress
self.udpHole?.send(type: .stunRequest, data: stunData, remoteAddress: remoteAddress) self.sendHolePacket(type: .stunRequest, data: stunData, remoteAddress: remoteAddress)
} }
} }
@ -574,14 +599,22 @@ actor SDLContextActor {
sessionManager.removeSession(dstMac: dstMac) sessionManager.removeSession(dstMac: dstMac)
case .sendRegister(let sendRegisterEvent): case .sendRegister(let sendRegisterEvent):
SDLLogger.log("[SDLContext] sendRegisterEvent, ip: \(sendRegisterEvent)") SDLLogger.log("[SDLContext] sendRegisterEvent, ip: \(sendRegisterEvent)")
let address = SDLUtil.int32ToIp(sendRegisterEvent.natIp) // register
if let remoteAddress = try? SocketAddress.makeAddressResolvingHost(address, port: Int(sendRegisterEvent.natPort)) { var register = SDLRegister()
// register register.networkID = self.config.networkAddress.networkId
var register = SDLRegister() register.srcMac = self.config.networkAddress.mac
register.networkID = self.config.networkAddress.networkId register.dstMac = sendRegisterEvent.dstMac
register.srcMac = self.config.networkAddress.mac let registerData = try! register.serializedData()
register.dstMac = sendRegisterEvent.dstMac
self.udpHole?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress) if sendRegisterEvent.natIp > 0 && sendRegisterEvent.natPort > 0 {
let address = SDLUtil.int32ToIp(sendRegisterEvent.natIp)
if let remoteAddress = try? SocketAddress.makeAddressResolvingHost(address, port: Int(sendRegisterEvent.natPort)) {
self.sendHolePacket(type: .register, data: registerData, remoteAddress: remoteAddress)
}
}
if sendRegisterEvent.hasV6Info, let remoteAddress = try? await sendRegisterEvent.v6Info.socketAddress() {
self.sendHolePacket(type: .register, data: registerData, remoteAddress: remoteAddress)
} }
case .shutdown(let shutdownEvent): case .shutdown(let shutdownEvent):
let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message) let alertNotice = NoticeMessage.alert(alert: shutdownEvent.message)
@ -626,7 +659,7 @@ actor SDLContextActor {
registerAck.srcMac = networkAddr.mac registerAck.srcMac = networkAddr.mac
registerAck.dstMac = register.srcMac registerAck.dstMac = register.srcMac
self.udpHole?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress) self.sendHolePacket(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress)
// , super-nodenatudpnat // , super-nodenatudpnat
let session = Session(dstMac: register.srcMac, natAddress: remoteAddress) let session = Session(dstMac: register.srcMac, natAddress: remoteAddress)
self.sessionManager.addSession(session: session) self.sessionManager.addSession(session: session)
@ -741,20 +774,6 @@ actor SDLContextActor {
return false return false
} }
//
// public func flowReportTask() {
// Task {
// //
// self.flowTracerCancel = Timer.publish(every: 60.0, on: .main, in: .common).autoconnect()
// .sink { _ in
// Task {
// let (forwardNum, p2pNum, inboundNum) = await self.flowTracer.reset()
// await self.superClient?.flowReport(forwardNum: forwardNum, p2pNum: p2pNum, inboundNum: inboundNum)
// }
// }
// }
// }
// , 线packetFlow // , 线packetFlow
private func startReader() { private func startReader() {
// //
@ -874,7 +893,9 @@ actor SDLContextActor {
let networkAddr = self.config.networkAddress let networkAddr = self.config.networkAddress
// 2 // 2
let layerPacket = LayerPacket(dstMac: dstMac, srcMac: networkAddr.mac, type: type, data: data) let layerPacket = LayerPacket(dstMac: dstMac, srcMac: networkAddr.mac, type: type, data: data)
guard let udpHole = self.udpHole, let dataCipher = self.dataCipher, let encodedPacket = try? dataCipher.encrypt(plainText: layerPacket.marshal()) else { guard (self.udpHole != nil || self.udpHoleV6 != nil),
let dataCipher = self.dataCipher,
let encodedPacket = try? dataCipher.encrypt(plainText: layerPacket.marshal()) else {
return return
} }
@ -891,18 +912,18 @@ actor SDLContextActor {
// 广 // 广
if ARPPacket.isBroadcastMac(dstMac) { if ARPPacket.isBroadcastMac(dstMac) {
// super_node // super_node
udpHole.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) self.sendHolePacket(type: .data, data: data, remoteAddress: self.config.stunSocketAddress)
} }
else { else {
// session // session
if let session = self.sessionManager.getSession(toAddress: dstMac) { if let session = self.sessionManager.getSession(toAddress: dstMac) {
SDLLogger.log("[SDLContext] step 5 send packet by session: \(session)", for: .trace) SDLLogger.log("[SDLContext] step 5 send packet by session: \(session)", for: .trace)
udpHole.send(type: .data, data: data, remoteAddress: session.natAddress) self.sendHolePacket(type: .data, data: data, remoteAddress: session.natAddress)
self.flowTracer.inc(num: data.count, type: .p2p) self.flowTracer.inc(num: data.count, type: .p2p)
} }
else { else {
// super_node // super_node
udpHole.send(type: .data, data: data, remoteAddress: self.config.stunSocketAddress) self.sendHolePacket(type: .data, data: data, remoteAddress: self.config.stunSocketAddress)
SDLLogger.log("[SDLContext] step 5 send packet by super: \(self.config.stunSocketAddress)", for: .trace) SDLLogger.log("[SDLContext] step 5 send packet by super: \(self.config.stunSocketAddress)", for: .trace)
// //
self.flowTracer.inc(num: data.count, type: .forward) self.flowTracer.inc(num: data.count, type: .forward)
@ -965,6 +986,43 @@ actor SDLContextActor {
SDLLogger.log("[SDLContext] nat_type is: \(natType)") SDLLogger.log("[SDLContext] nat_type is: \(natType)")
} }
// hole
private func sendHolePacket(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) {
switch remoteAddress {
case .v4:
self.udpHole?.send(type: type, data: data, remoteAddress: remoteAddress)
case .v6:
self.udpHoleV6?.send(type: type, data: data, remoteAddress: remoteAddress)
default:
SDLLogger.log("[SDLContext] unsupported remoteAddress: \(remoteAddress)", for: .debug)
}
}
private func makeUDPHoleV6Info() -> SDLV6Info? {
guard let port = self.udpHoleV6LocalAddress?.port else {
return nil
}
let interfaces = NetworkInterfaceManager.getInterfaces()
let interface = interfaces.first { interface in
interface.ip.contains(":")
&& !interface.name.hasPrefix("utun")
&& !interface.ip.hasPrefix("fe80:")
&& interface.ip != "::"
}
guard let interface,
let ipData = SDLUtil.ipv6StrToData(interface.ip) else {
return nil
}
var v6Info = SDLV6Info()
v6Info.port = UInt32(port)
v6Info.v6 = ipData
return v6Info
}
private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> { private func spawnLoop(_ body: @escaping () async throws -> Void) -> Task<Void, Never> {
return Task.detached { return Task.detached {
while !Task.isCancelled { while !Task.isCancelled {
@ -1037,6 +1095,7 @@ actor SDLContextActor {
deinit { deinit {
self.udpHole = nil self.udpHole = nil
self.udpHoleV6 = nil self.udpHoleV6 = nil
self.udpHoleV6LocalAddress = nil
self.dnsClient = nil self.dnsClient = nil
} }
} }