TunnelsManager: restore sanity
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
c80901fbed
commit
1568ae57e3
|
@ -48,11 +48,9 @@ class TunnelsManager {
|
||||||
os_log("Failed to load tunnel provider managers: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
os_log("Failed to load tunnel provider managers: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async {
|
|
||||||
completionHandler(TunnelsManager(tunnelProviders: managers ?? []))
|
completionHandler(TunnelsManager(tunnelProviders: managers ?? []))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func add(tunnelConfiguration: TunnelConfiguration, completionHandler: @escaping (TunnelContainer?, TunnelManagementError?) -> Void) {
|
func add(tunnelConfiguration: TunnelConfiguration, completionHandler: @escaping (TunnelContainer?, TunnelManagementError?) -> Void) {
|
||||||
let tunnelName = tunnelConfiguration.interface.name
|
let tunnelName = tunnelConfiguration.interface.name
|
||||||
|
@ -76,13 +74,10 @@ class TunnelsManager {
|
||||||
defer { self?.isAddingTunnel = false }
|
defer { self?.isAddingTunnel = false }
|
||||||
guard (error == nil) else {
|
guard (error == nil) else {
|
||||||
os_log("Add: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
os_log("Add: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
||||||
DispatchQueue.main.async {
|
|
||||||
completionHandler(nil, TunnelManagementError.vpnSystemErrorOnAddTunnel)
|
completionHandler(nil, TunnelManagementError.vpnSystemErrorOnAddTunnel)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { [weak self] in
|
if let s = self {
|
||||||
guard let s = self else { return }
|
|
||||||
let tunnel = TunnelContainer(tunnel: tunnelProviderManager)
|
let tunnel = TunnelContainer(tunnel: tunnelProviderManager)
|
||||||
s.tunnels.append(tunnel)
|
s.tunnels.append(tunnel)
|
||||||
s.tunnels.sort { $0.name < $1.name }
|
s.tunnels.sort { $0.name < $1.name }
|
||||||
|
@ -137,13 +132,10 @@ class TunnelsManager {
|
||||||
defer { self?.isModifyingTunnel = false }
|
defer { self?.isModifyingTunnel = false }
|
||||||
guard (error == nil) else {
|
guard (error == nil) else {
|
||||||
os_log("Modify: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
os_log("Modify: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
||||||
DispatchQueue.main.async {
|
|
||||||
completionHandler(TunnelManagementError.vpnSystemErrorOnModifyTunnel)
|
completionHandler(TunnelManagementError.vpnSystemErrorOnModifyTunnel)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { [weak self] in
|
if let s = self {
|
||||||
guard let s = self else { return }
|
|
||||||
if (isNameChanged) {
|
if (isNameChanged) {
|
||||||
let oldIndex = s.tunnels.firstIndex(of: tunnel)!
|
let oldIndex = s.tunnels.firstIndex(of: tunnel)!
|
||||||
s.tunnels.sort { $0.name < $1.name }
|
s.tunnels.sort { $0.name < $1.name }
|
||||||
|
@ -174,13 +166,12 @@ class TunnelsManager {
|
||||||
completionHandler(TunnelManagementError.vpnSystemErrorOnRemoveTunnel)
|
completionHandler(TunnelManagementError.vpnSystemErrorOnRemoveTunnel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DispatchQueue.main.async { [weak self] in
|
if let s = self {
|
||||||
guard let s = self else { return }
|
|
||||||
let index = s.tunnels.firstIndex(of: tunnel)!
|
let index = s.tunnels.firstIndex(of: tunnel)!
|
||||||
s.tunnels.remove(at: index)
|
s.tunnels.remove(at: index)
|
||||||
s.delegate?.tunnelRemoved(at: index)
|
s.delegate?.tunnelRemoved(at: index)
|
||||||
completionHandler(nil)
|
|
||||||
}
|
}
|
||||||
|
completionHandler(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +236,7 @@ class TunnelContainer: NSObject {
|
||||||
@objc dynamic var status: TunnelStatus
|
@objc dynamic var status: TunnelStatus
|
||||||
|
|
||||||
fileprivate let tunnelProvider: NETunnelProviderManager
|
fileprivate let tunnelProvider: NETunnelProviderManager
|
||||||
fileprivate var statusObservationToken: AnyObject?
|
private var statusObservationToken: AnyObject?
|
||||||
|
|
||||||
private var dnsResolver: DNSResolver? = nil
|
private var dnsResolver: DNSResolver? = nil
|
||||||
|
|
||||||
|
@ -339,21 +330,18 @@ class TunnelContainer: NSObject {
|
||||||
tunnelProvider.saveToPreferences { [weak self] (error) in
|
tunnelProvider.saveToPreferences { [weak self] (error) in
|
||||||
if (error != nil) {
|
if (error != nil) {
|
||||||
os_log("Error saving tunnel after re-enabling: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
os_log("Error saving tunnel after re-enabling: %{public}@", log: OSLog.default, type: .error, "\(error!)")
|
||||||
DispatchQueue.main.async {
|
|
||||||
completionHandler(error)
|
completionHandler(error)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
os_log("startActivation: Tunnel saved after re-enabling", log: OSLog.default, type: .info)
|
os_log("startActivation: Tunnel saved after re-enabling", log: OSLog.default, type: .info)
|
||||||
os_log("startActivation: Invoking startActivation", log: OSLog.default, type: .debug)
|
os_log("startActivation: Invoking startActivation", log: OSLog.default, type: .debug)
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
self?.startActivation(recursionCount: recursionCount + 1, lastError: NEVPNError(NEVPNError.configurationUnknown), tunnelConfiguration: tunnelConfiguration, resolvedEndpoints: resolvedEndpoints, completionHandler: completionHandler)
|
self?.startActivation(recursionCount: recursionCount + 1, lastError: NEVPNError(NEVPNError.configurationUnknown), tunnelConfiguration: tunnelConfiguration, resolvedEndpoints: resolvedEndpoints, completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the tunnel
|
// Start the tunnel
|
||||||
|
startObservingTunnelStatus()
|
||||||
let session = (tunnelProvider.connection as! NETunnelProviderSession)
|
let session = (tunnelProvider.connection as! NETunnelProviderSession)
|
||||||
do {
|
do {
|
||||||
os_log("startActivation: Generating options", log: OSLog.default, type: .debug)
|
os_log("startActivation: Generating options", log: OSLog.default, type: .debug)
|
||||||
|
@ -362,22 +350,19 @@ class TunnelContainer: NSObject {
|
||||||
os_log("startActivation: Starting tunnel", log: OSLog.default, type: .debug)
|
os_log("startActivation: Starting tunnel", log: OSLog.default, type: .debug)
|
||||||
try session.startTunnel(options: tunnelOptions)
|
try session.startTunnel(options: tunnelOptions)
|
||||||
os_log("startActivation: Success", log: OSLog.default, type: .debug)
|
os_log("startActivation: Success", log: OSLog.default, type: .debug)
|
||||||
startObservingTunnelStatus()
|
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
} catch (let error) {
|
} catch (let error) {
|
||||||
os_log("startActivation: Error starting tunnel. Examining error", log: OSLog.default, type: .debug)
|
os_log("startActivation: Error starting tunnel. Examining error", log: OSLog.default, type: .debug)
|
||||||
guard let vpnError = error as? NEVPNError else {
|
guard let vpnError = error as? NEVPNError else {
|
||||||
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
||||||
DispatchQueue.main.async {
|
status = .inactive
|
||||||
completionHandler(error)
|
completionHandler(error)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard (vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale) else {
|
guard (vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale) else {
|
||||||
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
|
||||||
DispatchQueue.main.async {
|
status = .inactive
|
||||||
completionHandler(error)
|
completionHandler(error)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert(vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale)
|
assert(vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale)
|
||||||
|
@ -387,19 +372,16 @@ class TunnelContainer: NSObject {
|
||||||
tunnelProvider.loadFromPreferences { [weak self] (error) in
|
tunnelProvider.loadFromPreferences { [weak self] (error) in
|
||||||
if (error != nil) {
|
if (error != nil) {
|
||||||
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error!)")
|
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error!)")
|
||||||
DispatchQueue.main.async {
|
self?.status = .inactive
|
||||||
completionHandler(error)
|
completionHandler(error)
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
os_log("startActivation: Tunnel reloaded", log: OSLog.default, type: .info)
|
os_log("startActivation: Tunnel reloaded", log: OSLog.default, type: .info)
|
||||||
os_log("startActivation: Invoking startActivation", log: OSLog.default, type: .debug)
|
os_log("startActivation: Invoking startActivation", log: OSLog.default, type: .debug)
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
self?.startActivation(recursionCount: recursionCount + 1, lastError: vpnError, tunnelConfiguration: tunnelConfiguration, resolvedEndpoints: resolvedEndpoints, completionHandler: completionHandler)
|
self?.startActivation(recursionCount: recursionCount + 1, lastError: vpnError, tunnelConfiguration: tunnelConfiguration, resolvedEndpoints: resolvedEndpoints, completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fileprivate func startDeactivation() {
|
fileprivate func startDeactivation() {
|
||||||
assert(status == .active)
|
assert(status == .active)
|
||||||
|
@ -433,21 +415,14 @@ class TunnelContainer: NSObject {
|
||||||
}
|
}
|
||||||
if (s.status == .resolvingEndpointDomains && connection.status == .disconnected) {
|
if (s.status == .resolvingEndpointDomains && connection.status == .disconnected) {
|
||||||
// Don't change to .inactive if we're still resolving endpoints
|
// Don't change to .inactive if we're still resolving endpoints
|
||||||
assert(false)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.status = TunnelStatus(from: connection.status)
|
s.status = TunnelStatus(from: connection.status)
|
||||||
if (s.status == .inactive) {
|
if (s.status == .inactive) {
|
||||||
s.stopObservingTunnelStatus()
|
s.statusObservationToken = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func stopObservingTunnelStatus() {
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
self?.statusObservationToken = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc enum TunnelStatus: Int {
|
@objc enum TunnelStatus: Int {
|
||||||
|
|
Loading…
Reference in New Issue