From cd144f41e16d4dacada50a2872ccf9988040a356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 13 Nov 2024 10:46:38 +0800 Subject: [PATCH] Implement new interface api --- .../Network/ExtensionPlatformInterface.swift | 82 +++++++++++++++++-- 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/Library/Network/ExtensionPlatformInterface.swift b/Library/Network/ExtensionPlatformInterface.swift index 2f315b4..a67bed7 100644 --- a/Library/Network/ExtensionPlatformInterface.swift +++ b/Library/Network/ExtensionPlatformInterface.swift @@ -195,7 +195,7 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc } public func usePlatformAutoDetectControl() -> Bool { - true + false } public func autoDetectControl(_: Int32) throws {} @@ -223,20 +223,84 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc tunnel.writeMessage(message) } - public func usePlatformDefaultInterfaceMonitor() -> Bool { - false - } + private var nwMonitor: NWPathMonitor? = nil - public func startDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws {} + public func startDefaultInterfaceMonitor(_ listener: LibboxInterfaceUpdateListenerProtocol?) throws { + guard let listener else { + return + } + let monitor = NWPathMonitor() + nwMonitor = monitor + let semaphore = DispatchSemaphore(value: 0) + monitor.pathUpdateHandler = { path in + self.onUpdateDefaultInterface(listener, path) + semaphore.signal() + monitor.pathUpdateHandler = { path in + self.onUpdateDefaultInterface(listener, path) + } + } + monitor.start(queue: DispatchQueue.global()) + semaphore.wait() + } - public func closeDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws {} + private func onUpdateDefaultInterface(_ listener: LibboxInterfaceUpdateListenerProtocol, _ path: Network.NWPath) { + if path.status == .unsatisfied { + listener.updateDefaultInterface("", interfaceIndex: -1, isExpensive: false, isConstrained: false) + } else { + let defaultInterface = path.availableInterfaces.first! + listener.updateDefaultInterface(defaultInterface.name, interfaceIndex: Int32(defaultInterface.index), isExpensive: path.isExpensive, isConstrained: path.isConstrained) + } + } - public func useGetter() -> Bool { - false + public func closeDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws { + nwMonitor?.cancel() + nwMonitor = nil } public func getInterfaces() throws -> LibboxNetworkInterfaceIteratorProtocol { - throw NSError(domain: "not implemented", code: 0) + guard let nwMonitor else { + throw NSError(domain: "NWMonitor not started", code: 0) + } + let path = nwMonitor.currentPath + if path.status == .unsatisfied { + return networkInterfaceArray([]) + } + var interfaces: [LibboxNetworkInterface] = [] + for it in path.availableInterfaces { + let interface = LibboxNetworkInterface() + interface.name = it.name + interface.index = Int32(it.index) + switch it.type { + case .wifi: + interface.type = LibboxInterfaceTypeWIFI + case .cellular: + interface.type = LibboxInterfaceTypeCellular + case .wiredEthernet: + interface.type = LibboxInterfaceTypeEthernet + default: + interface.type = LibboxInterfaceTypeOther + } + interfaces.append(interface) + } + return networkInterfaceArray(interfaces) + } + + class networkInterfaceArray: NSObject, LibboxNetworkInterfaceIteratorProtocol { + private var iterator: IndexingIterator<[LibboxNetworkInterface]> + init(_ array: [LibboxNetworkInterface]) { + iterator = array.makeIterator() + } + + private var nextValue: LibboxNetworkInterface? = nil + + func hasNext() -> Bool { + nextValue = iterator.next() + return nextValue != nil + } + + func next() -> LibboxNetworkInterface? { + nextValue + } } public func underNetworkExtension() -> Bool {