@@ -206,14 +206,31 @@ class TunnelsManager {
206206 }
207207 }
208208
209- func modify( tunnel: TunnelContainer , tunnelConfiguration: TunnelConfiguration , onDemandOption: ActivateOnDemandOption , completionHandler: @escaping ( TunnelsManagerError ? ) -> Void ) {
209+ func modify( tunnel: TunnelContainer , tunnelConfiguration: TunnelConfiguration ,
210+ onDemandOption: ActivateOnDemandOption ,
211+ shouldEnsureOnDemandEnabled: Bool = false ,
212+ completionHandler: @escaping ( TunnelsManagerError ? ) -> Void ) {
210213 let tunnelName = tunnelConfiguration. name ?? " "
211214 if tunnelName. isEmpty {
212215 completionHandler ( TunnelsManagerError . tunnelNameEmpty)
213216 return
214217 }
215218
216219 let tunnelProviderManager = tunnel. tunnelProvider
220+
221+ let isIntroducingOnDemandRules = ( tunnelProviderManager. onDemandRules ?? [ ] ) . isEmpty && onDemandOption != . off
222+ if isIntroducingOnDemandRules && tunnel. status != . inactive && tunnel. status != . deactivating {
223+ tunnel. onDeactivated = { [ weak self] in
224+ self ? . modify ( tunnel: tunnel, tunnelConfiguration: tunnelConfiguration,
225+ onDemandOption: onDemandOption, shouldEnsureOnDemandEnabled: true ,
226+ completionHandler: completionHandler)
227+ }
228+ self . startDeactivation ( of: tunnel)
229+ return
230+ } else {
231+ tunnel. onDeactivated = nil
232+ }
233+
217234 let oldName = tunnelProviderManager. localizedDescription ?? " "
218235 let isNameChanged = tunnelName != oldName
219236 if isNameChanged {
@@ -231,10 +248,11 @@ class TunnelsManager {
231248 }
232249 tunnelProviderManager. isEnabled = true
233250
234- let wasOnDemandEnabled = tunnelProviderManager. isOnDemandEnabled
235- let isIntroducingOnDemandRules = ( tunnelProviderManager. onDemandRules ?? [ ] ) . isEmpty && onDemandOption != . off
251+ let isActivatingOnDemand = !tunnelProviderManager. isOnDemandEnabled && shouldEnsureOnDemandEnabled
236252 onDemandOption. apply ( on: tunnelProviderManager)
237- let isActivatingOnDemand = !wasOnDemandEnabled && tunnelProviderManager. isOnDemandEnabled
253+ if shouldEnsureOnDemandEnabled {
254+ tunnelProviderManager. isOnDemandEnabled = true
255+ }
238256
239257 tunnelProviderManager. saveToPreferences { [ weak self] error in
240258 if let error = error {
@@ -266,11 +284,8 @@ class TunnelsManager {
266284 if isActivatingOnDemand {
267285 // Reload tunnel after saving.
268286 // Without this, the tunnel stopes getting updates on the tunnel status from iOS.
269- tunnelProviderManager. loadFromPreferences { [ weak self ] error in
287+ tunnelProviderManager. loadFromPreferences { error in
270288 tunnel. isActivateOnDemandEnabled = tunnelProviderManager. isOnDemandEnabled
271- if isIntroducingOnDemandRules {
272- self ? . startDeactivation ( of: tunnel)
273- }
274289 if let error = error {
275290 wg_log ( . error, message: " Modify: Re-loading after saving configuration failed: \( error) " )
276291 completionHandler ( TunnelsManagerError . systemErrorOnModifyTunnel ( systemError: error) )
@@ -279,9 +294,6 @@ class TunnelsManager {
279294 }
280295 }
281296 } else {
282- if isIntroducingOnDemandRules {
283- self . startDeactivation ( of: tunnel)
284- }
285297 completionHandler ( nil )
286298 }
287299 }
@@ -507,6 +519,11 @@ class TunnelsManager {
507519 }
508520 }
509521
522+ if session. status == . disconnected {
523+ tunnel. onDeactivated ? ( )
524+ tunnel. onDeactivated = nil
525+ }
526+
510527 if tunnel. status == . restarting && session. status == . disconnected {
511528 tunnel. startActivation ( activationDelegate: self . activationDelegate)
512529 return
@@ -577,6 +594,7 @@ class TunnelContainer: NSObject {
577594 var activationAttemptId : String ?
578595 var activationTimer : Timer ?
579596 var deactivationTimer : Timer ?
597+ var onDeactivated : ( ( ) -> Void ) ?
580598
581599 fileprivate var tunnelProvider : NETunnelProviderManager {
582600 didSet {
0 commit comments