VPN: When activating while another tunnel is active, deactivate the other tunnel
This commit is contained in:
parent
e6917a6075
commit
e974b7df23
|
@ -23,21 +23,6 @@ class ErrorPresenter {
|
|||
// TunnelActivationError
|
||||
case TunnelActivationError.tunnelActivationFailed:
|
||||
return ("Activation failure", "The tunnel could not be activated due to an internal error")
|
||||
case TunnelActivationError.attemptingActivationWhenAnotherTunnelIsBusy(let otherTunnelStatus):
|
||||
let statusString: String = {
|
||||
switch (otherTunnelStatus) {
|
||||
case .active: fallthrough
|
||||
case .reasserting: fallthrough
|
||||
case .restarting:
|
||||
return "active"
|
||||
case .activating: fallthrough
|
||||
case .deactivating:
|
||||
return "being deactivated"
|
||||
case .inactive:
|
||||
fatalError()
|
||||
}
|
||||
}()
|
||||
return ("Activation failure", "Another tunnel is currently \(statusString)")
|
||||
|
||||
default:
|
||||
os_log("ErrorPresenter: Error not presented: %{public}@", log: OSLog.default, type: .error, "\(error)")
|
||||
|
|
|
@ -259,6 +259,8 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
|
|||
text = "Reactivating"
|
||||
case .restarting:
|
||||
text = "Restarting"
|
||||
case .waiting:
|
||||
text = "Waiting"
|
||||
}
|
||||
textLabel?.text = text
|
||||
DispatchQueue.main.async { [weak statusSwitch] in
|
||||
|
|
|
@ -14,7 +14,6 @@ protocol TunnelsManagerDelegate: class {
|
|||
|
||||
enum TunnelActivationError: Error {
|
||||
case tunnelActivationFailed
|
||||
case attemptingActivationWhenAnotherTunnelIsBusy(otherTunnelStatus: TunnelStatus)
|
||||
case attemptingActivationWhenTunnelIsNotInactive
|
||||
case attemptingDeactivationWhenTunnelIsInactive
|
||||
}
|
||||
|
@ -191,13 +190,15 @@ class TunnelsManager {
|
|||
completionHandler(TunnelActivationError.attemptingActivationWhenTunnelIsNotInactive)
|
||||
return
|
||||
}
|
||||
for t in tunnels {
|
||||
if t.status != .inactive {
|
||||
completionHandler(TunnelActivationError.attemptingActivationWhenAnotherTunnelIsBusy(otherTunnelStatus: t.status))
|
||||
return
|
||||
if let tunnelInOperation = tunnels.first(where: { $0.status != .inactive }) {
|
||||
tunnel.status = .waiting
|
||||
tunnelInOperation.onDeactivationComplete = {
|
||||
tunnel.startActivation(completionHandler: completionHandler)
|
||||
}
|
||||
startDeactivation(of: tunnelInOperation)
|
||||
} else {
|
||||
tunnel.startActivation(completionHandler: completionHandler)
|
||||
}
|
||||
tunnel.startActivation(completionHandler: completionHandler)
|
||||
}
|
||||
|
||||
func startDeactivation(of tunnel: TunnelContainer) {
|
||||
|
@ -218,6 +219,8 @@ class TunnelContainer: NSObject {
|
|||
@objc dynamic var name: String
|
||||
@objc dynamic var status: TunnelStatus
|
||||
|
||||
var onDeactivationComplete: (() -> Void)?
|
||||
|
||||
fileprivate let tunnelProvider: NETunnelProviderManager
|
||||
private var statusObservationToken: AnyObject?
|
||||
|
||||
|
@ -245,10 +248,11 @@ class TunnelContainer: NSObject {
|
|||
}
|
||||
|
||||
fileprivate func startActivation(completionHandler: @escaping (Error?) -> Void) {
|
||||
assert(status == .inactive || status == .restarting)
|
||||
assert(status == .inactive || status == .restarting || status == .waiting)
|
||||
|
||||
guard let tunnelConfiguration = tunnelConfiguration() else { fatalError() }
|
||||
|
||||
onDeactivationComplete = nil
|
||||
startActivation(tunnelConfiguration: tunnelConfiguration,
|
||||
completionHandler: completionHandler)
|
||||
}
|
||||
|
@ -356,6 +360,8 @@ class TunnelContainer: NSObject {
|
|||
s.status = TunnelStatus(from: connection.status)
|
||||
if (s.status == .inactive) {
|
||||
s.statusObservationToken = nil
|
||||
s.onDeactivationComplete?()
|
||||
s.onDeactivationComplete = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,6 +375,7 @@ class TunnelContainer: NSObject {
|
|||
case reasserting // Not a possible state at present
|
||||
|
||||
case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
|
||||
case waiting // Waiting for another tunnel to be brought down
|
||||
|
||||
init(from vpnStatus: NEVPNStatus) {
|
||||
switch (vpnStatus) {
|
||||
|
|
Loading…
Reference in New Issue