// // SDLConfiguration.swift // sdlan // // Created by 安礼成 on 2025/7/14. // import Foundation import NIOCore // 配置项目 public class SDLConfiguration { public struct StunServer { public let host: String public let ports: [Int] public init(host: String, ports: [Int]) { self.host = host self.ports = ports } } public struct NetworkAddress { public let networkId: UInt32 public let ip: UInt32 public let maskLen: UInt8 public let mac: Data public let networkDomain: String } // 当前的客户端版本 let version: UInt8 // 安装渠道 let installedChannel: String let superHost: String let superPort: Int let stunServers: [StunServer] let remoteDnsServer: String let noticePort: Int lazy var stunSocketAddress: SocketAddress = { let stunServer = stunServers[0] return try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]) }() // 网络探测地址信息 lazy var stunProbeSocketAddressArray: [[SocketAddress]] = { return stunServers.map { stunServer in [ try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[0]), try! SocketAddress.makeAddressResolvingHost(stunServer.host, port: stunServer.ports[1]) ] } }() let clientId: String let networkAddress: NetworkAddress let hostname: String let accessToken: String public init(version: UInt8, installedChannel: String, superHost: String, superPort: Int, stunServers: [StunServer], clientId: String, networkAddress: NetworkAddress, hostname: String, noticePort: Int, accessToken: String, remoteDnsServer: String) { self.version = version self.installedChannel = installedChannel self.superHost = superHost self.superPort = superPort self.stunServers = stunServers self.clientId = clientId self.networkAddress = networkAddress self.noticePort = noticePort self.accessToken = accessToken self.remoteDnsServer = remoteDnsServer self.hostname = hostname } // 获取mac地址 public static func getMacAddress() -> Data { let key = "gMacAddress2" let userDefaults = UserDefaults.standard if let mac = userDefaults.value(forKey: key) as? Data { return mac } else { let mac = generateMacAddress() userDefaults.setValue(mac, forKey: key) return mac } } // 随机生成mac地址 private static func generateMacAddress() -> Data { var macAddress = [UInt8](repeating: 0, count: 6) for i in 0..<6 { macAddress[i] = UInt8.random(in: 0...255) } return Data(macAddress) } } // 解析配置文件 extension SDLConfiguration { static func parse(options: [String: NSObject]) -> SDLConfiguration? { guard let installed_channel = options["installed_channel"] as? String, let superIp = options["super_ip"] as? String, let superPort = options["super_port"] as? Int, let stunServersStr = options["stun_servers"] as? String, let noticePort = options["notice_port"] as? Int, let token = options["token"] as? String, let accessToken = options["access_token"] as? String, let clientId = options["client_id"] as? String, let remoteDnsServer = options["remote_dns_server"] as? String, let hostname = options["hostname"] as? String, let networkAddressDict = options["networkAddress"] as? [String: NSObject] else { return nil } guard let stunServers = parseStunServers(stunServersStr: stunServersStr), stunServers.count >= 2 else { NSLog("stunServers配置错误") return nil } guard let networkAddress = parseNetworkAddress(networkAddressDict) else { return nil } NSLog("[PacketTunnelProvider] client_id: \(clientId), token: \(token)") return SDLConfiguration(version: 1, installedChannel: installed_channel, superHost: superIp, superPort: superPort, stunServers: stunServers, clientId: clientId, networkAddress: networkAddress, hostname: hostname, noticePort: noticePort, accessToken: accessToken, remoteDnsServer: remoteDnsServer) } private static func parseStunServers(stunServersStr: String) -> [SDLConfiguration.StunServer]? { let stunServers = stunServersStr.split(separator: ";").compactMap { server -> SDLConfiguration.StunServer? in let parts = server.split(separator: ":", maxSplits: 2) guard parts.count == 2 else { return nil } let ports = parts[1].split(separator: ",", maxSplits: 2) guard ports.count == 2, let port1 = Int(String(ports[0])), let port2 = Int(String(ports[1])) else { return nil } return .init(host: String(parts[0]), ports: [port1, port2]) } return stunServers.count >= 2 ? stunServers : nil } private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? { guard let networkId = config["network_id"] as? UInt32, let ipStr = config["ip"] as? String, let ip = SDLUtil.ipv4StrToInt32(ipStr), let maskLen = config["mask_len"] as? UInt8, let mac = config["mac"] as? Data, let networkDomain = config["network_domain"] as? String else { return nil } return .init(networkId: networkId, ip: ip, maskLen: maskLen, mac: mac, networkDomain: networkDomain) } }