192 lines
6.4 KiB
Swift
192 lines
6.4 KiB
Swift
//
|
|
// 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)
|
|
}
|
|
|
|
}
|