From f9239dae751780efee17af31359413fc57e1e002 Mon Sep 17 00:00:00 2001 From: Roopesh Chander Date: Thu, 13 Dec 2018 23:13:54 +0530 Subject: [PATCH] TunnelsManager: Reintroduce waiting for another tunnel to deactivate Signed-off-by: Roopesh Chander --- .../WireGuard/Tunnel/TunnelsManager.swift | 24 ++++++++++++++++--- .../iOS/TunnelDetailTableViewController.swift | 2 ++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift index 1e4823f..8f53ef9 100644 --- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift +++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift @@ -258,9 +258,17 @@ class TunnelsManager { return } + if let alreadyWaitingTunnel = tunnels.first(where: { $0.status == .waiting }) { + alreadyWaitingTunnel.status = .inactive + } + if let tunnelInOperation = tunnels.first(where: { $0.status != .inactive }) { - self.activationDelegate?.tunnelActivationAttemptFailed(tunnel: tunnel, error: .anotherTunnelIsOperational(otherTunnelName: tunnelInOperation.name)) - // FIXME: Switches in the UI won't be reset, but we'll be reintroducing waiting, so that's fine + wg_log(.info, message: "Tunnel '\(tunnel.name)' waiting for deactivation of '\(tunnelInOperation.name)'") + tunnel.status = .waiting + assert(tunnelInOperation.status != .inactive) + if tunnelInOperation.status != .deactivating { + startDeactivation(of: tunnelInOperation) + } return } @@ -269,6 +277,7 @@ class TunnelsManager { } func startDeactivation(of tunnel: TunnelContainer) { + tunnel.isAttemptingActivation = false if tunnel.status == .inactive || tunnel.status == .deactivating { return } @@ -312,6 +321,13 @@ class TunnelsManager { } tunnel.refreshStatus() + + // In case some other tunnel is waiting for this tunnel to get deactivated + if session.status == .disconnected || session.status == .invalid { + if let waitingTunnel = self.tunnels.first(where: { $0.status == .waiting }) { + waitingTunnel.startActivation(activationDelegate: self.activationDelegate) + } + } } } @@ -357,7 +373,7 @@ class TunnelContainer: NSObject { } fileprivate func startActivation(activationDelegate: TunnelsManagerActivationDelegate?) { - assert(status == .inactive || status == .restarting) + assert(status == .inactive || status == .restarting || status == .waiting) guard let tunnelConfiguration = tunnelConfiguration() else { fatalError() } @@ -446,6 +462,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 systemStatus: NEVPNStatus) { switch systemStatus { @@ -474,6 +491,7 @@ extension TunnelStatus: CustomDebugStringConvertible { case .deactivating: return "deactivating" case .reasserting: return "reasserting" case .restarting: return "restarting" + case .waiting: return "waiting" } } } diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift index 93b35e4..887c737 100644 --- a/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift +++ b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift @@ -270,6 +270,8 @@ private class StatusCell: UITableViewCell { text = "Reactivating" case .restarting: text = "Restarting" + case .waiting: + text = "Waiting" } textLabel?.text = text DispatchQueue.main.async { [weak statusSwitch] in