diff --git a/Tun/PacketTunnelProvider.swift b/Tun/PacketTunnelProvider.swift index c1e90c0..0615c23 100644 --- a/Tun/PacketTunnelProvider.swift +++ b/Tun/PacketTunnelProvider.swift @@ -22,6 +22,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let msg = shared?.string(forKey: "test_msg") SDLLogger.shared.log("NE read message: \(msg ?? "failed")") + DarwinNotificationCenter.shared.post(.vpnStatusChanged) + // host: "192.168.0.101", port: 1265 guard let options, let config = SDLConfiguration.parse(options: options) else { completionHandler(TunnelError.invalidConfiguration) diff --git a/Tun/Punchnet/Actors/SDLContextActor.swift b/Tun/Punchnet/Actors/SDLContextActor.swift index e22608d..fe00c3b 100644 --- a/Tun/Punchnet/Actors/SDLContextActor.swift +++ b/Tun/Punchnet/Actors/SDLContextActor.swift @@ -21,7 +21,7 @@ actor SDLContextActor { private var state: State = .unregistered - nonisolated let config: SDLConfiguration + var config: SDLConfiguration // nat的网络类型 var natType: SDLNATProberActor.NatType = .blocked @@ -134,6 +134,11 @@ actor SDLContextActor { } } + public func updateSDLConfiguration(config: SDLConfiguration) async throws { + self.config = config + try await self.setNetworkSettings(config: config, dnsServer: SDLDNSClient.Helper.dnsServer) + } + private func startQUICClient() async throws -> SDLQUICClient { self.quicWorker?.cancel() self.quicClient?.stop() @@ -415,7 +420,7 @@ actor SDLContextActor { SDLLogger.shared.log("[SDLContext] get registerSuperAck, aes_key len: \(key.count)", level: .info) // 服务器分配的tun网卡信息 do { - try await self.setNetworkSettings(networkAddress: self.config.networkAddress, dnsServer: SDLDNSClient.Helper.dnsServer) + try await self.setNetworkSettings(config: self.config, dnsServer: SDLDNSClient.Helper.dnsServer) SDLLogger.shared.log("[SDLContext] setNetworkSettings successed") self.state = .registered self.startReader() @@ -695,8 +700,8 @@ actor SDLContextActor { } // 不在同一个网段的数据,看到是否配置了网络出口 // 如果配置了,转发数据个网络出口,否则丢弃 - else { - let exitNodeIp: UInt32 = 1234 + else if let exitNode = config.exitNode { + let exitNodeIp: UInt32 = exitNode.exitNodeIp SDLLogger.shared.log("[SDLContext] global dstIp: \(packet.header.destination.asIpAddress())", level: .debug) // 查找arp缓存中是否有目标mac地址 if let dstMac = await self.arpServer.query(ip: exitNodeIp) { @@ -752,16 +757,21 @@ actor SDLContextActor { } } - // 网络改变时需要重新配置网络信息 - private func setNetworkSettings(networkAddress: SDLConfiguration.NetworkAddress, dnsServer: String) async throws { + // MARK: 网络改变时需要重新配置网络信息 + private func setNetworkSettings(config: SDLConfiguration, dnsServer: String) async throws { + let networkAddress = config.networkAddress + // 配置路由规则 - let routes: [NEIPv4Route] = [ + var routes: [NEIPv4Route] = [ NEIPv4Route(destinationAddress: networkAddress.netAddress, subnetMask: networkAddress.maskAddress), NEIPv4Route(destinationAddress: dnsServer, subnetMask: "255.255.255.255"), - - NEIPv4Route(destinationAddress: "172.16.1.0", subnetMask: "255.255.255.0"), ] + // 如果存在出口节点配置,则接管系统默认留有 + if let exitNode = config.exitNode { + routes.append(.default()) + } + // Add code here to start the process of connecting the tunnel. let networkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "8.8.8.8") networkSettings.mtu = 1250 diff --git a/Tun/Punchnet/SDLConfiguration.swift b/Tun/Punchnet/SDLConfiguration.swift index ecb7699..bdcb3f5 100644 --- a/Tun/Punchnet/SDLConfiguration.swift +++ b/Tun/Punchnet/SDLConfiguration.swift @@ -9,6 +9,8 @@ import NIOCore // 配置项目 public class SDLConfiguration { + + // 网络地址信息 public struct NetworkAddress { public let networkId: UInt32 public let ip: UInt32 @@ -38,6 +40,11 @@ public class SDLConfiguration { } } + // 网络出口 + public struct ExitNode { + let exitNodeIp: UInt32 + } + // 当前的客户端版本 let version: Int @@ -67,6 +74,8 @@ public class SDLConfiguration { let accessToken: String let identityId: UInt32 + let exitNode: ExitNode? + public init(version: Int, serverHost: String, stunServers: [String], @@ -75,7 +84,8 @@ public class SDLConfiguration { hostname: String, noticePort: Int, accessToken: String, - identityId: UInt32) { + identityId: UInt32, + exitNode: ExitNode?) { self.version = version self.serverHost = serverHost @@ -86,7 +96,9 @@ public class SDLConfiguration { self.accessToken = accessToken self.identityId = identityId self.hostname = hostname + self.exitNode = exitNode } + } // 解析配置文件 @@ -109,6 +121,12 @@ extension SDLConfiguration { 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], @@ -117,7 +135,8 @@ extension SDLConfiguration { hostname: hostname, noticePort: noticePort, accessToken: accessToken, - identityId: identityId) + identityId: identityId, + exitNode: exitNode) } private static func parseNetworkAddress(_ config: [String: NSObject]) -> SDLConfiguration.NetworkAddress? { diff --git a/punchnet/punchnetApp.swift b/punchnet/punchnetApp.swift index 1735a88..641949e 100644 --- a/punchnet/punchnetApp.swift +++ b/punchnet/punchnetApp.swift @@ -89,11 +89,13 @@ struct punchnetApp: App { class AppDelegate: NSObject, NSApplicationDelegate { func applicationWillFinishLaunching(_ notification: Notification) { - let shared = UserDefaults(suiteName: "group.com.jihe.punchnetmac") shared?.set("App says hello", forKey: "test_msg") shared?.synchronize() + DarwinNotificationCenter.shared.addObserver(for: .vpnStatusChanged) { name in + NSLog("DarwinNotificationCenter get message: \(name)") + } } func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {