From 50dbe9ecae446d0d4d07d557231ddc63c524a83a Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Tue, 26 May 2026 00:16:34 +0800 Subject: [PATCH] =?UTF-8?q?connect=E7=BD=91=E7=BB=9C=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=EF=BC=8C=E5=A2=9E=E5=8A=A0acl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tun/Configuration/SDLConfiguration.swift | 56 +++++++++++++++++++ punchnet/App/AppContext.swift | 1 + punchnet/Core/SystemConfig.swift | 5 ++ punchnet/Shared/Models/NetworkContext.swift | 7 +++ punchnet/Shared/Networking/SDLAPIClient.swift | 2 +- 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Tun/Configuration/SDLConfiguration.swift b/Tun/Configuration/SDLConfiguration.swift index f02cfd0..b7b0862 100644 --- a/Tun/Configuration/SDLConfiguration.swift +++ b/Tun/Configuration/SDLConfiguration.swift @@ -45,6 +45,13 @@ public class SDLConfiguration { let exitNodeIp: UInt32 } + public struct ACL { + let tcpPorts: Set + let udpPorts: Set + + static let empty = ACL(tcpPorts: [], udpPorts: []) + } + // 解析的服务器地址信息 public struct ResolvedServerEndpoint: Sendable { let host: String @@ -66,6 +73,7 @@ public class SDLConfiguration { let hostname: String let accessToken: String let identityId: UInt32 + let acl: ACL var exitNode: ExitNode? @@ -77,6 +85,7 @@ public class SDLConfiguration { hostname: String, accessToken: String, identityId: UInt32, + acl: ACL, exitNode: ExitNode?) { self.version = version self.serverEndpoint = serverEndpoint @@ -92,6 +101,7 @@ public class SDLConfiguration { self.networkAddress = networkAddress self.accessToken = accessToken self.identityId = identityId + self.acl = acl self.hostname = hostname self.exitNode = exitNode } @@ -129,6 +139,7 @@ extension SDLConfiguration { guard let networkAddress = parseNetworkAddress(networkAddressDict) else { return nil } + let acl = parseACL(options["acl"]) // 网络出口配置是可选的 var exitNode: ExitNode? = nil @@ -149,6 +160,7 @@ extension SDLConfiguration { hostname: hostname, accessToken: accessToken, identityId: identityId, + acl: acl, exitNode: exitNode) } @@ -164,5 +176,49 @@ extension SDLConfiguration { return .init(networkId: networkId, ip: ip, maskLen: maskLen, mac: mac, networkDomain: networkDomain) } + + private static func parseACL(_ value: NSObject?) -> SDLConfiguration.ACL { + guard let dict = value as? [String: NSObject] else { + return .empty + } + + return .init( + tcpPorts: parsePortSet(dict["tcp"]), + udpPorts: parsePortSet(dict["udp"]) + ) + } + + private static func parsePortSet(_ value: NSObject?) -> Set { + let ports: [UInt32] + if let values = value as? [UInt32] { + ports = values + } else if let values = value as? [Int] { + ports = values.compactMap { $0 >= 0 ? UInt32($0) : nil } + } else if let values = value as? [NSNumber] { + ports = values.map(\.uint32Value) + } else if let values = value as? NSArray { + ports = values.compactMap { item in + if let value = item as? UInt32 { + return value + } + if let value = item as? Int, value >= 0 { + return UInt32(value) + } + if let value = item as? NSNumber { + return value.uint32Value + } + return nil + } + } else { + ports = [] + } + + return Set(ports.compactMap { port in + guard port > 0, port <= UInt32(UInt16.max) else { + return nil + } + return UInt16(port) + }) + } } diff --git a/punchnet/App/AppContext.swift b/punchnet/App/AppContext.swift index 36a128f..8207f14 100644 --- a/punchnet/App/AppContext.swift +++ b/punchnet/App/AppContext.swift @@ -144,6 +144,7 @@ class AppContext { accessToken: session.accessToken, identityId: context.identityId, hostname: context.hostname, + acl: context.acl, exitNodeIp: self.selectedExitNodeIp ) try await self.vpnManager.enableVpn(options: options) diff --git a/punchnet/Core/SystemConfig.swift b/punchnet/Core/SystemConfig.swift index e075727..6e2e9d4 100644 --- a/punchnet/Core/SystemConfig.swift +++ b/punchnet/Core/SystemConfig.swift @@ -36,6 +36,7 @@ struct SystemConfig { accessToken: String, identityId: UInt32, hostname: String, + acl: NetworkContext.ACL, exitNodeIp: String?) -> [String: NSObject] { // guard let serverIp = DNSResolver.resolveAddrInfos(serverHost).first, // let stunAssistIp = DNSResolver.resolveAddrInfos(stunAssistHost).first else { @@ -53,6 +54,10 @@ struct SystemConfig { "server_host": serverHost as NSObject, "stun_assist_host": stunAssistHost as NSObject, "hostname": hostname as NSObject, + "acl": [ + "tcp": acl.tcp as NSObject, + "udp": acl.udp as NSObject + ] as NSObject, "network_address": [ "network_id": networkId as NSObject, "ip": ip as NSObject, diff --git a/punchnet/Shared/Models/NetworkContext.swift b/punchnet/Shared/Models/NetworkContext.swift index 542ce8d..01660e9 100644 --- a/punchnet/Shared/Models/NetworkContext.swift +++ b/punchnet/Shared/Models/NetworkContext.swift @@ -15,6 +15,7 @@ struct NetworkContext: Codable { let identityId: UInt32 let resourceList: [Resource] let nodeList: [Node] + let acl: ACL let exitNodeList: [ExitNode] enum CodingKeys: String, CodingKey { @@ -24,6 +25,7 @@ struct NetworkContext: Codable { case identityId = "identity_id" case resourceList = "resource_list" case nodeList = "node_list" + case acl = "acl" case exitNodeList = "exit_node" } @@ -38,6 +40,11 @@ struct NetworkContext: Codable { extension NetworkContext { + struct ACL: Codable { + let tcp: [UInt32] + let udp: [UInt32] + } + struct ExitNode: Codable { let uuid = UUID().uuidString let nnid: Int diff --git a/punchnet/Shared/Networking/SDLAPIClient.swift b/punchnet/Shared/Networking/SDLAPIClient.swift index d27b58d..13c9ef6 100644 --- a/punchnet/Shared/Networking/SDLAPIClient.swift +++ b/punchnet/Shared/Networking/SDLAPIClient.swift @@ -47,7 +47,7 @@ struct SDLAPIClient { let (data, _) = try await session.data(for: request) if let response = String(bytes: data, encoding: .utf8) { - NSLog("url: \(url.absoluteString), response is: \(response)") + print("url: \(url.absoluteString), reqeust data: \(String(data: postData, encoding: .utf8)!), response is: \(response)") } let apiResponse = try JSONDecoder().decode(SDLAPIResponse.self, from: data)