// // PacketTunnelProvider.swift // punchnet // // Created by 安礼成 on 2025/8/3. // import NetworkExtension enum TunnelError: Error { case invalidConfiguration case invalidContext } class PacketTunnelProvider: NEPacketTunnelProvider { var contextActor: SDLContextActor? private var rootTask: Task? override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { SDLTunnelAppNotifier.shared.clear() // 如果当前在运行状态,不允许重复请求 guard self.contextActor == nil else { completionHandler(TunnelError.invalidContext) return } // 加密算法 let rsaCipher = try! CCRSACipher(keySize: 1024) self.rootTask = Task { // host: "192.168.0.101", port: 1265 guard let options, let config = await SDLConfiguration.parse(options: options) else { completionHandler(TunnelError.invalidConfiguration) return } self.contextActor = SDLContextActor(provider: self, config: config, rsaCipher: rsaCipher) await self.contextActor?.start() try await self.contextActor?.waitForReady() completionHandler(nil) } } override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { // Add code here to start the process of stopping the tunnel. Task { await self.contextActor?.stop() self.contextActor = nil self.rootTask?.cancel() self.rootTask = nil completionHandler() } } override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) { // Add code here to handle the message. Task { if let message = try? NEMessage(serializedBytes: messageData) { switch message.message { case .exitNodeIpChanged(let exitNodeIpChanged): let exitNodeIp = exitNodeIpChanged.ip do { try await self.contextActor?.updateExitNode(exitNodeIp: exitNodeIp) var reply = NEReply() reply.code = 0 reply.message = "操作成功" completionHandler?(try reply.serializedData()) } catch let err { var reply = NEReply() reply.code = 1 reply.message = err.localizedDescription completionHandler?(try reply.serializedData()) } case .none: () } } } } override func sleep(completionHandler: @escaping () -> Void) { // Add code here to get ready to sleep. completionHandler() } override func wake() { // Add code here to wake up. } } // 获取物理网卡ip地址 extension PacketTunnelProvider { public static var viaInterface: NetworkInterface? = { let interfaces = NetworkInterfaceManager.getInterfaces() return interfaces.first {$0.name == "en0"} }() }