// // SDLConfiguration.swift // sdlan // // Created by 安礼成 on 2025/7/14. // import Foundation import NIOCore // 配置项目 public class SDLConfiguration { // 网络地址信息 public struct NetworkAddress { public let networkId: UInt32 public let ip: UInt32 public let maskLen: UInt8 public let mac: Data public let networkDomain: String // ip地址 var ipAddress: String { return SDLUtil.int32ToIp(self.ip) } // 掩码 var maskAddress: String { let len0 = 32 - maskLen let num: UInt32 = (0xFFFFFFFF >> len0) << len0 return SDLUtil.int32ToIp(num) } // 网络地址 var netAddress: String { let len0 = 32 - maskLen let mask: UInt32 = (0xFFFFFFFF >> len0) << len0 return SDLUtil.int32ToIp(self.ip & mask) } } // 网络出口 public struct ExitNode { let exitNodeIp: UInt32 } // 当前的客户端版本 let version: Int let serverHost: String let serverIp: String let stunServers: [String] let noticePort: Int lazy var stunSocketAddress: SocketAddress = { let stunServer = stunServers[0] return try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365) }() // 网络探测地址信息 lazy var stunProbeSocketAddressArray: [[SocketAddress]] = { return stunServers.map { stunServer in [ try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1365), try! SocketAddress.makeAddressResolvingHost(stunServer, port: 1366) ] } }() let clientId: String let networkAddress: NetworkAddress let hostname: String let accessToken: String let identityId: UInt32 var exitNode: ExitNode? public init(version: Int, serverHost: String, serverIp: String, stunServers: [String], clientId: String, networkAddress: NetworkAddress, hostname: String, noticePort: Int, accessToken: String, identityId: UInt32, exitNode: ExitNode?) { self.version = version self.serverHost = serverHost self.serverIp = serverIp self.stunServers = stunServers self.clientId = clientId self.networkAddress = networkAddress self.noticePort = noticePort self.accessToken = accessToken self.identityId = identityId self.hostname = hostname self.exitNode = exitNode } } // 解析配置文件 extension SDLConfiguration { static func parse(options: [String: NSObject]) async -> SDLConfiguration? { guard let version = options["version"] as? Int, let serverHost = options["server_host"] as? String, let stunAssistHost = options["stun_assist_host"] as? String, let noticePort = options["notice_port"] as? Int, let accessToken = options["access_token"] as? String, let identityId = options["identity_id"] as? UInt32, let clientId = options["client_id"] as? String, let hostname = options["hostname"] as? String, let networkAddressDict = options["network_address"] as? [String: NSObject] else { return nil } guard let networkAddress = parseNetworkAddress(networkAddressDict) else { return nil } // 解析dns域名所在的服务器地址 guard let serverIp = await SDLUtil.resolveHostname(host: serverHost) else { return nil } // 网络出口配置是可选的 var exitNode: ExitNode? = nil if let exitNodeIpStr = options["exit_node_ip"] as? String, let exitNodeIp = SDLUtil.ipv4StrToInt32(exitNodeIpStr) { exitNode = .init(exitNodeIp: exitNodeIp) } return SDLConfiguration(version: version, serverHost: serverHost, serverIp: serverIp, stunServers: [serverHost, stunAssistHost], clientId: clientId, networkAddress: networkAddress, hostname: hostname, noticePort: noticePort, accessToken: accessToken, identityId: identityId, exitNode: exitNode) } 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) } }