Skip to content

Commit ad713fe

Browse files
committed
Merge branch 'add-daita-settings-into-tunnel-ios-791'
2 parents 1283882 + bdfd397 commit ad713fe

34 files changed

+449
-349
lines changed

ios/MullvadMockData/MullvadREST/RelaySelectorStub.swift

+6-9
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,14 @@ import WireGuardKitTypes
1212

1313
/// Relay selector stub that accepts a block that can be used to provide custom implementation.
1414
public final class RelaySelectorStub: RelaySelectorProtocol {
15-
var selectedRelaysResult: (RelayConstraints, UInt) throws -> SelectedRelays
15+
var selectedRelaysResult: (UInt) throws -> SelectedRelays
1616

17-
init(selectedRelaysResult: @escaping (RelayConstraints, UInt) throws -> SelectedRelays) {
17+
init(selectedRelaysResult: @escaping (UInt) throws -> SelectedRelays) {
1818
self.selectedRelaysResult = selectedRelaysResult
1919
}
2020

21-
public func selectRelays(
22-
with constraints: RelayConstraints,
23-
connectionAttemptCount: UInt
24-
) throws -> SelectedRelays {
25-
return try selectedRelaysResult(constraints, connectionAttemptCount)
21+
public func selectRelays(connectionAttemptCount: UInt) throws -> SelectedRelays {
22+
return try selectedRelaysResult(connectionAttemptCount)
2623
}
2724
}
2825

@@ -31,7 +28,7 @@ extension RelaySelectorStub {
3128
public static func nonFallible() -> RelaySelectorStub {
3229
let publicKey = PrivateKey().publicKey.rawValue
3330

34-
return RelaySelectorStub { _, _ in
31+
return RelaySelectorStub { _ in
3532
let cityRelay = SelectedRelay(
3633
endpoint: MullvadEndpoint(
3734
ipv4Relay: IPv4Endpoint(ip: .loopback, port: 1300),
@@ -60,7 +57,7 @@ extension RelaySelectorStub {
6057

6158
/// Returns a relay selector that cannot satisfy constraints .
6259
public static func unsatisfied() -> RelaySelectorStub {
63-
return RelaySelectorStub { _, _ in
60+
return RelaySelectorStub { _ in
6461
throw NoRelaysSatisfyingConstraintsError()
6562
}
6663
}

ios/MullvadREST/Relay/RelaySelectorProtocol.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
//
88

99
import Foundation
10+
import MullvadSettings
1011
import MullvadTypes
1112

1213
/// Protocol describing a type that can select a relay.
1314
public protocol RelaySelectorProtocol {
14-
func selectRelays(with constraints: RelayConstraints, connectionAttemptCount: UInt) throws -> SelectedRelays
15+
func selectRelays(connectionAttemptCount: UInt) throws -> SelectedRelays
1516
}
1617

1718
/// Struct describing the selected relay.

ios/MullvadREST/Relay/RelaySelectorWrapper.swift

+13-13
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,51 @@ import MullvadTypes
1111

1212
public final class RelaySelectorWrapper: RelaySelectorProtocol {
1313
let relayCache: RelayCacheProtocol
14-
let multihopUpdater: MultihopUpdater
15-
private var multihopState: MultihopState = .off
16-
private var observer: MultihopObserverBlock!
14+
15+
let tunnelSettingsUpdater: SettingsUpdater
16+
private var tunnelSettings = LatestTunnelSettings()
17+
private var observer: SettingsObserverBlock!
1718

1819
deinit {
19-
self.multihopUpdater.removeObserver(observer)
20+
self.tunnelSettingsUpdater.removeObserver(observer)
2021
}
2122

2223
public init(
2324
relayCache: RelayCacheProtocol,
24-
multihopUpdater: MultihopUpdater
25+
tunnelSettingsUpdater: SettingsUpdater
2526
) {
2627
self.relayCache = relayCache
27-
self.multihopUpdater = multihopUpdater
28+
self.tunnelSettingsUpdater = tunnelSettingsUpdater
2829

2930
self.addObserver()
3031
}
3132

3233
public func selectRelays(
33-
with constraints: RelayConstraints,
3434
connectionAttemptCount: UInt
3535
) throws -> SelectedRelays {
3636
let relays = try relayCache.read().relays
3737

38-
switch multihopState {
38+
switch tunnelSettings.tunnelMultihopState {
3939
case .off:
4040
return try SinglehopPicker(
41-
constraints: constraints,
41+
constraints: tunnelSettings.relayConstraints,
4242
relays: relays,
4343
connectionAttemptCount: connectionAttemptCount
4444
).pick()
4545
case .on:
4646
return try MultihopPicker(
47-
constraints: constraints,
47+
constraints: tunnelSettings.relayConstraints,
4848
relays: relays,
4949
connectionAttemptCount: connectionAttemptCount
5050
).pick()
5151
}
5252
}
5353

5454
private func addObserver() {
55-
self.observer = MultihopObserverBlock(didUpdateMultihop: { [weak self] _, multihopState in
56-
self?.multihopState = multihopState
55+
self.observer = SettingsObserverBlock(didUpdateSettings: { [weak self] latestTunnelSettings in
56+
self?.tunnelSettings = latestTunnelSettings
5757
})
5858

59-
multihopUpdater.addObserver(observer)
59+
tunnelSettingsUpdater.addObserver(observer)
6060
}
6161
}

ios/MullvadREST/Transport/Shadowsocks/ShadowsocksLoader.swift

+23-28
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,42 @@ public protocol ShadowsocksLoaderProtocol {
1818
public class ShadowsocksLoader: ShadowsocksLoaderProtocol {
1919
let cache: ShadowsocksConfigurationCacheProtocol
2020
let relaySelector: ShadowsocksRelaySelectorProtocol
21-
let constraintsUpdater: RelayConstraintsUpdater
22-
let multihopUpdater: MultihopUpdater
23-
private var multihopState: MultihopState = .off
24-
private var observer: MultihopObserverBlock!
21+
let settingsUpdater: SettingsUpdater
22+
23+
private var observer: SettingsObserverBlock!
24+
private var tunnelSettings = LatestTunnelSettings()
25+
private let settingsStrategy = TunnelSettingsStrategy()
2526

2627
deinit {
27-
self.multihopUpdater.removeObserver(observer)
28+
self.settingsUpdater.removeObserver(observer)
2829
}
2930

30-
private var relayConstraints = RelayConstraints()
31-
3231
public init(
3332
cache: ShadowsocksConfigurationCacheProtocol,
3433
relaySelector: ShadowsocksRelaySelectorProtocol,
35-
constraintsUpdater: RelayConstraintsUpdater,
36-
multihopUpdater: MultihopUpdater
34+
settingsUpdater: SettingsUpdater
3735
) {
3836
self.cache = cache
3937
self.relaySelector = relaySelector
40-
self.constraintsUpdater = constraintsUpdater
41-
self.multihopUpdater = multihopUpdater
38+
self.settingsUpdater = settingsUpdater
4239
self.addObservers()
4340
}
4441

4542
private func addObservers() {
46-
// The constraints gets updated a lot when observing the tunnel, clear the cache if the constraints have changed.
47-
constraintsUpdater.onNewConstraints = { [weak self] newConstraints in
48-
if self?.relayConstraints != newConstraints {
49-
self?.relayConstraints = newConstraints
50-
try? self?.clear()
51-
}
52-
}
53-
54-
// The multihop state gets updated a lot when observing the tunnel, clear the cache if the multihop settings have changed.
55-
self.observer = MultihopObserverBlock(didUpdateMultihop: { [weak self] _, newMultihopState in
56-
if self?.multihopState != newMultihopState {
57-
self?.multihopState = newMultihopState
58-
try? self?.clear()
59-
}
60-
})
61-
multihopUpdater.addObserver(self.observer)
43+
observer =
44+
SettingsObserverBlock(
45+
didUpdateSettings: { [weak self] latestTunnelSettings in
46+
guard let self else { return }
47+
if settingsStrategy.shouldReconnectToNewRelay(
48+
oldSettings: tunnelSettings,
49+
newSettings: latestTunnelSettings
50+
) {
51+
try? clear()
52+
}
53+
tunnelSettings = latestTunnelSettings
54+
}
55+
)
56+
settingsUpdater.addObserver(self.observer)
6257
}
6358

6459
public func clear() throws {
@@ -81,7 +76,7 @@ public class ShadowsocksLoader: ShadowsocksLoaderProtocol {
8176
/// Returns a randomly selected shadowsocks configuration.
8277
private func create() throws -> ShadowsocksConfiguration {
8378
let bridgeConfiguration = try relaySelector.getBridges()
84-
let closestRelay = try relaySelector.selectRelay(with: relayConstraints, multihopState: multihopState)
79+
let closestRelay = try relaySelector.selectRelay(with: tunnelSettings)
8580

8681
guard let bridgeAddress = closestRelay?.ipv4AddrIn,
8782
let bridgeConfiguration else { throw POSIXError(.ENOENT) }

ios/MullvadREST/Transport/Shadowsocks/ShadowsocksRelaySelector.swift

+7-13
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ import MullvadSettings
1111
import MullvadTypes
1212

1313
public protocol ShadowsocksRelaySelectorProtocol {
14-
func selectRelay(
15-
with constraints: RelayConstraints,
16-
multihopState: MultihopState
17-
) throws -> REST.BridgeRelay?
14+
func selectRelay(with settings: LatestTunnelSettings) throws -> REST.BridgeRelay?
1815

1916
func getBridges() throws -> REST.ServerShadowsocks?
2017
}
@@ -28,21 +25,18 @@ final public class ShadowsocksRelaySelector: ShadowsocksRelaySelectorProtocol {
2825
self.relayCache = relayCache
2926
}
3027

31-
public func selectRelay(
32-
with constraints: RelayConstraints,
33-
multihopState: MultihopState
34-
) throws -> REST.BridgeRelay? {
28+
public func selectRelay(with settings: LatestTunnelSettings) throws -> REST.BridgeRelay? {
3529
let cachedRelays = try relayCache.read().relays
3630

37-
let locationConstraint = switch multihopState {
38-
case .on: constraints.entryLocations
39-
case .off: constraints.exitLocations
31+
let locationConstraint = switch settings.tunnelMultihopState {
32+
case .on: settings.relayConstraints.entryLocations
33+
case .off: settings.relayConstraints.exitLocations
4034
}
4135

4236
return RelaySelector.Shadowsocks.closestRelay(
4337
location: locationConstraint,
44-
port: constraints.port,
45-
filter: constraints.filter,
38+
port: settings.relayConstraints.port,
39+
filter: settings.relayConstraints.filter,
4640
in: cachedRelays
4741
)
4842
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// DAITASettings.swift
3+
// MullvadSettings
4+
//
5+
// Created by Mojgan on 2024-08-08.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Whether DAITA is enabled
12+
public enum DAITAState: Codable {
13+
case on
14+
case off
15+
16+
public var isEnabled: Bool {
17+
self == .on
18+
}
19+
}
20+
21+
public struct DAITASettings: Codable, Equatable {
22+
public let state: DAITAState
23+
24+
public init(state: DAITAState = .off) {
25+
self.state = state
26+
}
27+
}

ios/MullvadSettings/MultihopSettings.swift

-56
Original file line numberDiff line numberDiff line change
@@ -9,62 +9,6 @@
99
import Foundation
1010
import MullvadTypes
1111

12-
public protocol MultihopPropagation {
13-
typealias MultihopHandler = (MultihopState) -> Void
14-
var onNewMultihop: MultihopHandler? { get set }
15-
}
16-
17-
public protocol MultihopObserver: AnyObject {
18-
func multihop(_ object: MultihopPropagation, didUpdateMultihop state: MultihopState)
19-
}
20-
21-
public class MultihopObserverBlock: MultihopObserver {
22-
public typealias DidUpdateMultihopHandler = (MultihopPropagation, MultihopState) -> Void
23-
public var onNewState: DidUpdateMultihopHandler
24-
25-
public init(didUpdateMultihop: @escaping DidUpdateMultihopHandler) {
26-
self.onNewState = didUpdateMultihop
27-
}
28-
29-
public func multihop(_ object: MultihopPropagation, didUpdateMultihop state: MultihopState) {
30-
self.onNewState(object, state)
31-
}
32-
}
33-
34-
public final class MultihopStateListener: MultihopPropagation {
35-
public var onNewMultihop: MultihopHandler?
36-
37-
public init(onNewMultihop: MultihopHandler? = nil) {
38-
self.onNewMultihop = onNewMultihop
39-
}
40-
}
41-
42-
public class MultihopUpdater {
43-
/// Observers.
44-
private let observerList = ObserverList<MultihopObserver>()
45-
private var listener: MultihopPropagation
46-
47-
public init(listener: MultihopPropagation) {
48-
self.listener = listener
49-
self.listener.onNewMultihop = { [weak self] state in
50-
guard let self else { return }
51-
self.observerList.notify {
52-
$0.multihop(listener, didUpdateMultihop: state)
53-
}
54-
}
55-
}
56-
57-
// MARK: - Multihop observations
58-
59-
public func addObserver(_ observer: MultihopObserver) {
60-
observerList.append(observer)
61-
}
62-
63-
public func removeObserver(_ observer: MultihopObserver) {
64-
observerList.remove(observer)
65-
}
66-
}
67-
6812
/// Whether Multi-hop is enabled
6913
public enum MultihopState: Codable {
7014
case on

ios/MullvadSettings/TunnelSettings.swift

+8-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
/// Alias to the latest version of the `TunnelSettings`.
12-
public typealias LatestTunnelSettings = TunnelSettingsV5
12+
public typealias LatestTunnelSettings = TunnelSettingsV6
1313

1414
/// Protocol all TunnelSettings must adhere to, for upgrade purposes.
1515
public protocol TunnelSettings: Codable {
@@ -33,13 +33,17 @@ public enum SchemaVersion: Int, Equatable {
3333
/// V4 format with multi-hop options, stored as `TunnelSettingsV5`.
3434
case v5 = 5
3535

36+
/// V5 format with DAITA settings, stored as `TunnelSettingsV6`.
37+
case v6 = 6
38+
3639
var settingsType: any TunnelSettings.Type {
3740
switch self {
3841
case .v1: return TunnelSettingsV1.self
3942
case .v2: return TunnelSettingsV2.self
4043
case .v3: return TunnelSettingsV3.self
4144
case .v4: return TunnelSettingsV4.self
4245
case .v5: return TunnelSettingsV5.self
46+
case .v6: return TunnelSettingsV6.self
4347
}
4448
}
4549

@@ -49,10 +53,11 @@ public enum SchemaVersion: Int, Equatable {
4953
case .v2: return .v3
5054
case .v3: return .v4
5155
case .v4: return .v5
52-
case .v5: return .v5
56+
case .v5: return .v6
57+
case .v6: return .v6
5358
}
5459
}
5560

5661
/// Current schema version.
57-
public static let current = SchemaVersion.v5
62+
public static let current = SchemaVersion.v6
5863
}

0 commit comments

Comments
 (0)