]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
UI: When saving on-demand rules, deactivate if reqd and then save
authorRoopesh Chander <roop@roopc.net>
Mon, 27 Sep 2021 10:37:20 +0000 (16:07 +0530)
committerRoopesh Chander <roop@roopc.net>
Mon, 27 Sep 2021 18:46:35 +0000 (00:16 +0530)
Signed-off-by: Roopesh Chander <roop@roopc.net>
Sources/WireGuardApp/Tunnel/ActivateOnDemandOption.swift
Sources/WireGuardApp/Tunnel/TunnelsManager.swift

index 9ba605a12a52a0b89db007f334918fe39e95f128..9697ce66c5ee1b2c8926ca126c1d0d20195841c6 100644 (file)
@@ -42,9 +42,7 @@ extension ActivateOnDemandOption {
             }
         }
         tunnelProviderManager.onDemandRules = rules
-        let status = tunnelProviderManager.connection.status
-        let isActive = status == .connected || status == .connecting
-        tunnelProviderManager.isOnDemandEnabled = (rules != nil) && (tunnelProviderManager.isOnDemandEnabled || isActive)
+        tunnelProviderManager.isOnDemandEnabled = (rules != nil) && tunnelProviderManager.isOnDemandEnabled
     }
 
     init(from tunnelProviderManager: NETunnelProviderManager) {
index 72aaf7cbb16eb3ac57f247b3682f01f101b7de80..7751e545792312f14d59cd86f2bfb681355d9592 100644 (file)
@@ -206,7 +206,10 @@ class TunnelsManager {
         }
     }
 
-    func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration, onDemandOption: ActivateOnDemandOption, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
+    func modify(tunnel: TunnelContainer, tunnelConfiguration: TunnelConfiguration,
+                onDemandOption: ActivateOnDemandOption,
+                shouldEnsureOnDemandEnabled: Bool = false,
+                completionHandler: @escaping (TunnelsManagerError?) -> Void) {
         let tunnelName = tunnelConfiguration.name ?? ""
         if tunnelName.isEmpty {
             completionHandler(TunnelsManagerError.tunnelNameEmpty)
@@ -214,6 +217,20 @@ class TunnelsManager {
         }
 
         let tunnelProviderManager = tunnel.tunnelProvider
+
+        let isIntroducingOnDemandRules = (tunnelProviderManager.onDemandRules ?? []).isEmpty && onDemandOption != .off
+        if isIntroducingOnDemandRules && tunnel.status != .inactive && tunnel.status != .deactivating {
+            tunnel.onDeactivated = { [weak self] in
+                self?.modify(tunnel: tunnel, tunnelConfiguration: tunnelConfiguration,
+                             onDemandOption: onDemandOption, shouldEnsureOnDemandEnabled: true,
+                             completionHandler: completionHandler)
+            }
+            self.startDeactivation(of: tunnel)
+            return
+        } else {
+            tunnel.onDeactivated = nil
+        }
+
         let oldName = tunnelProviderManager.localizedDescription ?? ""
         let isNameChanged = tunnelName != oldName
         if isNameChanged {
@@ -231,10 +248,11 @@ class TunnelsManager {
         }
         tunnelProviderManager.isEnabled = true
 
-        let wasOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled
-        let isIntroducingOnDemandRules = (tunnelProviderManager.onDemandRules ?? []).isEmpty && onDemandOption != .off
+        let isActivatingOnDemand = !tunnelProviderManager.isOnDemandEnabled && shouldEnsureOnDemandEnabled
         onDemandOption.apply(on: tunnelProviderManager)
-        let isActivatingOnDemand = !wasOnDemandEnabled && tunnelProviderManager.isOnDemandEnabled
+        if shouldEnsureOnDemandEnabled {
+            tunnelProviderManager.isOnDemandEnabled = true
+        }
 
         tunnelProviderManager.saveToPreferences { [weak self] error in
             if let error = error {
@@ -266,11 +284,8 @@ class TunnelsManager {
             if isActivatingOnDemand {
                 // Reload tunnel after saving.
                 // Without this, the tunnel stopes getting updates on the tunnel status from iOS.
-                tunnelProviderManager.loadFromPreferences { [weak self] error in
+                tunnelProviderManager.loadFromPreferences { error in
                     tunnel.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled
-                    if isIntroducingOnDemandRules {
-                        self?.startDeactivation(of: tunnel)
-                    }
                     if let error = error {
                         wg_log(.error, message: "Modify: Re-loading after saving configuration failed: \(error)")
                         completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel(systemError: error))
@@ -279,9 +294,6 @@ class TunnelsManager {
                     }
                 }
             } else {
-                if isIntroducingOnDemandRules {
-                    self.startDeactivation(of: tunnel)
-                }
                 completionHandler(nil)
             }
         }
@@ -507,6 +519,11 @@ class TunnelsManager {
                 }
             }
 
+            if session.status == .disconnected {
+                tunnel.onDeactivated?()
+                tunnel.onDeactivated = nil
+            }
+
             if tunnel.status == .restarting && session.status == .disconnected {
                 tunnel.startActivation(activationDelegate: self.activationDelegate)
                 return
@@ -577,6 +594,7 @@ class TunnelContainer: NSObject {
     var activationAttemptId: String?
     var activationTimer: Timer?
     var deactivationTimer: Timer?
+    var onDeactivated: (() -> Void)?
 
     fileprivate var tunnelProvider: NETunnelProviderManager {
         didSet {