From 5739b59854728fbf16862344f41725310f71da3f Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Mon, 13 Apr 2026 17:57:23 +0800 Subject: [PATCH] fix udp Hole --- Tun/Punchnet/SDLUDPHole.swift | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/Tun/Punchnet/SDLUDPHole.swift b/Tun/Punchnet/SDLUDPHole.swift index 03b3983..58debb3 100644 --- a/Tun/Punchnet/SDLUDPHole.swift +++ b/Tun/Punchnet/SDLUDPHole.swift @@ -20,16 +20,16 @@ final class SDLUDPHole: ChannelInboundHandler { public let messageStream: AsyncStream<(SocketAddress, SDLHoleMessage)> private let messageContinuation: AsyncStream<(SocketAddress, SDLHoleMessage)>.Continuation - // 解决channelready的问题 - private var isReady: Bool = false private var isStopped: Bool = false // 启动函数 init() throws { - (self.messageStream, self.messageContinuation) = AsyncStream.makeStream(of: (SocketAddress, SDLHoleMessage).self, bufferingPolicy: .unbounded) + let (stream, continuation) = AsyncStream.makeStream(of: (SocketAddress, SDLHoleMessage).self, bufferingPolicy: .bufferingNewest(2048)) + self.messageStream = stream + self.messageContinuation = continuation } - func start() throws -> SocketAddress? { + func start() throws -> SocketAddress { let bootstrap = DatagramBootstrap(group: group) .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) .channelInitializer { channel in @@ -38,8 +38,9 @@ final class SDLUDPHole: ChannelInboundHandler { let channel = try bootstrap.bind(host: "0.0.0.0", port: 0).wait() self.channel = channel + precondition(channel.localAddress != nil, "UDP channel has no localAddress after bind") - return channel.localAddress + return channel.localAddress! } func waitClose() async throws { @@ -54,12 +55,14 @@ final class SDLUDPHole: ChannelInboundHandler { self.isStopped = true self.messageContinuation.finish() self.channel?.close(promise: nil) + self.channel = nil + try? self.group.syncShutdownGracefully() } // --MARK: ChannelInboundHandler delegate func channelActive(context: ChannelHandlerContext) { - self.isReady = true + } func channelRead(context: ChannelHandlerContext, data: NIOAny) { @@ -69,26 +72,27 @@ final class SDLUDPHole: ChannelInboundHandler { let remoteAddress = envelope.remoteAddress if let rawBytes = buffer.getBytes(at: buffer.readerIndex, length: buffer.readableBytes) { - SDLLogger.log("[SDLUDPHole] get raw bytes: \(rawBytes.count), from: \(remoteAddress)", for: .punchnet) + SDLLogger.log("[SDLUDPHole] get raw bytes: \(rawBytes.count), from: \(remoteAddress)", for: .debug) } do { if let message = try decode(buffer: &buffer) { self.messageContinuation.yield((remoteAddress, message)) } else { - SDLLogger.log("[SDLUDPHole] decode message, get null", for: .punchnet) + SDLLogger.log("[SDLUDPHole] decode message, get null", for: .debug) } } catch let err { - SDLLogger.log("[SDLUDPHole] decode message, get error: \(err)", for: .punchnet) + SDLLogger.log("[SDLUDPHole] decode message, get error: \(err)", for: .debug) } } func channelInactive(context: ChannelHandlerContext) { - self.messageContinuation.finish() + self.channel = nil context.close(promise: nil) } func errorCaught(context: ChannelHandlerContext, error: any Error) { + self.channel = nil context.close(promise: nil) } @@ -151,12 +155,10 @@ final class SDLUDPHole: ChannelInboundHandler { return nil } - } deinit { self.stop() - try? self.group.syncShutdownGracefully() } }