Generate NetworkSettings with IPC
This generates and applies NetworkSettings object with unix socket IPC. - domain socket, json-rpc based communication - switches to anyhow for burrow crate - adds support for starting daemons on macos
This commit is contained in:
parent
6368ca7f74
commit
c9f104e523
31 changed files with 909 additions and 117 deletions
|
|
@ -1,39 +1,66 @@
|
|||
import libburrow
|
||||
import NetworkExtension
|
||||
import OSLog
|
||||
import os
|
||||
|
||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
let logger = Logger(subsystem: "com.hackclub.burrow", category: "General")
|
||||
let logger = Logger(subsystem: "com.hackclub.burrow", category: "frontend")
|
||||
var client: BurrowIpc?
|
||||
var osInitialized = false
|
||||
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
|
||||
let fild = libburrow.retrieve()
|
||||
if fild == -1 {
|
||||
// Not sure if this is the right way to return an error
|
||||
logger.error("Failed to retrieve file descriptor for burrow.")
|
||||
let err = NSError(
|
||||
domain: "com.hackclub.burrow",
|
||||
code: 1_010,
|
||||
userInfo: [NSLocalizedDescriptionKey: "Failed to find TunInterface"]
|
||||
)
|
||||
completionHandler(err)
|
||||
logger.log("Starting tunnel")
|
||||
if !osInitialized {
|
||||
libburrow.initialize_oslog()
|
||||
osInitialized = true
|
||||
}
|
||||
libburrow.start_srv()
|
||||
client = BurrowIpc(logger: logger)
|
||||
logger.info("Started server")
|
||||
Task {
|
||||
do {
|
||||
let command = BurrowRequest(id: 0, command: "ServerConfig")
|
||||
guard let data = try await client?.request(command, type: Response<BurrowResult<ServerConfigData>>.self)
|
||||
else {
|
||||
throw BurrowError.cantParseResult
|
||||
}
|
||||
let encoded = try JSONEncoder().encode(data.result)
|
||||
self.logger.log("Received final data: \(String(decoding: encoded, as: UTF8.self))")
|
||||
guard let serverconfig = data.result.Ok else {
|
||||
throw BurrowError.resultIsError
|
||||
}
|
||||
guard let tunNs = self.generateTunSettings(from: serverconfig) else {
|
||||
throw BurrowError.addrDoesntExist
|
||||
}
|
||||
try await self.setTunnelNetworkSettings(tunNs)
|
||||
self.logger.info("Set remote tunnel address to \(tunNs.tunnelRemoteAddress)")
|
||||
completionHandler(nil)
|
||||
} catch {
|
||||
self.logger.error("An error occurred: \(error)")
|
||||
completionHandler(error)
|
||||
}
|
||||
}
|
||||
logger.info("fd: \(fild)")
|
||||
completionHandler(nil)
|
||||
}
|
||||
|
||||
private func generateTunSettings(from: ServerConfigData) -> NETunnelNetworkSettings? {
|
||||
let cfig = from.ServerConfig
|
||||
guard let addr = cfig.address else {
|
||||
return nil
|
||||
}
|
||||
// Using a makeshift remote tunnel address
|
||||
var nst = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1")
|
||||
nst.ipv4Settings = NEIPv4Settings(addresses: [addr], subnetMasks: ["255.255.255.0"])
|
||||
logger.log("Initialized ipv4 settings: \(nst.ipv4Settings)")
|
||||
return nst
|
||||
}
|
||||
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||
completionHandler()
|
||||
}
|
||||
|
||||
override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
|
||||
if let handler = completionHandler {
|
||||
handler(messageData)
|
||||
}
|
||||
}
|
||||
|
||||
override func sleep(completionHandler: @escaping () -> Void) {
|
||||
completionHandler()
|
||||
}
|
||||
|
||||
override func wake() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue