summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadREST/Relay/ObfuscationMethodSelector.swift4
-rw-r--r--ios/MullvadREST/Relay/RelaySelector.swift14
-rw-r--r--ios/MullvadREST/Relay/RelaySelectorWrapper.swift44
-rw-r--r--ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift6
-rw-r--r--ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift45
-rw-r--r--ios/MullvadVPNTests/MullvadREST/Relay/ObfuscationMethodSelectorTests.swift6
-rw-r--r--ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorTests.swift17
-rw-r--r--ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift76
-rw-r--r--ios/MullvadVPNUITests/Pages/TunnelControlPage.swift24
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/BlockedStateErrorMapper.swift2
-rw-r--r--ios/PacketTunnelCore/Actor/State+Extensions.swift3
-rw-r--r--ios/PacketTunnelCore/Actor/State.swift5
-rw-r--r--ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift6
13 files changed, 192 insertions, 60 deletions
diff --git a/ios/MullvadREST/Relay/ObfuscationMethodSelector.swift b/ios/MullvadREST/Relay/ObfuscationMethodSelector.swift
index dcc7cf05da..f73509affe 100644
--- a/ios/MullvadREST/Relay/ObfuscationMethodSelector.swift
+++ b/ios/MullvadREST/Relay/ObfuscationMethodSelector.swift
@@ -17,9 +17,9 @@ public struct ObfuscationMethodSelector {
) -> WireGuardObfuscationState {
// TODO: Revisit this when QUIC obfuscation is added
if tunnelSettings.wireGuardObfuscation.state == .automatic {
- if connectionAttemptCount.isOrdered(nth: 3, forEverySetOf: 4) {
+ if connectionAttemptCount.isOrdered(nth: 2, forEverySetOf: 3) {
.shadowsocks
- } else if connectionAttemptCount.isOrdered(nth: 4, forEverySetOf: 4) {
+ } else if connectionAttemptCount.isOrdered(nth: 3, forEverySetOf: 3) {
.udpOverTcp
} else {
.off
diff --git a/ios/MullvadREST/Relay/RelaySelector.swift b/ios/MullvadREST/Relay/RelaySelector.swift
index 14742aef09..8393f997e6 100644
--- a/ios/MullvadREST/Relay/RelaySelector.swift
+++ b/ios/MullvadREST/Relay/RelaySelector.swift
@@ -9,8 +9,6 @@
import MullvadSettings
import MullvadTypes
-private let defaultPort: UInt16 = 443
-
public enum RelaySelector {
// MARK: - public
@@ -83,17 +81,11 @@ public enum RelaySelector {
rawPortRanges: [[UInt16]],
numberOfFailedAttempts: UInt
) -> UInt16? {
- switch portConstraint {
+ return switch portConstraint {
case let .only(port):
- return port
-
+ port
case .any:
- // 1. First attempt should pick a random port.
- // 2. The second should pick port 443.
- // 3. Repeat steps 1 and 2.
- let useDefaultPort = numberOfFailedAttempts.isOrdered(nth: 2, forEverySetOf: 2)
-
- return useDefaultPort ? defaultPort : pickRandomPort(rawPortRanges: rawPortRanges)
+ pickRandomPort(rawPortRanges: rawPortRanges)
}
}
diff --git a/ios/MullvadREST/Relay/RelaySelectorWrapper.swift b/ios/MullvadREST/Relay/RelaySelectorWrapper.swift
index c52a0a2faf..1a6487dca9 100644
--- a/ios/MullvadREST/Relay/RelaySelectorWrapper.swift
+++ b/ios/MullvadREST/Relay/RelaySelectorWrapper.swift
@@ -20,7 +20,14 @@ public final class RelaySelectorWrapper: RelaySelectorProtocol, Sendable {
tunnelSettings: LatestTunnelSettings,
connectionAttemptCount: UInt
) throws -> SelectedRelays {
- let obfuscation = try prepareObfuscation(for: tunnelSettings, connectionAttemptCount: connectionAttemptCount)
+ let relays = try relayCache.read().relays
+ try validateWireguardPort(tunnelSettings, relays: relays)
+
+ let obfuscation = try prepareObfuscation(
+ for: tunnelSettings,
+ connectionAttemptCount: connectionAttemptCount,
+ relays: relays
+ )
return switch tunnelSettings.tunnelMultihopState {
case .off:
@@ -41,7 +48,12 @@ public final class RelaySelectorWrapper: RelaySelectorProtocol, Sendable {
}
public func findCandidates(tunnelSettings: LatestTunnelSettings) throws -> RelayCandidates {
- let obfuscation = try prepareObfuscation(for: tunnelSettings, connectionAttemptCount: 0)
+ let relays = try relayCache.read().relays
+ let obfuscation = try prepareObfuscation(
+ for: tunnelSettings,
+ connectionAttemptCount: 0,
+ relays: relays
+ )
let findCandidates: (REST.ServerRelaysResponse, Bool) throws
-> [RelayWithLocation<REST.ServerRelay>] = { relays, daitaEnabled in
@@ -68,12 +80,36 @@ public final class RelaySelectorWrapper: RelaySelectorProtocol, Sendable {
private func prepareObfuscation(
for tunnelSettings: LatestTunnelSettings,
- connectionAttemptCount: UInt
+ connectionAttemptCount: UInt,
+ relays: REST.ServerRelaysResponse
) throws -> ObfuscatorPortSelection {
- let relays = try relayCache.read().relays
return try ObfuscatorPortSelector(relays: relays).obfuscate(
tunnelSettings: tunnelSettings,
connectionAttemptCount: connectionAttemptCount
)
}
+
+ private func validateWireguardPort(
+ _ tunnelSettings: LatestTunnelSettings,
+ relays: REST.ServerRelaysResponse
+ ) throws {
+ switch tunnelSettings.wireGuardObfuscation.state {
+ case .automatic, .off:
+ if case let .only(port) = tunnelSettings.relayConstraints.port {
+ let isPortWithinValidWireGuardRanges: Bool =
+ relays.wireguard.portRanges
+ .contains { range in
+ if let minPort = range.first, let maxPort = range.last {
+ return (minPort ... maxPort).contains(port)
+ }
+ return false
+ }
+ guard isPortWithinValidWireGuardRanges else {
+ throw NoRelaysSatisfyingConstraintsError(.invalidPort)
+ }
+ }
+ case .on, .udpOverTcp, .quic, .shadowsocks:
+ break
+ }
+ }
}
diff --git a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
index b68577ba14..7aa56ed588 100644
--- a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
+++ b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
@@ -823,6 +823,12 @@ final class ApplicationCoordinator: Coordinator, Presenting, @preconcurrency Roo
updateDeviceInfo(deviceState: tunnelManager.deviceState)
case .latestChangesInAppNotificationProvider:
router.present(.changelog)
+ case .tunnelStatusNotificationProvider:
+ switch response.actionIdentifier {
+ case TunnelStatusNotificationProvider.ActionIdentifier.showVPNSettings.rawValue:
+ router.present(.settings(.vpnSettings))
+ default: break
+ }
default: return
}
}
diff --git a/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift b/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
index e0135cb44f..43eba09131 100644
--- a/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/Notification Providers/TunnelStatusNotificationProvider.swift
@@ -8,8 +8,13 @@
import Foundation
import PacketTunnelCore
+import UIKit
final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotificationProvider, @unchecked Sendable {
+ enum ActionIdentifier: String {
+ case showVPNSettings
+ }
+
private var isWaitingForConnectivity = false
private var noNetwork = false
private var packetTunnelError: BlockedStateReason?
@@ -135,7 +140,19 @@ final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotific
}
private func notificationDescription(for packetTunnelError: BlockedStateReason) -> InAppNotificationDescriptor {
- InAppNotificationDescriptor(
+ let tapAction: InAppNotificationAction? = switch packetTunnelError {
+ case .noRelaysSatisfyingPortConstraints:
+ InAppNotificationAction {
+ NotificationManager.shared
+ .notificationProvider(
+ self,
+ didReceiveAction: "\(ActionIdentifier.showVPNSettings)"
+ )
+ }
+ default:
+ nil
+ }
+ return InAppNotificationDescriptor(
identifier: identifier,
style: .error,
title: NSLocalizedString(
@@ -143,13 +160,23 @@ final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotific
value: "BLOCKING INTERNET",
comment: ""
),
- body: .init(string: String(
- format: NSLocalizedString(
- "TUNNEL_BLOCKED_INAPP_NOTIFICATION_BODY",
- value: localizedReasonForBlockedStateError(packetTunnelError),
- comment: ""
- )
- ))
+ body: createNotificationBody(localizedReasonForBlockedStateError(packetTunnelError)),
+ tapAction: tapAction
+ )
+ }
+
+ private func createNotificationBody(_ string: String) -> NSAttributedString {
+ NSAttributedString(
+ markdownString: NSLocalizedString(
+ "LATEST_CHANGES_IN_APP_NOTIFICATION_BODY",
+ value: string,
+ comment: ""
+ ),
+ options: MarkdownStylingOptions(font: UIFont.preferredFont(forTextStyle: .body)),
+ applyEffect: { markdownType, _ in
+ guard case .bold = markdownType else { return [:] }
+ return [.foregroundColor: UIColor.InAppNotificationBanner.titleColor]
+ }
)
}
@@ -248,6 +275,8 @@ final class TunnelStatusNotificationProvider: NotificationProvider, InAppNotific
errorString = "No DAITA compatible servers match your location settings. Try changing location."
case .noRelaysSatisfyingConstraints:
errorString = "No servers match your settings, try changing server or other settings."
+ case .noRelaysSatisfyingPortConstraints:
+ errorString = "The selected WireGuard port is not supported, please change it under **VPN settings**."
case .invalidAccount:
errorString = "You are logged in with an invalid account number. Please log out and try another one."
case .deviceLoggedOut:
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscationMethodSelectorTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscationMethodSelectorTests.swift
index 6fb2be5a25..3694076db0 100644
--- a/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscationMethodSelectorTests.swift
+++ b/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscationMethodSelectorTests.swift
@@ -29,7 +29,7 @@ class ObfuscationMethodSelectorTests: XCTestCase {
connectionAttemptCount: attempt,
tunnelSettings: tunnelSettings
)
- if attempt.isOrdered(nth: 1, forEverySetOf: 4) || attempt.isOrdered(nth: 2, forEverySetOf: 4) {
+ if attempt.isOrdered(nth: 1, forEverySetOf: 3) {
XCTAssertEqual(method, .off)
} else {
XCTAssertNotEqual(method, .off)
@@ -53,7 +53,7 @@ class ObfuscationMethodSelectorTests: XCTestCase {
connectionAttemptCount: attempt,
tunnelSettings: tunnelSettings
)
- if attempt.isOrdered(nth: 3, forEverySetOf: 4) {
+ if attempt.isOrdered(nth: 2, forEverySetOf: 3) {
XCTAssertEqual(method, .shadowsocks)
} else {
XCTAssertNotEqual(method, .shadowsocks)
@@ -77,7 +77,7 @@ class ObfuscationMethodSelectorTests: XCTestCase {
connectionAttemptCount: attempt,
tunnelSettings: tunnelSettings
)
- if attempt.isOrdered(nth: 4, forEverySetOf: 4) {
+ if attempt.isOrdered(nth: 3, forEverySetOf: 3) {
XCTAssertEqual(method, .udpOverTcp)
} else {
XCTAssertNotEqual(method, .udpOverTcp)
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorTests.swift
index e383aa1b25..fcc71b4653 100644
--- a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorTests.swift
+++ b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorTests.swift
@@ -15,7 +15,6 @@ import Network
import XCTest
private let portRanges: [[UInt16]] = [[4000, 4001], [5000, 5001]]
-private let defaultPort: UInt16 = 443
class RelaySelectorTests: XCTestCase {
let sampleRelays = ServerRelaysResponseStubs.sampleRelays
@@ -114,25 +113,13 @@ class RelaySelectorTests: XCTestCase {
XCTAssertEqual(result.endpoint.ipv4Relay.port, 1)
}
- func testRandomPortSelectionWithFailedAttempts() throws {
+ func testRandomPortSelection() throws {
let constraints = RelayConstraints(
exitLocations: .only(UserSelectedRelays(locations: [.hostname("se", "sto", "se6-wireguard")]))
)
let allPorts = portRanges.flatMap { $0 }
- var result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 0)
- XCTAssertTrue(allPorts.contains(result.endpoint.ipv4Relay.port))
-
- result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 1)
- XCTAssertEqual(result.endpoint.ipv4Relay.port, defaultPort)
-
- result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 2)
- XCTAssertTrue(allPorts.contains(result.endpoint.ipv4Relay.port))
-
- result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 3)
- XCTAssertEqual(result.endpoint.ipv4Relay.port, defaultPort)
-
- result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 4)
+ let result = try pickRelay(by: constraints, in: sampleRelays, failedAttemptCount: 0)
XCTAssertTrue(allPorts.contains(result.endpoint.ipv4Relay.port))
}
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
index b84cb528b8..0302ad5380 100644
--- a/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
+++ b/ios/MullvadVPNTests/MullvadREST/Relay/RelaySelectorWrapperTests.swift
@@ -120,4 +120,80 @@ class RelaySelectorWrapperTests: XCTestCase {
let selectedRelays = try wrapper.selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
XCTAssertNotNil(selectedRelays.entry)
}
+
+ func testValidWireguardPortDoesNotThrow() throws {
+ let wrapper = RelaySelectorWrapper(relayCache: relayCache)
+
+ let settings = LatestTunnelSettings(
+ relayConstraints: .init(
+ port:
+ .only(
+ ServerRelaysResponseStubs.sampleRelays.wireguard.portRanges.first!.first!
+ )
+ )
+ )
+
+ XCTAssertNoThrow(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+ }
+
+ func testInvalidWireguardPortThrows() throws {
+ let wrapper = RelaySelectorWrapper(relayCache: relayCache)
+
+ var settings = LatestTunnelSettings(
+ relayConstraints: .init(port: .only(1)),
+ wireGuardObfuscation: .init(state: .automatic)
+ )
+
+ XCTAssertThrowsError(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+
+ settings = LatestTunnelSettings(
+ relayConstraints: .init(port: .only(1)),
+ wireGuardObfuscation: .init(state: .off)
+ )
+
+ XCTAssertThrowsError(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+ }
+
+ func testInvalidWireguardPortDoesNotThrowWhenObfuscated() throws {
+ let wrapper = RelaySelectorWrapper(relayCache: relayCache)
+
+ var settings = LatestTunnelSettings(
+ relayConstraints: .init(port: .only(1)),
+ wireGuardObfuscation: .init(state: .quic)
+ )
+
+ XCTAssertNoThrow(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+
+ settings = LatestTunnelSettings(
+ relayConstraints: .init(port: .only(1)),
+ wireGuardObfuscation: .init(state: .udpOverTcp)
+ )
+
+ XCTAssertNoThrow(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+
+ settings = LatestTunnelSettings(
+ relayConstraints: .init(port: .only(1)),
+ wireGuardObfuscation: .init(state: .shadowsocks)
+ )
+
+ XCTAssertNoThrow(
+ try wrapper
+ .selectRelays(tunnelSettings: settings, connectionAttemptCount: 0)
+ )
+ }
}
diff --git a/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift b/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift
index 9a1039dfcc..c2996c6741 100644
--- a/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift
+++ b/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift
@@ -131,32 +131,32 @@ class TunnelControlPage: Page {
/// Verify that the app attempts to connect over UDP before switching to TCP. For testing blocked UDP traffic.
@discardableResult func verifyConnectingOverTCPAfterUDPAttempts() -> Self {
- let connectionAttempts = waitForConnectionAttempts(4, timeout: 30)
+ let connectionAttempts = waitForConnectionAttempts(3, timeout: 30)
// TODO: Revisit this when QUIC obfuscation is added
- // Should do four connection attempts but due to UI bug sometimes only two are displayed, sometimes all four
- if connectionAttempts.count == 4 { // Expected retries flow
+ // Should do three connection attempts but due to UI bug sometimes only two are displayed, sometimes all three
+ if connectionAttempts.count == 3 { // Expected retries flow
for (attemptIndex, attempt) in connectionAttempts.enumerated() {
- if attemptIndex < 3 {
+ if attemptIndex < 2 {
XCTAssertEqual(attempt.protocolName, "UDP")
- } else if attemptIndex == 3 {
+ } else if attemptIndex == 2 {
XCTAssertEqual(attempt.protocolName, "TCP")
} else {
XCTFail("Unexpected connection attempt")
}
}
- } else if connectionAttempts.count == 3 { // Most of the times this incorrect flow is shown
+ } else if connectionAttempts.count == 2 { // Most of the times this incorrect flow is shown
for (attemptIndex, attempt) in connectionAttempts.enumerated() {
- if attemptIndex == 0 || attemptIndex == 1 {
+ if attemptIndex == 0 {
XCTAssertEqual(attempt.protocolName, "UDP")
- } else if attemptIndex == 2 {
+ } else if attemptIndex == 1 {
XCTAssertEqual(attempt.protocolName, "TCP")
} else {
XCTFail("Unexpected connection attempt")
}
}
} else {
- XCTFail("Unexpected number of connection attempts, expected 3~4, got \(connectionAttempts.count)")
+ XCTFail("Unexpected number of connection attempts, expected 2~3, got \(connectionAttempts.count)")
}
return self
@@ -164,9 +164,9 @@ class TunnelControlPage: Page {
/// Verify that connection attempts are made in the correct order
@discardableResult func verifyConnectionAttemptsOrder() -> Self {
- var connectionAttempts = waitForConnectionAttempts(4, timeout: 80)
+ var connectionAttempts = waitForConnectionAttempts(3, timeout: 80)
var totalAttemptsOffset = 0
- XCTAssertEqual(connectionAttempts.count, 4)
+ XCTAssertEqual(connectionAttempts.count, 3)
/// Sometimes, the UI will only show an IP address for the first connection attempt, which gets skipped by
/// `waitForConnectionAttempts`, and offsets expected attempts count by 1, but still counts towards
@@ -177,7 +177,7 @@ class TunnelControlPage: Page {
totalAttemptsOffset = 1
}
for (attemptIndex, attempt) in connectionAttempts.enumerated() {
- if attemptIndex < 3 - totalAttemptsOffset {
+ if attemptIndex < 2 - totalAttemptsOffset {
XCTAssertEqual(attempt.protocolName, "UDP")
} else {
XCTAssertEqual(attempt.protocolName, "TCP")
diff --git a/ios/PacketTunnel/PacketTunnelProvider/BlockedStateErrorMapper.swift b/ios/PacketTunnel/PacketTunnelProvider/BlockedStateErrorMapper.swift
index 219e7d518d..2383142ba1 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/BlockedStateErrorMapper.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/BlockedStateErrorMapper.swift
@@ -58,6 +58,8 @@ public struct BlockedStateErrorMapper: BlockedStateErrorMapperProtocol {
.noRelaysSatisfyingDaitaConstraints
case .noObfuscatedRelaysFound:
.noRelaysSatisfyingObfuscationSettings
+ case .invalidPort:
+ .noRelaysSatisfyingPortConstraints
default:
.noRelaysSatisfyingConstraints
}
diff --git a/ios/PacketTunnelCore/Actor/State+Extensions.swift b/ios/PacketTunnelCore/Actor/State+Extensions.swift
index b42a52458e..2421f498a1 100644
--- a/ios/PacketTunnelCore/Actor/State+Extensions.swift
+++ b/ios/PacketTunnelCore/Actor/State+Extensions.swift
@@ -206,7 +206,8 @@ extension BlockedStateReason {
case .noRelaysSatisfyingConstraints, .noRelaysSatisfyingFilterConstraints,
.multihopEntryEqualsExit, .noRelaysSatisfyingObfuscationSettings,
.noRelaysSatisfyingDaitaConstraints, .readSettings, .invalidAccount, .accountExpired, .deviceRevoked,
- .unknown, .deviceLoggedOut, .outdatedSchema, .invalidRelayPublicKey:
+ .unknown, .deviceLoggedOut, .outdatedSchema, .invalidRelayPublicKey,
+ .noRelaysSatisfyingPortConstraints:
return false
}
}
diff --git a/ios/PacketTunnelCore/Actor/State.swift b/ios/PacketTunnelCore/Actor/State.swift
index 3aac312490..6f837fc734 100644
--- a/ios/PacketTunnelCore/Actor/State.swift
+++ b/ios/PacketTunnelCore/Actor/State.swift
@@ -211,9 +211,12 @@ public enum BlockedStateReason: String, Codable, Equatable, Sendable {
/// No relays satisfying DAITA constraints.
case noRelaysSatisfyingDaitaConstraints
- /// No relays satisfying DAITA constraints.
+ /// No relays satisfying obfuscation settings.
case noRelaysSatisfyingObfuscationSettings
+ /// No relays satisfying port constraints.
+ case noRelaysSatisfyingPortConstraints
+
/// Any other failure when reading settings.
case readSettings
diff --git a/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift b/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
index 318a451a7b..ba506a0519 100644
--- a/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
+++ b/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
@@ -57,13 +57,13 @@ final class ProtocolObfuscatorTests: XCTestCase {
func testObfuscateAutomatic() throws {
let settings = settings(.automatic, obfuscationPort: .automatic)
- try (UInt(0) ... 3).forEach { attempt in
+ try (UInt(0) ... 2).forEach { attempt in
let obfuscated = obfuscator.obfuscate(endpoint, settings: settings, retryAttempts: attempt)
switch attempt {
- case 0, 1:
+ case 0:
XCTAssertEqual(endpoint, obfuscated.endpoint)
- case 2, 3:
+ case 1, 2:
let obfuscationProtocol = try XCTUnwrap(obfuscator.tunnelObfuscator as? TunnelObfuscationStub)
validate(obfuscated.endpoint, against: obfuscationProtocol)
default: