punchnet-macos/Tun/Punchnet/SDLConfiguration.swift

156 lines
5.0 KiB
Swift

//
// 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 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,
stunServers: [String],
clientId: String,
networkAddress: NetworkAddress,
hostname: String,
noticePort: Int,
accessToken: String,
identityId: UInt32,
exitNode: ExitNode?) {
self.version = version
self.serverHost = serverHost
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]) -> 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
}
//
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,
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)
}
}