// // SDLContext.swift // Tun // // Created by 安礼成 on 2024/2/29. // import Foundation import NetworkExtension import NIOCore import Combine // 上下文环境变量,全局共享 /* 1. 处理rsa的加解密逻辑 */ actor SDLTunnelProviderActor { // 路由信息 struct Route { let dstAddress: String let subnetMask: String var debugInfo: String { return "\(dstAddress):\(subnetMask)" } } // 数据包读取任务 private var readTask: Task<(), Never>? let provider: NEPacketTunnelProvider let logger: SDLLogger public init(provider: NEPacketTunnelProvider, logger: SDLLogger) { self.logger = logger self.provider = provider } func writePackets(packets: [NEPacket]) { //let packet = NEPacket(data: ipPacket.data, protocolFamily: 2) self.provider.packetFlow.writePacketObjects(packets) } // 网络改变时需要重新配置网络信息 func setNetworkSettings(devAddr: SDLDevAddr, dnsServer: String) async throws { let netAddress = SDLNetAddress(ip: devAddr.netAddr, maskLen: UInt8(devAddr.netBitLen)) let routes = [ Route(dstAddress: netAddress.networkAddress, subnetMask: netAddress.maskAddress), Route(dstAddress: dnsServer, subnetMask: "255.255.255.255") ] // Add code here to start the process of connecting the tunnel. let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8") networkSettings.mtu = 1460 // 设置网卡的DNS解析 let networkDomain = devAddr.networkDomain let dnsSettings = NEDNSSettings(servers: [dnsServer]) dnsSettings.searchDomains = [networkDomain] dnsSettings.matchDomains = [networkDomain] dnsSettings.matchDomainsNoSearch = false networkSettings.dnsSettings = dnsSettings self.logger.log("[SDLContext] Tun started at network ip: \(netAddress.ipAddress), mask: \(netAddress.maskAddress)", level: .info) let ipv4Settings = NEIPv4Settings(addresses: [netAddress.ipAddress], subnetMasks: [netAddress.maskAddress]) // 设置路由表 //NEIPv4Route.default() ipv4Settings.includedRoutes = routes.map { route in NEIPv4Route(destinationAddress: route.dstAddress, subnetMask: route.subnetMask) } networkSettings.ipv4Settings = ipv4Settings // 网卡配置设置必须成功 try await self.provider.setTunnelNetworkSettings(networkSettings) } // 开始读取数据, 用单独的线程处理packetFlow func readPackets() async -> [Data] { let (packets, numbers) = await self.provider.packetFlow.readPackets() return zip(packets, numbers).compactMap { (data, number) in return number == 2 ? data : nil } } }