From b208dc7859fc8b190454aeee44d98618667b2637 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Wed, 7 Jan 2026 16:29:03 +0800 Subject: [PATCH] fix udp actor --- Tun/Punchnet/Actors/SDLContextNew.swift | 26 ++++----- Tun/Punchnet/Actors/SDLUDPHoleActor.swift | 70 ++++++----------------- 2 files changed, 32 insertions(+), 64 deletions(-) diff --git a/Tun/Punchnet/Actors/SDLContextNew.swift b/Tun/Punchnet/Actors/SDLContextNew.swift index d9b809e..eaa9f3a 100644 --- a/Tun/Punchnet/Actors/SDLContextNew.swift +++ b/Tun/Punchnet/Actors/SDLContextNew.swift @@ -50,7 +50,6 @@ public class SDLContextNew { // 依赖的变量 var udpHoleActor: SDLUDPHoleActor? var superClientActor: SDLSuperClientActor? - var providerActor: SDLTunnelProviderActor // dns的client对象 @@ -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-node查询到的nat地址不一定靠谱,需要通过udp包的来源地址作为nat地址 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) } diff --git a/Tun/Punchnet/Actors/SDLUDPHoleActor.swift b/Tun/Punchnet/Actors/SDLUDPHoleActor.swift index d08bad6..667c313 100644 --- a/Tun/Punchnet/Actors/SDLUDPHoleActor.swift +++ b/Tun/Punchnet/Actors/SDLUDPHoleActor.swift @@ -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> @@ -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 { - 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 { +// 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) }