summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2026-01-20 17:01:28 +0100
committerEmīls <emils@mullvad.net>2026-01-20 17:01:28 +0100
commit074823cab41c7e4690f2d43eab8f4f42a2a635a1 (patch)
tree811e54d40750f51a01bb4ebb9b06cdc6f11ed59e
parent607782717d89680aedeabbb6fba060c7dbaf5ff3 (diff)
parent7c5b33c3d0295a5dd55b5b2e3dfb957f991e2777 (diff)
downloadmullvadvpn-074823cab41c7e4690f2d43eab8f4f42a2a635a1.tar.xz
mullvadvpn-074823cab41c7e4690f2d43eab8f4f42a2a635a1.zip
Merge branch 'app-enters-offline-state-before-connecting-with-ian-ios-1435'
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManager.swift39
1 files changed, 29 insertions, 10 deletions
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
index fee62d2a56..682607a68f 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
@@ -60,6 +60,11 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
private var networkMonitor: NWPathMonitor?
private let relaySelector: RelaySelectorProtocol
+ private var pendingNetworkPathUpdate: DispatchWorkItem?
+ private static let networkPathUpdateDelay: DispatchTimeInterval = .seconds(
+ 5
+ )
+
private var privateKeyRotationTimer: DispatchSourceTimer?
public private(set) var isRunningPeriodicPrivateKeyRotation = false
public private(set) var nextKeyRotationDate: Date?
@@ -106,6 +111,9 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
name: UIApplication.didBecomeActiveNotification,
object: nil
)
+
+ self.startNetworkMonitor()
+
}
// MARK: - Periodic private key rotation
@@ -197,8 +205,6 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
}
self.updatePrivateKeyRotationTimer()
- self.startNetworkMonitor()
-
completionHandler()
}
@@ -879,13 +885,6 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
guard let self else { return }
self.logger.debug("VPN connection status changed to \(status).")
-
- if [.disconnected, .invalid].contains(tunnel.status) {
- self.startNetworkMonitor()
- } else {
- self.cancelNetworkMonitor()
- }
-
self.updateTunnelStatus(status)
}
}
@@ -895,13 +894,33 @@ final class TunnelManager: StorePaymentObserver, @unchecked Sendable {
networkMonitor = NWPathMonitor()
networkMonitor?.pathUpdateHandler = { [weak self] path in
- self?.didUpdateNetworkPath(path)
+ self?.scheduleNetworkPathUpdate(path)
}
networkMonitor?.start(queue: internalQueue)
}
+ /// Schedule a network path update with a 1-second delay to debounce rapid changes.
+ private func scheduleNetworkPathUpdate(_ path: Network.NWPath) {
+ pendingNetworkPathUpdate?.cancel()
+
+ let workItem = DispatchWorkItem { [weak self] in
+ self?.didUpdateNetworkPath(path)
+ }
+ pendingNetworkPathUpdate = workItem
+
+ internalQueue
+ .asyncAfter(
+ deadline:
+ .now()
+ .advanced(by: Self.networkPathUpdateDelay),
+ execute: workItem
+ )
+ }
+
private func cancelNetworkMonitor() {
+ pendingNetworkPathUpdate?.cancel()
+ pendingNetworkPathUpdate = nil
networkMonitor?.pathUpdateHandler = nil
networkMonitor?.cancel()
networkMonitor = nil