summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2024-08-27 10:20:50 +0200
committerBug Magnet <marco.nikic@mullvad.net>2024-08-27 10:20:50 +0200
commit3388f5d5591c7bd704ab06839a651b5c46802425 (patch)
tree076a77de9def351db14141e2019cd2dd5dee690f
parent9d922b2bae3eb7cebcf19bada560984d5903a065 (diff)
parentecee6b61bc69accb647f3300f5d66cd8f8660142 (diff)
downloadmullvadvpn-3388f5d5591c7bd704ab06839a651b5c46802425.tar.xz
mullvadvpn-3388f5d5591c7bd704ab06839a651b5c46802425.zip
Merge branch 'packet-tunnel-stuck-in-blocked-state-after-flightmode-ios-707'
-rw-r--r--ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift1
-rw-r--r--ios/PacketTunnelCore/Actor/State+Extensions.swift6
-rw-r--r--ios/PacketTunnelCore/Actor/Timings.swift4
-rw-r--r--ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift47
4 files changed, 52 insertions, 6 deletions
diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift
index de3fe8cb7a..4b4a95c406 100644
--- a/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift
+++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor+ErrorState.swift
@@ -104,6 +104,7 @@ extension PacketTunnelActor {
currentKey: connState.currentKey,
keyPolicy: connState.keyPolicy,
networkReachability: connState.networkReachability,
+ recoveryTask: startRecoveryTaskIfNeeded(reason: reason),
priorState: priorState
)
}
diff --git a/ios/PacketTunnelCore/Actor/State+Extensions.swift b/ios/PacketTunnelCore/Actor/State+Extensions.swift
index 4399942ead..d784b46451 100644
--- a/ios/PacketTunnelCore/Actor/State+Extensions.swift
+++ b/ios/PacketTunnelCore/Actor/State+Extensions.swift
@@ -188,16 +188,16 @@ extension BlockedStateReason {
- Keychain and filesystem are locked on boot until user unlocks device in the very first time.
- App update that requires settings schema migration. Packet tunnel will be automatically restarted after update but it would not be able to read settings until
user opens the app which performs migration.
+ - Packet tunnel will be automatically restarted when there is a tunnel adapter error.
*/
var shouldRestartAutomatically: Bool {
switch self {
- case .deviceLocked:
+ case .deviceLocked, .tunnelAdapter:
return true
-
case .noRelaysSatisfyingConstraints, .noRelaysSatisfyingFilterConstraints,
.multihopEntryEqualsExit,
.noRelaysSatisfyingDaitaConstraints, .readSettings, .invalidAccount, .accountExpired, .deviceRevoked,
- .tunnelAdapter, .unknown, .deviceLoggedOut, .outdatedSchema, .invalidRelayPublicKey:
+ .unknown, .deviceLoggedOut, .outdatedSchema, .invalidRelayPublicKey:
return false
}
}
diff --git a/ios/PacketTunnelCore/Actor/Timings.swift b/ios/PacketTunnelCore/Actor/Timings.swift
index 4e2d5d8b77..5a62f7b058 100644
--- a/ios/PacketTunnelCore/Actor/Timings.swift
+++ b/ios/PacketTunnelCore/Actor/Timings.swift
@@ -11,7 +11,7 @@ import MullvadTypes
/// Struct holding all timings used by tunnel actor.
public struct PacketTunnelActorTimings {
- /// Periodicity at which actor will attempt to restart when an error occurred on system boot when filesystem is locked until device is unlocked.
+ /// Periodicity at which actor will attempt to restart when an error occurred on system boot when filesystem is locked until device is unlocked or tunnel adapter error.
public var bootRecoveryPeriodicity: Duration
/// Time that takes for new WireGuard key to propagate across relays.
@@ -19,7 +19,7 @@ public struct PacketTunnelActorTimings {
/// Designated initializer.
public init(
- bootRecoveryPeriodicity: Duration = .seconds(10),
+ bootRecoveryPeriodicity: Duration = .seconds(5),
wgKeyPropagationDelay: Duration = .seconds(120)
) {
self.bootRecoveryPeriodicity = bootRecoveryPeriodicity
diff --git a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
index 1d649b59a3..cdea29460d 100644
--- a/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
+++ b/ios/PacketTunnelCoreTests/PacketTunnelActorTests.swift
@@ -12,10 +12,11 @@ import Combine
@testable import MullvadSettings
import MullvadTypes
import Network
-@testable import PacketTunnelCore
import WireGuardKitTypes
import XCTest
+@testable import PacketTunnelCore
+
final class PacketTunnelActorTests: XCTestCase {
private var stateSink: Combine.Cancellable?
private let launchOptions = StartOptions(launchSource: .app)
@@ -446,6 +447,48 @@ final class PacketTunnelActorTests: XCTestCase {
actor.reconnect(to: .random, reconnectReason: .userInitiated)
await fulfillment(of: [stopMonitorExpectation], timeout: .UnitTest.timeout)
}
+
+ func testRecoveringConnectionAfterTunnelAdaptorError() async throws {
+ let errorStateExpectation = expectation(description: "Expect error state")
+ let connectingStateExpectation = expectation(description: "Expect connecting state")
+ connectingStateExpectation.expectedFulfillmentCount = 2
+ let connectedStateExpectation = expectation(description: "Expect connected state")
+
+ let blockedStateMapper = BlockedStateErrorMapperStub { error in
+ if error is TunnelAdapterErrorStub {
+ return .tunnelAdapter
+ } else {
+ return .unknown
+ }
+ }
+
+ let actor = PacketTunnelActor.mock(blockedStateErrorMapper: blockedStateMapper)
+
+ actor.start(options: launchOptions)
+
+ stateSink = await actor.$observedState
+ .receive(on: DispatchQueue.main)
+ .sink { newState in
+ switch newState {
+ case .error:
+ errorStateExpectation.fulfill()
+ case .connecting:
+ connectingStateExpectation.fulfill()
+ case .connected:
+ connectedStateExpectation.fulfill()
+ default:
+ break
+ }
+ }
+
+ actor.setErrorState(reason: .tunnelAdapter)
+
+ await fulfillment(
+ of: [errorStateExpectation, connectingStateExpectation, connectedStateExpectation],
+ timeout: .UnitTest.timeout,
+ enforceOrder: true
+ )
+ }
}
extension PacketTunnelActorTests {
@@ -470,4 +513,6 @@ extension PacketTunnelActorTests {
}
}
+struct TunnelAdapterErrorStub: Error {}
+
// swiftlint:disable:this file_length