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

View File

@ -10,7 +10,6 @@ import NIOCore
import NIOPosix import NIOPosix
// sn-server // sn-server
@available(macOS 14, *)
actor SDLUDPHoleActor { actor SDLUDPHoleActor {
private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
private let asyncChannel: NIOAsyncChannel<AddressedEnvelope<ByteBuffer>, AddressedEnvelope<ByteBuffer>> private let asyncChannel: NIOAsyncChannel<AddressedEnvelope<ByteBuffer>, AddressedEnvelope<ByteBuffer>>
@ -136,30 +135,24 @@ actor SDLUDPHoleActor {
return self.cookieGenerator.nextId() return self.cookieGenerator.nextId()
} }
// MARK: super_node apis // // tun
// func stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int = 5) async throws -> SDLStunProbeReply {
func stunRequest(request: SDLStunRequest, remoteAddress: SocketAddress) { // return try await self._stunProbe(remoteAddress: remoteAddress, attr: attr, timeout: timeout).get()
self.send(remoteAddress: remoteAddress, type: .stunRequest, data: try! request.serializedData()) // }
} //
// private func _stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int) -> EventLoopFuture<SDLStunProbeReply> {
// tun // let cookie = self.cookieGenerator.nextId()
func stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int = 5) async throws -> SDLStunProbeReply { // var stunProbe = SDLStunProbe()
return try await self._stunProbe(remoteAddress: remoteAddress, attr: attr, timeout: timeout).get() // stunProbe.cookie = cookie
} // stunProbe.attr = UInt32(attr.rawValue)
// self.send( type: .stunProbe, data: try! stunProbe.serializedData(), remoteAddress: remoteAddress)
private func _stunProbe(remoteAddress: SocketAddress, attr: SDLProbeAttr = .none, timeout: Int) -> EventLoopFuture<SDLStunProbeReply> { // self.logger.log("[SDLUDPHole] stunProbe: \(remoteAddress)", level: .debug)
let cookie = self.cookieGenerator.nextId() //
var stunProbe = SDLStunProbe() // let promise = self.asyncChannel.channel.eventLoop.makePromise(of: SDLStunProbeReply.self)
stunProbe.cookie = cookie // self.promises[cookie] = promise
stunProbe.attr = UInt32(attr.rawValue) //
self.send(remoteAddress: remoteAddress, type: .stunProbe, data: try! stunProbe.serializedData()) // return promise.futureResult
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) { private func trigger(probeReply: SDLStunProbeReply) {
let id = probeReply.cookie let id = probeReply.cookie
@ -173,33 +166,8 @@ actor SDLUDPHoleActor {
} }
// MARK: client-client apis // 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) let message = UDPMessage(remoteAddress: remoteAddress, type: type, data: data)
self.writeContinuation.yield(message) self.writeContinuation.yield(message)
} }