@@ -206,14 +206,31 @@ class TunnelsManager {
206
206
}
207
207
}
208
208
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 ) {
210
213
let tunnelName = tunnelConfiguration. name ?? " "
211
214
if tunnelName. isEmpty {
212
215
completionHandler ( TunnelsManagerError . tunnelNameEmpty)
213
216
return
214
217
}
215
218
216
219
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
+
217
234
let oldName = tunnelProviderManager. localizedDescription ?? " "
218
235
let isNameChanged = tunnelName != oldName
219
236
if isNameChanged {
@@ -231,10 +248,11 @@ class TunnelsManager {
231
248
}
232
249
tunnelProviderManager. isEnabled = true
233
250
234
- let wasOnDemandEnabled = tunnelProviderManager. isOnDemandEnabled
235
- let isIntroducingOnDemandRules = ( tunnelProviderManager. onDemandRules ?? [ ] ) . isEmpty && onDemandOption != . off
251
+ let isActivatingOnDemand = !tunnelProviderManager. isOnDemandEnabled && shouldEnsureOnDemandEnabled
236
252
onDemandOption. apply ( on: tunnelProviderManager)
237
- let isActivatingOnDemand = !wasOnDemandEnabled && tunnelProviderManager. isOnDemandEnabled
253
+ if shouldEnsureOnDemandEnabled {
254
+ tunnelProviderManager. isOnDemandEnabled = true
255
+ }
238
256
239
257
tunnelProviderManager. saveToPreferences { [ weak self] error in
240
258
if let error = error {
@@ -266,11 +284,8 @@ class TunnelsManager {
266
284
if isActivatingOnDemand {
267
285
// Reload tunnel after saving.
268
286
// 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
270
288
tunnel. isActivateOnDemandEnabled = tunnelProviderManager. isOnDemandEnabled
271
- if isIntroducingOnDemandRules {
272
- self ? . startDeactivation ( of: tunnel)
273
- }
274
289
if let error = error {
275
290
wg_log ( . error, message: " Modify: Re-loading after saving configuration failed: \( error) " )
276
291
completionHandler ( TunnelsManagerError . systemErrorOnModifyTunnel ( systemError: error) )
@@ -279,9 +294,6 @@ class TunnelsManager {
279
294
}
280
295
}
281
296
} else {
282
- if isIntroducingOnDemandRules {
283
- self . startDeactivation ( of: tunnel)
284
- }
285
297
completionHandler ( nil )
286
298
}
287
299
}
@@ -507,6 +519,11 @@ class TunnelsManager {
507
519
}
508
520
}
509
521
522
+ if session. status == . disconnected {
523
+ tunnel. onDeactivated ? ( )
524
+ tunnel. onDeactivated = nil
525
+ }
526
+
510
527
if tunnel. status == . restarting && session. status == . disconnected {
511
528
tunnel. startActivation ( activationDelegate: self . activationDelegate)
512
529
return
@@ -577,6 +594,7 @@ class TunnelContainer: NSObject {
577
594
var activationAttemptId : String ?
578
595
var activationTimer : Timer ?
579
596
var deactivationTimer : Timer ?
597
+ var onDeactivated : ( ( ) -> Void ) ?
580
598
581
599
fileprivate var tunnelProvider : NETunnelProviderManager {
582
600
didSet {
0 commit comments