summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/PacketTunnelCore/Actor/ObservedState.swift9
-rw-r--r--ios/PacketTunnelCore/Actor/PacketTunnelActor.swift10
-rw-r--r--ios/PacketTunnelCore/Actor/ProtocolObfuscator.swift28
-rw-r--r--ios/PacketTunnelCore/Actor/State.swift4
-rw-r--r--ios/PacketTunnelCoreTests/Mocks/ProtocolObfuscationStub.swift4
-rw-r--r--ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift18
6 files changed, 48 insertions, 25 deletions
diff --git a/ios/PacketTunnelCore/Actor/ObservedState.swift b/ios/PacketTunnelCore/Actor/ObservedState.swift
index 5aece77e56..83ea8f96a5 100644
--- a/ios/PacketTunnelCore/Actor/ObservedState.swift
+++ b/ios/PacketTunnelCore/Actor/ObservedState.swift
@@ -9,6 +9,7 @@
import Combine
import Foundation
import MullvadREST
+import MullvadSettings
import MullvadTypes
import Network
@preconcurrency import WireGuardKitTypes
@@ -36,6 +37,7 @@ public struct ObservedConnectionState: Equatable, Codable, Sendable {
public var lastKeyRotation: Date?
public let isPostQuantum: Bool
public let isDaitaEnabled: Bool
+ public let obfuscationMethod: WireGuardObfuscationState
public var isNetworkReachable: Bool {
networkReachability != .unreachable
@@ -50,7 +52,8 @@ public struct ObservedConnectionState: Equatable, Codable, Sendable {
remotePort: UInt16,
lastKeyRotation: Date? = nil,
isPostQuantum: Bool,
- isDaitaEnabled: Bool
+ isDaitaEnabled: Bool,
+ obfuscationMethod: WireGuardObfuscationState = .off
) {
self.selectedRelays = selectedRelays
self.relayConstraints = relayConstraints
@@ -61,6 +64,7 @@ public struct ObservedConnectionState: Equatable, Codable, Sendable {
self.lastKeyRotation = lastKeyRotation
self.isPostQuantum = isPostQuantum
self.isDaitaEnabled = isDaitaEnabled
+ self.obfuscationMethod = obfuscationMethod
}
}
@@ -111,7 +115,8 @@ extension State.ConnectionData {
remotePort: remotePort,
lastKeyRotation: lastKeyRotation,
isPostQuantum: isPostQuantum,
- isDaitaEnabled: isDaitaEnabled
+ isDaitaEnabled: isDaitaEnabled,
+ obfuscationMethod: obfuscationMethod
)
}
}
diff --git a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
index e55cf1e8cb..bf4feac3c1 100644
--- a/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
+++ b/ios/PacketTunnelCore/Actor/PacketTunnelActor.swift
@@ -402,7 +402,8 @@ extension PacketTunnelActor {
transportLayer: .udp,
remotePort: connectedRelay.endpoint.ipv4Relay.port,
isPostQuantum: settings.quantumResistance.isEnabled,
- isDaitaEnabled: settings.daita.daitaState.isEnabled
+ isDaitaEnabled: settings.daita.daitaState.isEnabled,
+ obfuscationMethod: .off
)
case .disconnecting, .disconnected:
return nil
@@ -426,7 +427,7 @@ extension PacketTunnelActor {
guard let connectionState = try makeConnectionState(nextRelays: nextRelays, settings: settings, reason: reason)
else { return nil }
- let obfuscatedEndpoint = protocolObfuscator.obfuscate(
+ let obfuscated = protocolObfuscator.obfuscate(
connectionState.connectedEndpoint,
settings: settings.tunnelSettings,
retryAttempts: connectionState.selectedRelays.retryAttempt
@@ -441,11 +442,12 @@ extension PacketTunnelActor {
networkReachability: connectionState.networkReachability,
connectionAttemptCount: connectionState.connectionAttemptCount,
lastKeyRotation: connectionState.lastKeyRotation,
- connectedEndpoint: obfuscatedEndpoint,
+ connectedEndpoint: obfuscated.endpoint,
transportLayer: transportLayer,
remotePort: protocolObfuscator.remotePort,
isPostQuantum: settings.quantumResistance.isEnabled,
- isDaitaEnabled: settings.daita.daitaState.isEnabled
+ isDaitaEnabled: settings.daita.daitaState.isEnabled,
+ obfuscationMethod: obfuscated.method
)
}
diff --git a/ios/PacketTunnelCore/Actor/ProtocolObfuscator.swift b/ios/PacketTunnelCore/Actor/ProtocolObfuscator.swift
index ca162f0919..2a0ed7bf06 100644
--- a/ios/PacketTunnelCore/Actor/ProtocolObfuscator.swift
+++ b/ios/PacketTunnelCore/Actor/ProtocolObfuscator.swift
@@ -12,8 +12,17 @@ import MullvadRustRuntime
import MullvadSettings
import MullvadTypes
+public struct ProtocolObfuscationResult {
+ let endpoint: MullvadEndpoint
+ let method: WireGuardObfuscationState
+}
+
public protocol ProtocolObfuscation {
- func obfuscate(_ endpoint: MullvadEndpoint, settings: LatestTunnelSettings, retryAttempts: UInt) -> MullvadEndpoint
+ func obfuscate(
+ _ endpoint: MullvadEndpoint,
+ settings: LatestTunnelSettings,
+ retryAttempts: UInt
+ ) -> ProtocolObfuscationResult
var transportLayer: TransportLayer? { get }
var remotePort: UInt16 { get }
}
@@ -38,7 +47,7 @@ public class ProtocolObfuscator<Obfuscator: TunnelObfuscation>: ProtocolObfuscat
_ endpoint: MullvadEndpoint,
settings: LatestTunnelSettings,
retryAttempts: UInt = 0
- ) -> MullvadEndpoint {
+ ) -> ProtocolObfuscationResult {
let obfuscationMethod = ObfuscationMethodSelector.obfuscationMethodBy(
connectionAttemptCount: retryAttempts,
tunnelSettings: settings
@@ -48,7 +57,7 @@ public class ProtocolObfuscator<Obfuscator: TunnelObfuscation>: ProtocolObfuscat
guard obfuscationMethod != .off else {
tunnelObfuscator = nil
- return endpoint
+ return .init(endpoint: endpoint, method: .off)
}
// At this point, the only possible obfuscation methods should be either `.udpOverTcp` or `.shadowsocks`
@@ -61,11 +70,14 @@ public class ProtocolObfuscator<Obfuscator: TunnelObfuscation>: ProtocolObfuscat
obfuscator.start()
tunnelObfuscator = obfuscator
- return MullvadEndpoint(
- ipv4Relay: IPv4Endpoint(ip: .loopback, port: obfuscator.localUdpPort),
- ipv4Gateway: endpoint.ipv4Gateway,
- ipv6Gateway: endpoint.ipv6Gateway,
- publicKey: endpoint.publicKey
+ return .init(
+ endpoint: MullvadEndpoint(
+ ipv4Relay: IPv4Endpoint(ip: .loopback, port: obfuscator.localUdpPort),
+ ipv4Gateway: endpoint.ipv4Gateway,
+ ipv6Gateway: endpoint.ipv6Gateway,
+ publicKey: endpoint.publicKey
+ ),
+ method: obfuscationMethod
)
}
}
diff --git a/ios/PacketTunnelCore/Actor/State.swift b/ios/PacketTunnelCore/Actor/State.swift
index 83ecd53145..3aac312490 100644
--- a/ios/PacketTunnelCore/Actor/State.swift
+++ b/ios/PacketTunnelCore/Actor/State.swift
@@ -9,6 +9,7 @@
import Foundation
import MullvadREST
import MullvadRustRuntime
+import MullvadSettings
import MullvadTypes
@preconcurrency import WireGuardKitTypes
@@ -153,6 +154,9 @@ extension State {
/// True if Daita is enabled
public let isDaitaEnabled: Bool
+
+ /// The obfuscation method in force on the connection
+ public let obfuscationMethod: WireGuardObfuscationState
}
/// Data associated with error state.
diff --git a/ios/PacketTunnelCoreTests/Mocks/ProtocolObfuscationStub.swift b/ios/PacketTunnelCoreTests/Mocks/ProtocolObfuscationStub.swift
index 9acdf9f1d0..77087782a3 100644
--- a/ios/PacketTunnelCoreTests/Mocks/ProtocolObfuscationStub.swift
+++ b/ios/PacketTunnelCoreTests/Mocks/ProtocolObfuscationStub.swift
@@ -18,8 +18,8 @@ struct ProtocolObfuscationStub: ProtocolObfuscation {
_ endpoint: MullvadEndpoint,
settings: LatestTunnelSettings,
retryAttempts: UInt
- ) -> MullvadEndpoint {
- endpoint
+ ) -> ProtocolObfuscationResult {
+ .init(endpoint: endpoint, method: .off)
}
var transportLayer: TransportLayer? { .udp }
diff --git a/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift b/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
index 83491d18f8..318a451a7b 100644
--- a/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
+++ b/ios/PacketTunnelCoreTests/ProtocolObfuscatorTests.swift
@@ -33,39 +33,39 @@ final class ProtocolObfuscatorTests: XCTestCase {
func testObfuscateOffDoesNotChangeEndpoint() {
let settings = settings(.off, obfuscationPort: .automatic)
- let nonObfuscatedEndpoint = obfuscator.obfuscate(endpoint, settings: settings)
+ let nonObfuscated = obfuscator.obfuscate(endpoint, settings: settings)
- XCTAssertEqual(endpoint, nonObfuscatedEndpoint)
+ XCTAssertEqual(endpoint, nonObfuscated.endpoint)
}
func testObfuscateUdpOverTcp() throws {
let settings = settings(.udpOverTcp, obfuscationPort: .automatic)
- let obfuscatedEndpoint = obfuscator.obfuscate(endpoint, settings: settings)
+ let obfuscated = obfuscator.obfuscate(endpoint, settings: settings)
let obfuscationProtocol = try XCTUnwrap(obfuscator.tunnelObfuscator as? TunnelObfuscationStub)
- validate(obfuscatedEndpoint, against: obfuscationProtocol)
+ validate(obfuscated.endpoint, against: obfuscationProtocol)
}
func testObfuscateShadowsocks() throws {
let settings = settings(.shadowsocks, obfuscationPort: .automatic)
- let obfuscatedEndpoint = obfuscator.obfuscate(endpoint, settings: settings)
+ let obfuscated = obfuscator.obfuscate(endpoint, settings: settings)
let obfuscationProtocol = try XCTUnwrap(obfuscator.tunnelObfuscator as? TunnelObfuscationStub)
- validate(obfuscatedEndpoint, against: obfuscationProtocol)
+ validate(obfuscated.endpoint, against: obfuscationProtocol)
}
func testObfuscateAutomatic() throws {
let settings = settings(.automatic, obfuscationPort: .automatic)
try (UInt(0) ... 3).forEach { attempt in
- let obfuscatedEndpoint = obfuscator.obfuscate(endpoint, settings: settings, retryAttempts: attempt)
+ let obfuscated = obfuscator.obfuscate(endpoint, settings: settings, retryAttempts: attempt)
switch attempt {
case 0, 1:
- XCTAssertEqual(endpoint, obfuscatedEndpoint)
+ XCTAssertEqual(endpoint, obfuscated.endpoint)
case 2, 3:
let obfuscationProtocol = try XCTUnwrap(obfuscator.tunnelObfuscator as? TunnelObfuscationStub)
- validate(obfuscatedEndpoint, against: obfuscationProtocol)
+ validate(obfuscated.endpoint, against: obfuscationProtocol)
default:
XCTExpectFailure("Should not end up here, test setup is wrong")
}