// // SDLanServer.swift // Tun // // Created by 安礼成 on 2024/1/31. // import Foundation import NIOCore import NIOPosix import SwiftProtobuf enum SDLUDPHoleError: Error { case invalidLocalAddress } // 处理和sn-server服务器之间的通讯 final class SDLUDPHole: ChannelInboundHandler { typealias InboundIn = AddressedEnvelope // 事件 enum HoleEvent { case ready case closed case errorCaught } private var isStopped: Bool = false private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) private var channel: Channel? public let messageStream: AsyncStream<(SocketAddress, SDLHoleMessage)> private let messageContinuation: AsyncStream<(SocketAddress, SDLHoleMessage)>.Continuation // 事件相关逻辑 public let eventStream: AsyncStream private let eventContinuation: AsyncStream.Continuation // 启动函数 init() throws { let (stream, continuation) = AsyncStream.makeStream(of: (SocketAddress, SDLHoleMessage).self, bufferingPolicy: .bufferingNewest(2048)) self.messageStream = stream self.messageContinuation = continuation let eventPair = AsyncStream.makeStream(of: HoleEvent.self) self.eventStream = eventPair.stream self.eventContinuation = eventPair.continuation } func start() throws -> SocketAddress { let bootstrap = DatagramBootstrap(group: group) .channelOption(ChannelOptions.socketOption(.so_reuseaddr), value: 1) .channelInitializer { channel in channel.pipeline.addHandler(self) } // 绑定到IPv4通配地址,只处理IPv4流量 let channel = try bootstrap.bind(host: "0.0.0.0", port: 0).wait() guard let localAddress = channel.localAddress else { throw SDLUDPHoleError.invalidLocalAddress } self.channel = channel eventContinuation.yield(.ready) return localAddress } // --MARK: ChannelInboundHandler delegate func channelRead(context: ChannelHandlerContext, data: NIOAny) { let envelope = unwrapInboundIn(data) var buffer = envelope.data let remoteAddress = envelope.remoteAddress let byteCount = buffer.readableBytes - buffer.readerIndex SDLLogger.log("[SDLUDPHole] get raw bytes: \(byteCount), from: \(remoteAddress)", for: .debug) do { if let message = try SDLHoleMessage.decode(buffer: &buffer) { self.messageContinuation.yield((remoteAddress, message)) } else { SDLLogger.log("[SDLUDPHole] decode message, get null", for: .debug) } } catch let err { SDLLogger.log("[SDLUDPHole] decode message, get error: \(err)", for: .debug) } } func channelInactive(context: ChannelHandlerContext) { SDLLogger.log("[SDLUDPHole] channelInactive", for: .debug) self.eventContinuation.yield(.closed) } func errorCaught(context: ChannelHandlerContext, error: any Error) { SDLLogger.log("[SDLUDPHole] channel error: \(error)", for: .debug) context.close(promise: nil) self.eventContinuation.yield(.errorCaught) } // MARK: 处理写入逻辑 func send(type: SDLPacketType, data: Data, remoteAddress: SocketAddress) { guard let channel = self.channel else { return } var buffer = channel.allocator.buffer(capacity: data.count + 1) buffer.writeBytes([type.rawValue]) buffer.writeBytes(data) let envelope = AddressedEnvelope(remoteAddress: remoteAddress, data: buffer) _ = channel.eventLoop.submit { channel.writeAndFlush(envelope, promise: nil) } } func stop() { guard !self.isStopped else { return } self.isStopped = true SDLLogger.log("[SDLUDPHole] stop", for: .debug) self.messageContinuation.finish() self.eventContinuation.finish() self.channel = nil try? self.group.syncShutdownGracefully() } }