Fix packet tunnel start options persistence
This commit is contained in:
@@ -13,7 +13,7 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
private static let logger = Logger(category: "ExtensionProvider")
|
private static let logger = Logger(category: "ExtensionProvider")
|
||||||
|
|
||||||
public private(set) var commandServer: LibboxCommandServer?
|
public private(set) var commandServer: LibboxCommandServer?
|
||||||
private var platformInterface: ExtensionPlatformInterface!
|
private lazy var platformInterface = ExtensionPlatformInterface(self)
|
||||||
public var tunnelOptions: [String: NSObject]?
|
public var tunnelOptions: [String: NSObject]?
|
||||||
private var startOptionsURL: URL?
|
private var startOptionsURL: URL?
|
||||||
|
|
||||||
@@ -29,13 +29,13 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
|
|
||||||
private func applyStartOptions(_ options: [String: NSObject]) {
|
private func applyStartOptions(_ options: [String: NSObject]) {
|
||||||
tunnelOptions = options
|
tunnelOptions = options
|
||||||
var prefs = OverridePreferences()
|
overridePreferences = OverridePreferences(
|
||||||
prefs.includeAllNetworks = (options["includeAllNetworks"] as? NSNumber)?.boolValue ?? false
|
includeAllNetworks: (options["includeAllNetworks"] as? NSNumber)?.boolValue ?? false,
|
||||||
prefs.systemProxyEnabled = (options["systemProxyEnabled"] as? NSNumber)?.boolValue ?? true
|
systemProxyEnabled: (options["systemProxyEnabled"] as? NSNumber)?.boolValue ?? true,
|
||||||
prefs.excludeDefaultRoute = (options["excludeDefaultRoute"] as? NSNumber)?.boolValue ?? false
|
excludeDefaultRoute: (options["excludeDefaultRoute"] as? NSNumber)?.boolValue ?? false,
|
||||||
prefs.autoRouteUseSubRangesByDefault = (options["autoRouteUseSubRangesByDefault"] as? NSNumber)?.boolValue ?? false
|
autoRouteUseSubRangesByDefault: (options["autoRouteUseSubRangesByDefault"] as? NSNumber)?.boolValue ?? false,
|
||||||
prefs.excludeAPNsRoute = (options["excludeAPNsRoute"] as? NSNumber)?.boolValue ?? false
|
excludeAPNsRoute: (options["excludeAPNsRoute"] as? NSNumber)?.boolValue ?? false
|
||||||
overridePreferences = prefs
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func persistStartOptions(_ options: [String: NSObject]) throws {
|
private func persistStartOptions(_ options: [String: NSObject]) throws {
|
||||||
@@ -46,9 +46,36 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
try data.write(to: startOptionsURL, options: .atomic)
|
try data.write(to: startOptionsURL, options: .atomic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func loadPersistedStartOptions() throws -> [String: NSObject]? {
|
||||||
|
guard let startOptionsURL, FileManager.default.fileExists(atPath: startOptionsURL.path) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
let data = try Data(contentsOf: startOptionsURL)
|
||||||
|
return try ExtensionStartOptions.decode(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func resolveStartOptions(_ startOptions: [String: NSObject]?) throws -> [String: NSObject] {
|
||||||
|
if let startOptions, startOptions["configContent"] as? String != nil {
|
||||||
|
return startOptions
|
||||||
|
}
|
||||||
|
let persistedOptions: [String: NSObject]?
|
||||||
|
do {
|
||||||
|
persistedOptions = try loadPersistedStartOptions()
|
||||||
|
} catch {
|
||||||
|
throw ExtensionStartupError("(packet-tunnel) error: load start options: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
if let persistedOptions {
|
||||||
|
if let startOptions {
|
||||||
|
return persistedOptions.merging(startOptions) { _, new in new }
|
||||||
|
}
|
||||||
|
return persistedOptions
|
||||||
|
}
|
||||||
|
throw ExtensionStartupError("(packet-tunnel) error: missing start options")
|
||||||
|
}
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
private var xpcListener: NSXPCListener?
|
private var xpcListener: NSXPCListener!
|
||||||
private var xpcService: CommandXPCService?
|
private var xpcService: CommandXPCService!
|
||||||
private var locationManager: CLLocationManager?
|
private var locationManager: CLLocationManager?
|
||||||
private var locationDelegate: stubLocationDelegate?
|
private var locationDelegate: stubLocationDelegate?
|
||||||
#endif
|
#endif
|
||||||
@@ -76,27 +103,28 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
startOptionsURL = URL(fileURLWithPath: basePath).appendingPathComponent(ExtensionStartOptions.snapshotFileName)
|
startOptionsURL = URL(fileURLWithPath: basePath).appendingPathComponent(ExtensionStartOptions.snapshotFileName)
|
||||||
var effectiveOptions = startOptions
|
|
||||||
if let startOptions {
|
#if os(macOS)
|
||||||
|
if Variant.useSystemExtension {
|
||||||
|
let socketPath = basePath + "/command.sock"
|
||||||
|
let machServiceName = AppConfiguration.appGroupID + ".system"
|
||||||
|
xpcService = CommandXPCService(socketPath: socketPath)
|
||||||
|
xpcListener = NSXPCListener(machServiceName: machServiceName)
|
||||||
|
xpcListener.delegate = xpcService
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
let effectiveOptions = try resolveStartOptions(startOptions)
|
||||||
|
if effectiveOptions["configContent"] == nil {
|
||||||
|
throw ExtensionStartupError("(packet-tunnel) error: missing configContent in tunnel options")
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
try persistStartOptions(startOptions)
|
try persistStartOptions(effectiveOptions)
|
||||||
} catch {
|
} catch {
|
||||||
throw ExtensionStartupError("(packet-tunnel) error: persist start options: \(error.localizedDescription)")
|
throw ExtensionStartupError("(packet-tunnel) error: persist start options: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
} else if let startOptionsURL, FileManager.default.fileExists(atPath: startOptionsURL.path) {
|
|
||||||
do {
|
|
||||||
let data = try Data(contentsOf: startOptionsURL)
|
|
||||||
effectiveOptions = try ExtensionStartOptions.decode(data)
|
|
||||||
} catch {
|
|
||||||
throw ExtensionStartupError("(packet-tunnel) error: load start options: \(error.localizedDescription)")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw ExtensionStartupError("(packet-tunnel) error: missing start options")
|
|
||||||
}
|
|
||||||
|
|
||||||
if let effectiveOptions {
|
|
||||||
applyStartOptions(effectiveOptions)
|
applyStartOptions(effectiveOptions)
|
||||||
}
|
|
||||||
|
|
||||||
let options = LibboxSetupOptions()
|
let options = LibboxSetupOptions()
|
||||||
options.basePath = basePath
|
options.basePath = basePath
|
||||||
@@ -106,10 +134,10 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
options.logMaxLines = 3000
|
options.logMaxLines = 3000
|
||||||
|
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
if let port = effectiveOptions?["commandServerPort"] as? NSNumber {
|
if let port = effectiveOptions["commandServerPort"] as? NSNumber {
|
||||||
options.commandServerListenPort = port.int32Value
|
options.commandServerListenPort = port.int32Value
|
||||||
}
|
}
|
||||||
if let secret = effectiveOptions?["commandServerSecret"] as? String {
|
if let secret = effectiveOptions["commandServerSecret"] as? String {
|
||||||
options.commandServerSecret = secret
|
options.commandServerSecret = secret
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -120,12 +148,9 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
throw ExtensionStartupError("(packet-tunnel) error: setup service: \(setupError.localizedDescription)")
|
throw ExtensionStartupError("(packet-tunnel) error: setup service: \(setupError.localizedDescription)")
|
||||||
}
|
}
|
||||||
|
|
||||||
let ignoreMemoryLimit = (effectiveOptions?["ignoreMemoryLimit"] as? NSNumber)?.boolValue ?? false
|
let ignoreMemoryLimit = (effectiveOptions["ignoreMemoryLimit"] as? NSNumber)?.boolValue ?? false
|
||||||
LibboxSetMemoryLimit(!ignoreMemoryLimit)
|
LibboxSetMemoryLimit(!ignoreMemoryLimit)
|
||||||
|
|
||||||
if platformInterface == nil {
|
|
||||||
platformInterface = ExtensionPlatformInterface(self)
|
|
||||||
}
|
|
||||||
var error: NSError?
|
var error: NSError?
|
||||||
commandServer = LibboxNewCommandServer(platformInterface, platformInterface, &error)
|
commandServer = LibboxNewCommandServer(platformInterface, platformInterface, &error)
|
||||||
if let error {
|
if let error {
|
||||||
@@ -139,14 +164,9 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
if Variant.useSystemExtension {
|
if Variant.useSystemExtension {
|
||||||
let socketPath = options.basePath + "/command.sock"
|
xpcListener.resume()
|
||||||
xpcService = CommandXPCService(socketPath: socketPath)
|
|
||||||
let machServiceName = AppConfiguration.appGroupID + ".system"
|
|
||||||
xpcListener = NSXPCListener(machServiceName: machServiceName)
|
|
||||||
xpcListener!.delegate = xpcService
|
|
||||||
xpcListener!.resume()
|
|
||||||
Self.logger.info("set Command Server")
|
Self.logger.info("set Command Server")
|
||||||
xpcService!.commandServer = commandServer
|
xpcService.commandServer = commandServer
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -154,7 +174,7 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
try await startService()
|
try await startService()
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
if Variant.useSystemExtension {
|
if Variant.useSystemExtension {
|
||||||
xpcService!.markServiceReady()
|
xpcService.markServiceReady()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@@ -185,8 +205,8 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
if !Variant.useSystemExtension, commandServer!.needWIFIState() {
|
if !Variant.useSystemExtension, commandServer!.needWIFIState() {
|
||||||
locationManager = CLLocationManager()
|
locationManager = CLLocationManager()
|
||||||
locationDelegate = stubLocationDelegate()
|
locationDelegate = stubLocationDelegate()
|
||||||
locationManager?.delegate = locationDelegate
|
locationManager!.delegate = locationDelegate
|
||||||
locationManager?.requestLocation()
|
locationManager!.requestLocation()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -209,10 +229,8 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
} catch {
|
} catch {
|
||||||
writeMessage("(packet-tunnel) stop service: \(error.localizedDescription)")
|
writeMessage("(packet-tunnel) stop service: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
if let platformInterface {
|
|
||||||
platformInterface.reset()
|
platformInterface.reset()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func reloadService() async throws {
|
func reloadService() async throws {
|
||||||
writeMessage("(packet-tunnel) reloading service")
|
writeMessage("(packet-tunnel) reloading service")
|
||||||
@@ -233,9 +251,9 @@ open class ExtensionProvider: NEPacketTunnelProvider {
|
|||||||
}
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
if Variant.useSystemExtension {
|
if Variant.useSystemExtension {
|
||||||
xpcListener?.invalidate()
|
xpcListener.invalidate()
|
||||||
xpcListener = nil
|
xpcListener = nil
|
||||||
xpcService?.commandServer = nil
|
xpcService.commandServer = nil
|
||||||
xpcService = nil
|
xpcService = nil
|
||||||
UserServiceEndpointRegistry.shared.clear()
|
UserServiceEndpointRegistry.shared.clear()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user