fix udp actor

This commit is contained in:
anlicheng 2026-01-07 16:29:03 +08:00
parent 4e0247f648
commit b208dc7859
2 changed files with 32 additions and 64 deletions

View File

@ -50,7 +50,6 @@ public class SDLContextNew {
//
var udpHoleActor: SDLUDPHoleActor?
var superClientActor: SDLSuperClientActor?
var providerActor: SDLTunnelProviderActor
// dnsclient
@ -189,8 +188,10 @@ public class SDLContextNew {
group.addTask {
while !Task.isCancelled {
try Task.checkCancellation()
try await Task.sleep(nanoseconds: 5 * 1_000_000_000)
try Task.checkCancellation()
if let udpHoleActor = self.udpHoleActor {
let cookie = await udpHoleActor.getCookieId()
var stunRequest = SDLStunRequest()
@ -202,7 +203,7 @@ public class SDLContextNew {
stunRequest.natType = UInt32(self.natType.rawValue)
let remoteAddress = self.config.stunSocketAddress
await udpHoleActor.stunRequest(request: stunRequest, remoteAddress: remoteAddress)
await udpHoleActor.send(type: .stunRequest, data: try stunRequest.serializedData(), remoteAddress: remoteAddress)
self.lastCookie = cookie
}
}
@ -211,6 +212,7 @@ public class SDLContextNew {
group.addTask {
if let eventFlow = self.udpHoleActor?.eventFlow {
for try await event in eventFlow {
try Task.checkCancellation()
try await self.handleUDPEvent(event: event)
}
}
@ -304,7 +306,7 @@ public class SDLContextNew {
registerSuper.token = self.config.token
registerSuper.networkCode = self.config.networkCode
registerSuper.hostname = self.config.hostname
guard let message = try await self.superClientActor?.registerSuper(register: registerSuper).get() else {
guard let message = try await self.superClientActor?.request(type: .registerSuper, data: try registerSuper.serializedData()).get() else {
return
}
@ -373,7 +375,7 @@ public class SDLContextNew {
register.networkID = self.devAddr.networkID
register.srcMac = self.devAddr.mac
register.dstMac = sendRegisterEvent.dstMac
await self.udpHoleActor?.sendRegister(register: register, remoteAddress: remoteAddress)
await self.udpHoleActor?.send(type: .register, data: try register.serializedData(), remoteAddress: remoteAddress)
}
case .networkShutdown(let shutdownEvent):
@ -402,8 +404,7 @@ public class SDLContextNew {
var commandAck = SDLCommandAck()
commandAck.status = true
await self.superClientActor?.commandAck(packetId: packetId, ack: commandAck)
await self.superClientActor?.send(type: .commandAck, packetId: packetId, data: try commandAck.serializedData())
}
}
@ -428,8 +429,7 @@ public class SDLContextNew {
registerAck.srcMac = self.devAddr.mac
registerAck.dstMac = register.srcMac
await self.udpHoleActor?.sendRegisterAck(registerAck: registerAck, remoteAddress: remoteAddress)
await self.udpHoleActor?.send(type: .registerAck, data: try registerAck.serializedData(), remoteAddress: remoteAddress)
// , super-nodenatudpnat
let session = Session(dstMac: register.srcMac, natAddress: remoteAddress)
await self.sessionManager.addSession(session: session)
@ -591,13 +591,13 @@ public class SDLContextNew {
// session
if let session = await self.sessionManager.getSession(toAddress: dstMac) {
self.logger.log("[SDLContext] send packet by session: \(session)", level: .debug)
await self.udpHoleActor?.sendPacket(data: dataPacket, remoteAddress: session.natAddress)
await self.udpHoleActor?.send(type: .data, data: try! dataPacket.serializedData(), remoteAddress: session.natAddress)
await self.flowTracer.inc(num: data.count, type: .p2p)
}
else {
// super_node
let superAddress = self.config.stunSocketAddress
await self.udpHoleActor?.sendPacket(data: dataPacket, remoteAddress: superAddress)
await self.udpHoleActor?.send(type: .data, data: try! dataPacket.serializedData(), remoteAddress: superAddress)
//
await self.flowTracer.inc(num: data.count, type: .forward)
@ -634,7 +634,7 @@ public class SDLContextNew {
var queryInfo = SDLQueryInfo()
queryInfo.dstMac = request.dstMac
guard let message = try? await self.superClientActor?.queryInfo(query: queryInfo).get() else {
guard let message = try? await self.superClientActor?.request(type: .queryInfo, data: try queryInfo.serializedData()).get() else {
return
}
@ -650,7 +650,7 @@ public class SDLContextNew {
register.srcMac = request.srcMac
register.dstMac = request.dstMac
await self.udpHoleActor?.sendRegister(register: register, remoteAddress: remoteAddress)
await self.udpHoleActor?.send(type: .register, data: try! register.serializedData(), remoteAddress: remoteAddress)
} else {
self.logger.log("[SDLContext] hole sock address is invalid: \(peerInfo.v4Info)", level: .warning)
}

View File

@ -10,7 +10,6 @@ import NIOCore
import NIOPosix
// sn-server
@available(macOS 14, *)
actor SDLUDPHoleActor {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
private let asyncChannel: NIOAsyncChannel<AddressedEnvelope<ByteBuffer>, AddressedEnvelope<ByteBuffer>>
@ -136,30 +135,24 @@ actor SDLUDPHoleActor {
return self.cookieGenerator.nextId()
}
// MARK: super_node apis
func stunRequest(request: SDLStunRequest, remoteAddress: SocketAddress) {
self.send(remoteAddress: remoteAddress, type: .stunRequest, data: try! request.serializedData())
}
// tun
func stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int = 5) async throws -> SDLStunProbeReply {
return try await self._stunProbe(remoteAddress: remoteAddress, attr: attr, timeout: timeout).get()
}
private func _stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int) -> EventLoopFuture<SDLStunProbeReply> {
let cookie = self.cookieGenerator.nextId()
var stunProbe = SDLStunProbe()
stunProbe.cookie = cookie
stunProbe.attr = UInt32(attr.rawValue)
self.send(remoteAddress: remoteAddress, type: .stunProbe, data: try! stunProbe.serializedData())
self.logger.log("[SDLUDPHole] stunProbe: \(remoteAddress)", level: .debug)
let promise = self.asyncChannel.channel.eventLoop.makePromise(of: SDLStunProbeReply.self)
self.promises[cookie] = promise
return promise.futureResult
}
// // tun
// func stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int = 5) async throws -> SDLStunProbeReply {
// return try await self._stunProbe(remoteAddress: remoteAddress, attr: attr, timeout: timeout).get()
// }
//
// private func _stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int) -> EventLoopFuture<SDLStunProbeReply> {
// let cookie = self.cookieGenerator.nextId()
// var stunProbe = SDLStunProbe()
// stunProbe.cookie = cookie
// stunProbe.attr = UInt32(attr.rawValue)
// self.send( type: .stunProbe, data: try! stunProbe.serializedData(), remoteAddress: remoteAddress)
// self.logger.log("[SDLUDPHole] stunProbe: \(remoteAddress)", level: .debug)
//
// let promise = self.asyncChannel.channel.eventLoop.makePromise(of: SDLStunProbeReply.self)
// self.promises[cookie] = promise
//
// return promise.futureResult
// }
private func trigger(probeReply: SDLStunProbeReply) {
let id = probeReply.cookie
@ -173,33 +166,8 @@ actor SDLUDPHoleActor {
}
// MARK: client-client apis
// session
func sendPacket(data: SDLData, remoteAddress: SocketAddress) {
if let packet = try? data.serializedData() {
self.logger.log("[SDLUDPHole] sendPacket: \(remoteAddress), count: \(packet.count)", level: .debug)
self.send(remoteAddress: remoteAddress, type: .data, data: packet)
}
}
// register
func sendRegister(register: SDLRegister, remoteAddress: SocketAddress) {
if let packet = try? register.serializedData() {
self.logger.log("[SDLUDPHole] SendRegister: \(remoteAddress), src_mac: \(LayerPacket.MacAddress.description(data: register.srcMac)), dst_mac: \(LayerPacket.MacAddress.description(data: register.dstMac))", level: .debug)
self.send(remoteAddress: remoteAddress, type: .register, data: packet)
}
}
// registerAck
func sendRegisterAck(registerAck: SDLRegisterAck, remoteAddress: SocketAddress) {
if let packet = try? registerAck.serializedData() {
self.logger.log("[SDLUDPHole] SendRegisterAck: \(remoteAddress), \(registerAck)", level: .debug)
self.send(remoteAddress: remoteAddress, type: .registerAck, data: packet)
}
}
//
private func send(remoteAddress: SocketAddress, type: SDLPacketType, data: Data) {
func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) {
let message = UDPMessage(remoteAddress: remoteAddress, type: type, data: data)
self.writeContinuation.yield(message)
}