summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJon Petersson <jon.petersson@mullvad.net>2025-10-07 12:37:55 +0200
committerJon Petersson <jon.petersson@mullvad.net>2025-10-14 09:54:28 +0200
commit0cc99647448b899b9f39c31e36620f4d42b464c4 (patch)
tree45dc23c90695080045f3a999657cb9b6d284a6dc
parentfe1844b2c887cace39aeac0f57c41d7e8b2d7d09 (diff)
downloadmullvadvpn-0cc99647448b899b9f39c31e36620f4d42b464c4.tar.xz
mullvadvpn-0cc99647448b899b9f39c31e36620f4d42b464c4.zip
Fix quantum exchange hot loop
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift15
-rw-r--r--ios/PacketTunnelCore/Actor/NetworkPath+NetworkReachability.swift2
-rw-r--r--ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift2
3 files changed, 13 insertions, 6 deletions
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index 063d8f681d..9852e4a4e4 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -28,6 +28,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
private var relaySelector: RelaySelectorWrapper!
private var ephemeralPeerExchangingPipeline: EphemeralPeerExchangingPipeline!
private let tunnelSettingsUpdater: SettingsUpdater!
+ private let pathObserver: PacketTunnelPathObserver!
private var encryptedDNSTransport: EncryptedDNSTransport!
private var migrationManager: MigrationManager!
let migrationFailureIterator = REST.RetryStrategy.failedMigrationRecovery.makeDelayIterator()
@@ -57,6 +58,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
tunnelSettingsUpdater = SettingsUpdater(listener: tunnelSettingsListener)
migrationManager = MigrationManager(cacheDirectory: containerURL)
+ pathObserver = PacketTunnelPathObserver(eventQueue: internalQueue)
+
super.init()
performSettingsMigration()
@@ -102,7 +105,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
timings: PacketTunnelActorTimings(),
tunnelAdapter: adapter,
tunnelMonitor: tunnelMonitor,
- defaultPathObserver: PacketTunnelPathObserver(eventQueue: internalQueue),
+ defaultPathObserver: pathObserver,
blockedStateErrorMapper: BlockedStateErrorMapper(),
relaySelector: relaySelector,
settingsReader: TunnelSettingsManager(settingsReader: SettingsReader()) { [weak self] settings in
@@ -446,8 +449,12 @@ extension PacketTunnelProvider: EphemeralPeerReceiving {
}
func ephemeralPeerExchangeFailed() {
- // Do not try reconnecting to the `.current` relay, else the actor's `State` equality check will fail
- // and it will not try to reconnect
- actor.reconnect(to: .random, reconnectReason: .connectionLoss)
+ // Do not retry connection unless there's network reachability. Doing so will lead to a hot loop where
+ // connections are retried every time peer exchange fails, which it will if reachability is not satisfied.
+ if pathObserver.currentPathStatus.networkReachability == .reachable {
+ // Do not try reconnecting to the `.current` relay, else the actor's `State` equality check will fail
+ // and it will not try to reconnect
+ actor.reconnect(to: .random, reconnectReason: .connectionLoss)
+ }
}
}
diff --git a/ios/PacketTunnelCore/Actor/NetworkPath+NetworkReachability.swift b/ios/PacketTunnelCore/Actor/NetworkPath+NetworkReachability.swift
index 4c4cd719f8..1566d98744 100644
--- a/ios/PacketTunnelCore/Actor/NetworkPath+NetworkReachability.swift
+++ b/ios/PacketTunnelCore/Actor/NetworkPath+NetworkReachability.swift
@@ -11,7 +11,7 @@ import Network
extension Network.NWPath.Status {
/// Converts `NetworkPath.status` into `NetworkReachability`.
- var networkReachability: NetworkReachability {
+ public var networkReachability: NetworkReachability {
switch self {
case .satisfied:
.reachable
diff --git a/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift b/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift
index 89cbe5e810..a286471562 100644
--- a/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift
+++ b/ios/PacketTunnelCore/TunnelMonitor/TunnelMonitor.swift
@@ -123,7 +123,7 @@ public final class TunnelMonitor: TunnelMonitorProtocol, @unchecked Sendable {
public func handleNetworkPathUpdate(_ networkPath: Network.NWPath.Status) {
nslock.withLock {
- let isReachable = networkPath == .satisfied || networkPath == .requiresConnection
+ let isReachable = networkPath.networkReachability == .reachable
switch state.connectionState {
case .pendingStart: