VPN: Make sure actions inside tunnelProvider completion handlers are done in the main queue

They should really already be in the main queue, but we do this just in case.
This commit is contained in:
Roopesh Chander 2018-11-03 19:20:00 +05:30
parent f4f1278a82
commit 215c56cec3

View File

@ -48,9 +48,11 @@ class TunnelsManager {
os_log("Failed to load tunnel provider managers: %{public}@", log: OSLog.default, type: .debug, "\(error)")
return
}
DispatchQueue.main.async {
completionHandler(TunnelsManager(tunnelProviders: managers ?? []))
}
}
}
func add(tunnelConfiguration: TunnelConfiguration, completionHandler: @escaping (TunnelContainer?, TunnelManagementError?) -> Void) {
let tunnelName = tunnelConfiguration.interface.name
@ -74,10 +76,13 @@ class TunnelsManager {
defer { self?.isAddingTunnel = false }
guard (error == nil) else {
os_log("Add: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
DispatchQueue.main.async {
completionHandler(nil, TunnelManagementError.vpnSystemErrorOnAddTunnel)
}
return
}
if let s = self {
DispatchQueue.main.async { [weak self] in
guard let s = self else { return }
let tunnel = TunnelContainer(tunnel: tunnelProviderManager)
s.tunnels.append(tunnel)
s.tunnels.sort { $0.name < $1.name }
@ -132,10 +137,13 @@ class TunnelsManager {
defer { self?.isModifyingTunnel = false }
guard (error == nil) else {
os_log("Modify: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
DispatchQueue.main.async {
completionHandler(TunnelManagementError.vpnSystemErrorOnModifyTunnel)
}
return
}
if let s = self {
DispatchQueue.main.async { [weak self] in
guard let s = self else { return }
if (isNameChanged) {
let oldIndex = s.tunnels.firstIndex(of: tunnel)!
s.tunnels.sort { $0.name < $1.name }
@ -166,14 +174,15 @@ class TunnelsManager {
completionHandler(TunnelManagementError.vpnSystemErrorOnRemoveTunnel)
return
}
if let s = self {
DispatchQueue.main.async { [weak self] in
guard let s = self else { return }
let index = s.tunnels.firstIndex(of: tunnel)!
s.tunnels.remove(at: index)
s.delegate?.tunnelRemoved(at: index)
}
completionHandler(nil)
}
}
}
func numberOfTunnels() -> Int {
return tunnels.count
@ -330,13 +339,17 @@ class TunnelContainer: NSObject {
tunnelProvider.saveToPreferences { [weak self] (error) in
if (error != nil) {
os_log("Error saving tunnel after re-enabling: %{public}@", log: OSLog.default, type: .error, "\(error!)")
DispatchQueue.main.async {
completionHandler(error)
}
return
}
os_log("startActivation: Tunnel saved after re-enabling", log: OSLog.default, type: .info)
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)
}
}
return
}
@ -355,14 +368,16 @@ class TunnelContainer: NSObject {
os_log("startActivation: Error starting tunnel. Examining error", log: OSLog.default, type: .debug)
guard let vpnError = error as? NEVPNError else {
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
status = .inactive
DispatchQueue.main.async {
completionHandler(error)
}
return
}
guard (vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale) else {
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error)")
status = .inactive
DispatchQueue.main.async {
completionHandler(error)
}
return
}
assert(vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale)
@ -372,16 +387,19 @@ class TunnelContainer: NSObject {
tunnelProvider.loadFromPreferences { [weak self] (error) in
if (error != nil) {
os_log("Failed to activate tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error!)")
self?.status = .inactive
DispatchQueue.main.async {
completionHandler(error)
}
return
}
os_log("startActivation: Tunnel reloaded", log: OSLog.default, type: .info)
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)
}
}
}
}
fileprivate func startDeactivation() {
assert(status == .active)