Add support for MAC and hostname rule items
This commit is contained in:
@@ -452,6 +452,11 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
|
||||
networkSettings = nil
|
||||
nwMonitor?.cancel()
|
||||
nwMonitor = nil
|
||||
#if os(macOS)
|
||||
neighborCallbackListener?.invalidate()
|
||||
neighborCallbackListener = nil
|
||||
neighborCallbackHandler = nil
|
||||
#endif
|
||||
}
|
||||
|
||||
public func send(_ notification: LibboxNotification?) throws {
|
||||
@@ -484,6 +489,50 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
private var neighborCallbackListener: NSXPCListener?
|
||||
private var neighborCallbackHandler: NeighborCallbackHandler?
|
||||
#endif
|
||||
|
||||
public func startNeighborMonitor(_ listener: LibboxNeighborUpdateListenerProtocol?) throws {
|
||||
#if os(macOS)
|
||||
guard let listener else { return }
|
||||
if Variant.useSystemExtension {
|
||||
let handler = NeighborCallbackHandler(listener)
|
||||
let xpcListener = NSXPCListener.anonymous()
|
||||
xpcListener.delegate = handler
|
||||
xpcListener.resume()
|
||||
try RootHelperClient.shared.startNeighborMonitor(
|
||||
callbackEndpoint: xpcListener.endpoint
|
||||
)
|
||||
neighborCallbackListener = xpcListener
|
||||
neighborCallbackHandler = handler
|
||||
return
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public func registerMyInterface(_ name: String?) {
|
||||
#if os(macOS)
|
||||
guard let name, !name.isEmpty else { return }
|
||||
if Variant.useSystemExtension {
|
||||
try? RootHelperClient.shared.registerMyInterface(name: name)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public func closeNeighborMonitor(_: LibboxNeighborUpdateListenerProtocol?) throws {
|
||||
#if os(macOS)
|
||||
if Variant.useSystemExtension {
|
||||
try? RootHelperClient.shared.closeNeighborMonitor()
|
||||
neighborCallbackListener?.invalidate()
|
||||
neighborCallbackListener = nil
|
||||
neighborCallbackHandler = nil
|
||||
return
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public func localDNSTransport() -> (any LibboxLocalDNSTransportProtocol)? {
|
||||
nil
|
||||
}
|
||||
@@ -492,3 +541,51 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
private class NeighborCallbackHandler: NSObject, NSXPCListenerDelegate, NeighborTableListenerProtocol {
|
||||
private let listener: LibboxNeighborUpdateListenerProtocol
|
||||
|
||||
init(_ listener: LibboxNeighborUpdateListenerProtocol) {
|
||||
self.listener = listener
|
||||
}
|
||||
|
||||
func listener(_: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool {
|
||||
let exportedInterface = NSXPCInterface(with: NeighborTableListenerProtocol.self)
|
||||
RootHelperXPC.configureListenerInterface(exportedInterface)
|
||||
newConnection.exportedInterface = exportedInterface
|
||||
newConnection.exportedObject = self
|
||||
newConnection.resume()
|
||||
return true
|
||||
}
|
||||
|
||||
func updateNeighborTable(entries: NSArray) {
|
||||
let iterator = NeighborEntryArrayIterator(entries)
|
||||
listener.updateNeighborTable(iterator)
|
||||
}
|
||||
}
|
||||
|
||||
private class NeighborEntryArrayIterator: NSObject, LibboxNeighborEntryIteratorProtocol {
|
||||
private var entries: [NeighborEntryResult]
|
||||
private var index = 0
|
||||
|
||||
init(_ array: NSArray) {
|
||||
entries = array.compactMap { $0 as? NeighborEntryResult }
|
||||
}
|
||||
|
||||
func hasNext() -> Bool {
|
||||
index < entries.count
|
||||
}
|
||||
|
||||
func next() -> LibboxNeighborEntry? {
|
||||
guard index < entries.count else { return nil }
|
||||
let result = entries[index]
|
||||
index += 1
|
||||
let entry = LibboxNeighborEntry()
|
||||
entry.address = result.address
|
||||
entry.macAddress = result.macAddress
|
||||
entry.hostname = result.hostname
|
||||
return entry
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,36 @@
|
||||
|
||||
private let logger = Logger(category: "RootHelperXPC")
|
||||
|
||||
@objc(NeighborEntryResult) public class NeighborEntryResult: NSObject, NSSecureCoding {
|
||||
public static let supportsSecureCoding = true
|
||||
|
||||
@objc public var address: String
|
||||
@objc public var macAddress: String
|
||||
@objc public var hostname: String
|
||||
|
||||
public init(address: String, macAddress: String, hostname: String) {
|
||||
self.address = address
|
||||
self.macAddress = macAddress
|
||||
self.hostname = hostname
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
address = coder.decodeObject(of: NSString.self, forKey: "address") as? String ?? ""
|
||||
macAddress = coder.decodeObject(of: NSString.self, forKey: "macAddress") as? String ?? ""
|
||||
hostname = coder.decodeObject(of: NSString.self, forKey: "hostname") as? String ?? ""
|
||||
}
|
||||
|
||||
public func encode(with coder: NSCoder) {
|
||||
coder.encode(address as NSString, forKey: "address")
|
||||
coder.encode(macAddress as NSString, forKey: "macAddress")
|
||||
coder.encode(hostname as NSString, forKey: "hostname")
|
||||
}
|
||||
}
|
||||
|
||||
@objc public protocol NeighborTableListenerProtocol {
|
||||
func updateNeighborTable(entries: NSArray)
|
||||
}
|
||||
|
||||
@objc public class ConnectionOwnerResult: NSObject, NSSecureCoding {
|
||||
public static let supportsSecureCoding = true
|
||||
|
||||
@@ -43,6 +73,9 @@
|
||||
func getWorkingDirectorySize(reply: @escaping (Int64, NSError?) -> Void)
|
||||
func cleanWorkingDirectory(reply: @escaping (NSError?) -> Void)
|
||||
func getVersion(reply: @escaping (String) -> Void)
|
||||
func startNeighborMonitor(callbackEndpoint: NSXPCListenerEndpoint, reply: @escaping (NSError?) -> Void)
|
||||
func closeNeighborMonitor(reply: @escaping (NSError?) -> Void)
|
||||
func registerMyInterface(name: String, reply: @escaping (NSError?) -> Void)
|
||||
}
|
||||
|
||||
public enum RootHelperXPC {
|
||||
@@ -54,6 +87,23 @@
|
||||
argumentIndex: 0,
|
||||
ofReply: true
|
||||
)
|
||||
let endpointClasses = NSSet(array: [NSXPCListenerEndpoint.self]) as! Set<AnyHashable>
|
||||
interface.setClasses(
|
||||
endpointClasses,
|
||||
for: #selector(RootHelperProtocol.startNeighborMonitor(callbackEndpoint:reply:)),
|
||||
argumentIndex: 0,
|
||||
ofReply: false
|
||||
)
|
||||
}
|
||||
|
||||
public static func configureListenerInterface(_ interface: NSXPCInterface) {
|
||||
let entryClasses = NSSet(array: [NSArray.self, NeighborEntryResult.self]) as! Set<AnyHashable>
|
||||
interface.setClasses(
|
||||
entryClasses,
|
||||
for: #selector(NeighborTableListenerProtocol.updateNeighborTable(entries:)),
|
||||
argumentIndex: 0,
|
||||
ofReply: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +269,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
public func startNeighborMonitor(callbackEndpoint: NSXPCListenerEndpoint) throws {
|
||||
try performXPCCallVoid("startNeighborMonitor") { proxy, reply in
|
||||
proxy.startNeighborMonitor(callbackEndpoint: callbackEndpoint, reply: reply)
|
||||
}
|
||||
}
|
||||
|
||||
public func closeNeighborMonitor() throws {
|
||||
try performXPCCallVoid("closeNeighborMonitor") { proxy, reply in
|
||||
proxy.closeNeighborMonitor(reply: reply)
|
||||
}
|
||||
}
|
||||
|
||||
public func registerMyInterface(name: String) throws {
|
||||
try performXPCCallVoid("registerMyInterface") { proxy, reply in
|
||||
proxy.registerMyInterface(name: name, reply: reply)
|
||||
}
|
||||
}
|
||||
|
||||
public func getVersion() throws -> String {
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
var result: String?
|
||||
|
||||
Reference in New Issue
Block a user