summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2023-10-13 09:09:28 +0200
committerBug Magnet <marco.nikic@mullvad.net>2023-10-13 09:09:28 +0200
commitc56ccac47cb49fdd5d3a6f5bedf41fbcd9207653 (patch)
treed635f4a1f131a03ea04493268c982cd4ced32796
parent7f8b7e9f4de225075f3ae63026f54689d356f982 (diff)
parentc731b04c54e98488dc1695e4dd4f74b6862b1286 (diff)
downloadmullvadvpn-c56ccac47cb49fdd5d3a6f5bedf41fbcd9207653.tar.xz
mullvadvpn-c56ccac47cb49fdd5d3a6f5bedf41fbcd9207653.zip
Merge branch 'selected-relay-struct-ios-339'
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj55
-rw-r--r--ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProviderHost.swift37
-rw-r--r--ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift16
-rw-r--r--ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift7
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelInteractor.swift5
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManager.swift17
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/AppMessageHandler.swift4
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift4
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/RelaySelectorWrapper.swift10
-rw-r--r--ios/PacketTunnelCore/Actor/Actor.swift11
-rw-r--r--ios/PacketTunnelCore/Actor/Command.swift2
-rw-r--r--ios/PacketTunnelCore/Actor/Protocols/RelaySelectorProtocol.swift35
-rw-r--r--ios/PacketTunnelCore/Actor/StartOptions.swift11
-rw-r--r--ios/PacketTunnelCore/Actor/State+Extensions.swift2
-rw-r--r--ios/PacketTunnelCore/Actor/State.swift7
-rw-r--r--ios/PacketTunnelCore/IPC/PacketTunnelOptions.swift19
-rw-r--r--ios/PacketTunnelCore/IPC/RelaySelectorResult+PacketTunnelRelay.swift21
-rw-r--r--ios/PacketTunnelCore/IPC/TunnelProviderMessage.swift4
-rw-r--r--ios/PacketTunnelCore/URLRequestProxy/URLRequestProxy.swift1
-rw-r--r--ios/PacketTunnelCoreTests/Mocks/RelaySelectorStub.swift30
20 files changed, 146 insertions, 152 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index fbeffe5635..7986b4245d 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -75,6 +75,7 @@
5820EDAB288FF0D2006BF4E4 /* DeviceRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5820EDAA288FF0D2006BF4E4 /* DeviceRowView.swift */; };
5822C0042A3724A800A3A5FB /* ShadowsocksConfigurationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9467E8A2A2E0317000DC21F /* ShadowsocksConfigurationCache.swift */; };
5822C0052A3724A800A3A5FB /* ShadowsocksConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9467E872A2DCD57000DC21F /* ShadowsocksConfiguration.swift */; };
+ 58238CB92AD57EC700768310 /* MullvadREST.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06799ABC28F98E1D00ACD94E /* MullvadREST.framework */; };
5823FA5426CE49F700283BF8 /* TunnelObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5823FA5326CE49F600283BF8 /* TunnelObserver.swift */; };
582403822A827E1500163DE8 /* RelaySelectorWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582403812A827E1500163DE8 /* RelaySelectorWrapper.swift */; };
5826B6CB2ABD83E200B1CA13 /* PacketTunnelOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587C575226D2615F005EF767 /* PacketTunnelOptions.swift */; };
@@ -286,7 +287,6 @@
58C7AF112ABD8480007EDD7A /* TunnelProviderMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585DA89226B0323E00B8C587 /* TunnelProviderMessage.swift */; };
58C7AF122ABD8480007EDD7A /* TunnelProviderReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5898D2A7290182B000EB5EBA /* TunnelProviderReply.swift */; };
58C7AF132ABD8480007EDD7A /* PacketTunnelStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585DA89826B0329200B8C587 /* PacketTunnelStatus.swift */; };
- 58C7AF142ABD8480007EDD7A /* RelaySelectorResult+PacketTunnelRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C9B8CC2ABB247700040B46 /* RelaySelectorResult+PacketTunnelRelay.swift */; };
58C7AF152ABD8480007EDD7A /* PacketTunnelRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5898D2B62902A9EA00EB5EBA /* PacketTunnelRelay.swift */; };
58C7AF162ABD84A8007EDD7A /* URLRequestProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58D229B6298D1D5200BB5A2D /* URLRequestProxy.swift */; };
58C7AF172ABD84AA007EDD7A /* ProxyURLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063687AF28EB083800BE7161 /* ProxyURLRequest.swift */; };
@@ -297,7 +297,6 @@
58C9B8D12ABB255100040B46 /* DeviceCheckOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FDF2D82A0BA11900C2B061 /* DeviceCheckOperation.swift */; };
58C9B8D22ABB255100040B46 /* DeviceStateAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 583D86472A2678DC0060D63B /* DeviceStateAccessor.swift */; };
58C9B8D32ABB255100040B46 /* DeviceCheckRemoteService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58915D672A25FA080066445B /* DeviceCheckRemoteService.swift */; };
- 58C9B8DA2ABB271D00040B46 /* MullvadTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A97F1F412A1F4E1A00ECEFDE /* MullvadTransport.framework */; };
58CAFA002983FF0200BE19F7 /* LoginInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAF9FF2983FF0200BE19F7 /* LoginInteractor.swift */; };
58CAFA032985367600BE19F7 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CAFA01298530DC00BE19F7 /* Promise.swift */; };
58CC40EF24A601900019D96E /* ObserverList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CC40EE24A601900019D96E /* ObserverList.swift */; };
@@ -414,7 +413,6 @@
58FE25BF2AA72311003D1918 /* MigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D96B192A8247C100A5C673 /* MigrationManager.swift */; };
58FE25C22AA72729003D1918 /* MullvadREST.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 06799ABC28F98E1D00ACD94E /* MullvadREST.framework */; };
58FE25C62AA72779003D1918 /* PacketTunnelCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C7A4362A863F440060C66F /* PacketTunnelCore.framework */; };
- 58FE25CB2AA727A9003D1918 /* libRelaySelector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D29829017DAC00EB5EBA /* libRelaySelector.a */; };
58FE25CE2AA72802003D1918 /* MullvadSettings.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58B2FDD32AA71D2A003EB5C6 /* MullvadSettings.framework */; };
58FE25D42AA729B5003D1918 /* ActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FE25D32AA729B5003D1918 /* ActorTests.swift */; };
58FE25D72AA72A8F003D1918 /* State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5824030C2A811B0000163DE8 /* State.swift */; };
@@ -597,6 +595,13 @@
remoteGlobalIDString = 06799ABB28F98E1D00ACD94E;
remoteInfo = MullvadREST;
};
+ 58238CBB2AD57EC800768310 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 58CE5E58224146200008646E /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 06799ABB28F98E1D00ACD94E;
+ remoteInfo = MullvadREST;
+ };
58695AA22A4ADA9200328DB3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58CE5E58224146200008646E /* Project object */;
@@ -653,13 +658,6 @@
remoteGlobalIDString = 58CE5E5F224146200008646E;
remoteInfo = MullvadVPN;
};
- 58C9B8DC2ABB271D00040B46 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 58CE5E58224146200008646E /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = A97F1F402A1F4E1A00ECEFDE;
- remoteInfo = MullvadTransport;
- };
58CE5E7F224146470008646E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58CE5E58224146200008646E /* Project object */;
@@ -821,13 +819,6 @@
remoteGlobalIDString = 58C7A4352A863F440060C66F;
remoteInfo = PacketTunnelCore;
};
- 58FE25CC2AA727A9003D1918 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 58CE5E58224146200008646E /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 5898D29729017DAC00EB5EBA;
- remoteInfo = RelaySelector;
- };
58FE25D02AA72802003D1918 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58CE5E58224146200008646E /* Project object */;
@@ -1325,7 +1316,6 @@
58C7A43D2A863F460060C66F /* PacketTunnelCoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PacketTunnelCoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
58C7A46F2A8649ED0060C66F /* PingerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PingerTests.swift; sourceTree = "<group>"; };
58C8191729FAA2C400DEB1B4 /* NotificationConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationConfiguration.swift; sourceTree = "<group>"; };
- 58C9B8CC2ABB247700040B46 /* RelaySelectorResult+PacketTunnelRelay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RelaySelectorResult+PacketTunnelRelay.swift"; sourceTree = "<group>"; };
58CAF9F72983D36800BE19F7 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
58CAF9FF2983FF0200BE19F7 /* LoginInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginInteractor.swift; sourceTree = "<group>"; };
58CAFA01298530DC00BE19F7 /* Promise.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = "<group>"; };
@@ -1593,9 +1583,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 58238CB92AD57EC700768310 /* MullvadREST.framework in Frameworks */,
A94D691A2ABAD66700413DD4 /* WireGuardKitTypes in Frameworks */,
- 58FE25CB2AA727A9003D1918 /* libRelaySelector.a in Frameworks */,
- 58C9B8DA2ABB271D00040B46 /* MullvadTransport.framework in Frameworks */,
58FE65952AB1D90600E53CB5 /* MullvadTypes.framework in Frameworks */,
58C7A45C2A8640490060C66F /* MullvadLogging.framework in Frameworks */,
);
@@ -2455,7 +2444,6 @@
587C575226D2615F005EF767 /* PacketTunnelOptions.swift */,
5898D2B62902A9EA00EB5EBA /* PacketTunnelRelay.swift */,
585DA89826B0329200B8C587 /* PacketTunnelStatus.swift */,
- 58C9B8CC2ABB247700040B46 /* RelaySelectorResult+PacketTunnelRelay.swift */,
585DA89226B0323E00B8C587 /* TunnelProviderMessage.swift */,
5898D2A7290182B000EB5EBA /* TunnelProviderReply.swift */,
);
@@ -2682,10 +2670,10 @@
58E7A0312AA0715100C57861 /* Protocols */ = {
isa = PBXGroup;
children = (
- 5819ABC22A8CF02C007B59A6 /* TunnelAdapterProtocol.swift */,
- 586E7A2C2A987689006DAB1B /* SettingsReaderProtocol.swift */,
- 5824037F2A827DF300163DE8 /* RelaySelectorProtocol.swift */,
580D6B8B2AB3369300B2D6E0 /* BlockedStateErrorMapperProtocol.swift */,
+ 5824037F2A827DF300163DE8 /* RelaySelectorProtocol.swift */,
+ 586E7A2C2A987689006DAB1B /* SettingsReaderProtocol.swift */,
+ 5819ABC22A8CF02C007B59A6 /* TunnelAdapterProtocol.swift */,
);
path = Protocols;
sourceTree = "<group>";
@@ -3161,9 +3149,8 @@
);
dependencies = (
58C7A45F2A8640490060C66F /* PBXTargetDependency */,
- 58FE25CD2AA727A9003D1918 /* PBXTargetDependency */,
58FE65982AB1D90600E53CB5 /* PBXTargetDependency */,
- 58C9B8DD2ABB271D00040B46 /* PBXTargetDependency */,
+ 58238CBC2AD57EC800768310 /* PBXTargetDependency */,
);
name = PacketTunnelCore;
packageProductDependencies = (
@@ -3935,7 +3922,6 @@
58C7A4522A863FB50060C66F /* Pinger.swift in Sources */,
580D6B8C2AB3369300B2D6E0 /* BlockedStateErrorMapperProtocol.swift in Sources */,
58C7AF172ABD84AA007EDD7A /* ProxyURLRequest.swift in Sources */,
- 58C7AF142ABD8480007EDD7A /* RelaySelectorResult+PacketTunnelRelay.swift in Sources */,
5838321F2AC3160A00EA2071 /* Actor+KeyPolicy.swift in Sources */,
58C7AF122ABD8480007EDD7A /* TunnelProviderReply.swift in Sources */,
58C7A4572A863FB90060C66F /* TunnelDeviceInfoProtocol.swift in Sources */,
@@ -4432,6 +4418,11 @@
target = 06799ABB28F98E1D00ACD94E /* MullvadREST */;
targetProxy = 58153073294CBE8B00D1702E /* PBXContainerItemProxy */;
};
+ 58238CBC2AD57EC800768310 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 06799ABB28F98E1D00ACD94E /* MullvadREST */;
+ targetProxy = 58238CBB2AD57EC800768310 /* PBXContainerItemProxy */;
+ };
58695AA32A4ADA9200328DB3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 5840231E2A406BF5007B27AC /* TunnelObfuscation */;
@@ -4479,11 +4470,6 @@
target = 58CE5E5F224146200008646E /* MullvadVPN */;
targetProxy = 58C7A4712A864B860060C66F /* PBXContainerItemProxy */;
};
- 58C9B8DD2ABB271D00040B46 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = A97F1F402A1F4E1A00ECEFDE /* MullvadTransport */;
- targetProxy = 58C9B8DC2ABB271D00040B46 /* PBXContainerItemProxy */;
- };
58CE5E80224146470008646E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 58CE5E78224146470008646E /* PacketTunnel */;
@@ -4589,11 +4575,6 @@
target = 58C7A4352A863F440060C66F /* PacketTunnelCore */;
targetProxy = 58FE25C82AA72779003D1918 /* PBXContainerItemProxy */;
};
- 58FE25CD2AA727A9003D1918 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 5898D29729017DAC00EB5EBA /* RelaySelector */;
- targetProxy = 58FE25CC2AA727A9003D1918 /* PBXContainerItemProxy */;
- };
58FE25D12AA72802003D1918 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 58B2FDD22AA71D2A003EB5C6 /* MullvadSettings */;
diff --git a/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProviderHost.swift b/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProviderHost.swift
index 39cd909202..d09a3e94ab 100644
--- a/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProviderHost.swift
+++ b/ios/MullvadVPN/SimulatorTunnelProvider/SimulatorTunnelProviderHost.swift
@@ -20,7 +20,7 @@ import RelayCache
import RelaySelector
final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
- private var selectorResult: RelaySelectorResult?
+ private var selectedRelay: SelectedRelay?
private let urlRequestProxy: URLRequestProxy
private let relayCacheTracker: RelayCacheTracker
@@ -40,24 +40,24 @@ final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
completionHandler: @escaping (Error?) -> Void
) {
dispatchQueue.async {
- var selectorResult: RelaySelectorResult?
+ var selectedRelay: SelectedRelay?
do {
let tunnelOptions = PacketTunnelOptions(rawOptions: options ?? [:])
- selectorResult = try tunnelOptions.getSelectorResult()
+ selectedRelay = try tunnelOptions.getSelectedRelay()
} catch {
self.providerLogger.error(
error: error,
message: """
- Failed to decode relay selector result passed from the app. \
+ Failed to decode selected relay passed from the app. \
Will continue by picking new relay.
"""
)
}
do {
- self.selectorResult = try selectorResult ?? self.pickRelay()
+ self.selectedRelay = try selectedRelay ?? self.pickRelay()
completionHandler(nil)
} catch {
@@ -72,7 +72,7 @@ final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
dispatchQueue.async {
- self.selectorResult = nil
+ self.selectedRelay = nil
completionHandler()
}
@@ -99,7 +99,7 @@ final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
switch message {
case .getTunnelStatus:
var tunnelStatus = PacketTunnelStatus()
- tunnelStatus.tunnelRelay = self.selectorResult?.packetTunnelRelay
+ tunnelStatus.tunnelRelay = self.selectedRelay?.packetTunnelRelay
var reply: Data?
do {
@@ -113,10 +113,17 @@ final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
completionHandler?(reply)
- case let .reconnectTunnel(aSelectorResult):
+ case let .reconnectTunnel(nextRelay):
reasserting = true
- if let aSelectorResult {
- selectorResult = aSelectorResult
+ switch nextRelay {
+ case let .preSelected(selectedRelay):
+ self.selectedRelay = selectedRelay
+ case .random:
+ if let nextRelay = try? pickRelay() {
+ self.selectedRelay = nextRelay
+ }
+ case .current:
+ break
}
reasserting = false
completionHandler?(nil)
@@ -145,15 +152,19 @@ final class SimulatorTunnelProviderHost: SimulatorTunnelProviderDelegate {
}
}
- private func pickRelay() throws -> RelaySelectorResult {
+ private func pickRelay() throws -> SelectedRelay {
let cachedRelays = try relayCacheTracker.getCachedRelays()
let tunnelSettings = try SettingsManager.readSettings()
-
- return try RelaySelector.evaluate(
+ let selectorResult = try RelaySelector.evaluate(
relays: cachedRelays.relays,
constraints: tunnelSettings.relayConstraints,
numberOfFailedAttempts: 0
)
+ return SelectedRelay(
+ endpoint: selectorResult.endpoint,
+ hostname: selectorResult.relay.hostname,
+ location: selectorResult.location
+ )
}
}
diff --git a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
index 9404d02cde..afba76a887 100644
--- a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
@@ -51,9 +51,9 @@ class StartTunnelOperation: ResultOperation<Void> {
case .disconnected, .pendingReconnect:
do {
- let selectorResult = try interactor.selectRelay()
+ let selectedRelay = try interactor.selectRelay()
- makeTunnelProviderAndStartTunnel(selectorResult: selectorResult) { error in
+ makeTunnelProviderAndStartTunnel(selectedRelay: selectedRelay) { error in
self.finish(result: error.map { .failure($0) } ?? .success(()))
}
} catch {
@@ -66,7 +66,7 @@ class StartTunnelOperation: ResultOperation<Void> {
}
private func makeTunnelProviderAndStartTunnel(
- selectorResult: RelaySelectorResult,
+ selectedRelay: SelectedRelay,
completionHandler: @escaping (Error?) -> Void
) {
makeTunnelProvider { result in
@@ -74,7 +74,7 @@ class StartTunnelOperation: ResultOperation<Void> {
do {
try self.startTunnel(
tunnel: try result.get(),
- selectorResult: selectorResult
+ selectedRelay: selectedRelay
)
completionHandler(nil)
@@ -85,11 +85,11 @@ class StartTunnelOperation: ResultOperation<Void> {
}
}
- private func startTunnel(tunnel: Tunnel, selectorResult: RelaySelectorResult) throws {
+ private func startTunnel(tunnel: Tunnel, selectedRelay: SelectedRelay) throws {
var tunnelOptions = PacketTunnelOptions()
do {
- try tunnelOptions.setSelectorResult(selectorResult)
+ try tunnelOptions.setSelectedRelay(selectedRelay)
} catch {
logger.error(
error: error,
@@ -101,8 +101,8 @@ class StartTunnelOperation: ResultOperation<Void> {
interactor.updateTunnelStatus { tunnelStatus in
tunnelStatus = TunnelStatus()
- tunnelStatus.packetTunnelStatus.tunnelRelay = selectorResult.packetTunnelRelay
- tunnelStatus.state = .connecting(selectorResult.packetTunnelRelay)
+ tunnelStatus.packetTunnelStatus.tunnelRelay = selectedRelay.packetTunnelRelay
+ tunnelStatus.state = .connecting(selectedRelay.packetTunnelRelay)
}
try tunnel.start(options: tunnelOptions.rawOptions())
diff --git a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
index ff5704428b..0eb06130d8 100644
--- a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
+++ b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift
@@ -23,17 +23,16 @@ private let dispatchQueue = DispatchQueue(label: "Tunnel.dispatchQueue")
private let proxyRequestTimeout = REST.defaultAPINetworkTimeout + 2
extension Tunnel {
- /// Request packet tunnel process to reconnect the tunnel with the given relay selector result.
- /// Packet tunnel will reconnect to the current relay if relay selector result is not provided.
+ /// Request packet tunnel process to reconnect the tunnel with the given relay.
func reconnectTunnel(
- relaySelectorResult: RelaySelectorResult?,
+ to nextRelay: NextRelay,
completionHandler: @escaping (Result<Void, Error>) -> Void
) -> Cancellable {
let operation = SendTunnelProviderMessageOperation(
dispatchQueue: dispatchQueue,
application: .shared,
tunnel: self,
- message: .reconnectTunnel(relaySelectorResult),
+ message: .reconnectTunnel(nextRelay),
completionHandler: completionHandler
)
diff --git a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
index d5f9d9ae8b..26f40bc0d4 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
@@ -8,8 +8,7 @@
import Foundation
import MullvadSettings
-import RelayCache
-import RelaySelector
+import PacketTunnelCore
protocol TunnelInteractor {
// MARK: - Tunnel manipulation
@@ -38,5 +37,5 @@ protocol TunnelInteractor {
func startTunnel()
func prepareForVPNConfigurationDeletion()
- func selectRelay() throws -> RelaySelectorResult
+ func selectRelay() throws -> SelectedRelay
}
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
index 1f27c66395..34cfca0d1a 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
@@ -283,9 +283,9 @@ final class TunnelManager: StorePaymentObserver {
throw UnsetTunnelError()
}
- let selectorResult = selectNewRelay ? try self.selectRelay() : nil
+ let nextRelay: NextRelay = selectNewRelay ? .preSelected(try self.selectRelay()) : .current
- return tunnel.reconnectTunnel(relaySelectorResult: selectorResult) { result in
+ return tunnel.reconnectTunnel(to: nextRelay) { result in
finish(result.error)
}
} catch {
@@ -819,14 +819,19 @@ final class TunnelManager: StorePaymentObserver {
updateTunnelStatus(tunnel?.status ?? .disconnected)
}
- fileprivate func selectRelay() throws -> RelaySelectorResult {
+ fileprivate func selectRelay() throws -> SelectedRelay {
let cachedRelays = try relayCacheTracker.getCachedRelays()
-
- return try RelaySelector.evaluate(
+ let selectorResult = try RelaySelector.evaluate(
relays: cachedRelays.relays,
constraints: settings.relayConstraints,
numberOfFailedAttempts: tunnelStatus.packetTunnelStatus.numberOfFailedAttempts
)
+
+ return SelectedRelay(
+ endpoint: selectorResult.endpoint,
+ hostname: selectorResult.relay.hostname,
+ location: selectorResult.location
+ )
}
fileprivate func prepareForVPNConfigurationDeletion() {
@@ -1306,7 +1311,7 @@ private struct TunnelInteractorProxy: TunnelInteractor {
tunnelManager.prepareForVPNConfigurationDeletion()
}
- func selectRelay() throws -> RelaySelectorResult {
+ func selectRelay() throws -> SelectedRelay {
try tunnelManager.selectRelay()
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider/AppMessageHandler.swift b/ios/PacketTunnel/PacketTunnelProvider/AppMessageHandler.swift
index 952fcb4bde..4071468799 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/AppMessageHandler.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/AppMessageHandler.swift
@@ -54,8 +54,8 @@ struct AppMessageHandler {
packetTunnelActor.notifyKeyRotation(date: nil)
return nil
- case let .reconnectTunnel(selectorResult):
- packetTunnelActor.reconnect(to: selectorResult.map { .preSelected($0) } ?? .current)
+ case let .reconnectTunnel(nextRelay):
+ packetTunnelActor.reconnect(to: nextRelay)
return nil
}
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index 4d52039ab6..3f4598da36 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -174,9 +174,9 @@ extension PacketTunnelProvider {
var parsedOptions = StartOptions(launchSource: tunnelOptions.isOnDemand() ? .onDemand : .app)
do {
- if let selectorResult = try tunnelOptions.getSelectorResult() {
+ if let selectedRelay = try tunnelOptions.getSelectedRelay() {
parsedOptions.launchSource = .app
- parsedOptions.selectorResult = selectorResult
+ parsedOptions.selectedRelay = selectedRelay
} else if !tunnelOptions.isOnDemand() {
parsedOptions.launchSource = .system
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider/RelaySelectorWrapper.swift b/ios/PacketTunnel/PacketTunnelProvider/RelaySelectorWrapper.swift
index 31e1e68f3c..eb5bd6dcee 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/RelaySelectorWrapper.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/RelaySelectorWrapper.swift
@@ -18,11 +18,17 @@ struct RelaySelectorWrapper: RelaySelectorProtocol {
func selectRelay(
with constraints: RelayConstraints,
connectionAttemptFailureCount: UInt
- ) throws -> RelaySelectorResult {
- try RelaySelector.evaluate(
+ ) throws -> SelectedRelay {
+ let selectorResult = try RelaySelector.evaluate(
relays: relayCache.read().relays,
constraints: constraints,
numberOfFailedAttempts: connectionAttemptFailureCount
)
+
+ return SelectedRelay(
+ endpoint: selectorResult.endpoint,
+ hostname: selectorResult.relay.hostname,
+ location: selectorResult.location
+ )
}
}
diff --git a/ios/PacketTunnelCore/Actor/Actor.swift b/ios/PacketTunnelCore/Actor/Actor.swift
index 18be2e2d40..fafeba2403 100644
--- a/ios/PacketTunnelCore/Actor/Actor.swift
+++ b/ios/PacketTunnelCore/Actor/Actor.swift
@@ -10,7 +10,6 @@ import Foundation
import MullvadLogging
import MullvadTypes
import NetworkExtension
-import struct RelaySelector.RelaySelectorResult
import class WireGuardKitTypes.PrivateKey
/**
@@ -133,7 +132,7 @@ extension PacketTunnelActor {
setTunnelMonitorEventHandler()
do {
- try await tryStart(nextRelay: options.selectorResult.map { .preSelected($0) } ?? .random)
+ try await tryStart(nextRelay: options.selectedRelay.map { .preSelected($0) } ?? .random)
} catch {
logger.error(error: error, message: "Failed to start the tunnel.")
@@ -332,9 +331,9 @@ extension PacketTunnelActor {
private func selectRelay(
nextRelay: NextRelay,
relayConstraints: RelayConstraints,
- currentRelay: RelaySelectorResult?,
+ currentRelay: SelectedRelay?,
connectionAttemptCount: UInt
- ) throws -> RelaySelectorResult {
+ ) throws -> SelectedRelay {
switch nextRelay {
case .current:
if let currentRelay {
@@ -350,8 +349,8 @@ extension PacketTunnelActor {
connectionAttemptFailureCount: connectionAttemptCount
)
- case let .preSelected(selectorResult):
- return selectorResult
+ case let .preSelected(selectedRelay):
+ return selectedRelay
}
}
}
diff --git a/ios/PacketTunnelCore/Actor/Command.swift b/ios/PacketTunnelCore/Actor/Command.swift
index 43771e62af..d7cf121684 100644
--- a/ios/PacketTunnelCore/Actor/Command.swift
+++ b/ios/PacketTunnelCore/Actor/Command.swift
@@ -50,7 +50,7 @@ enum Command {
case .random:
return "reconnect(random, \(stopTunnelMonitor))"
case let .preSelected(selectedRelay):
- return "reconnect(\(selectedRelay.relay.hostname), \(stopTunnelMonitor))"
+ return "reconnect(\(selectedRelay.hostname), \(stopTunnelMonitor))"
}
case let .error(reason):
return "error(\(reason))"
diff --git a/ios/PacketTunnelCore/Actor/Protocols/RelaySelectorProtocol.swift b/ios/PacketTunnelCore/Actor/Protocols/RelaySelectorProtocol.swift
index b856b2f1fe..8127008a8f 100644
--- a/ios/PacketTunnelCore/Actor/Protocols/RelaySelectorProtocol.swift
+++ b/ios/PacketTunnelCore/Actor/Protocols/RelaySelectorProtocol.swift
@@ -8,10 +8,39 @@
import Foundation
import MullvadTypes
-import RelaySelector
/// Protocol describing a type that can select a relay.
public protocol RelaySelectorProtocol {
- func selectRelay(with constraints: RelayConstraints, connectionAttemptFailureCount: UInt) throws
- -> RelaySelectorResult
+ func selectRelay(with constraints: RelayConstraints, connectionAttemptFailureCount: UInt) throws -> SelectedRelay
+}
+
+/// Struct describing the selected relay.
+public struct SelectedRelay: Equatable, Codable {
+ /// Selected relay endpoint.
+ public var endpoint: MullvadEndpoint
+
+ /// Relay hostname.
+ public var hostname: String
+
+ /// Relay geo location.
+ public var location: Location
+
+ /// Designated initializer.
+ public init(endpoint: MullvadEndpoint, hostname: String, location: Location) {
+ self.endpoint = endpoint
+ self.hostname = hostname
+ self.location = location
+ }
+}
+
+extension SelectedRelay {
+ /// Converts `SelectedRelay` to `PacketTunnelRelay` for sharing with UI.
+ public var packetTunnelRelay: PacketTunnelRelay {
+ PacketTunnelRelay(
+ ipv4Relay: endpoint.ipv4Relay,
+ ipv6Relay: endpoint.ipv6Relay,
+ hostname: hostname,
+ location: location
+ )
+ }
}
diff --git a/ios/PacketTunnelCore/Actor/StartOptions.swift b/ios/PacketTunnelCore/Actor/StartOptions.swift
index d2ebe72611..9dd3ffeb68 100644
--- a/ios/PacketTunnelCore/Actor/StartOptions.swift
+++ b/ios/PacketTunnelCore/Actor/StartOptions.swift
@@ -7,7 +7,6 @@
//
import Foundation
-import RelaySelector
/// Packet tunnel start options parsed from dictionary passed to packet tunnel with a call to `startTunnel()`.
public struct StartOptions {
@@ -15,19 +14,19 @@ public struct StartOptions {
public var launchSource: LaunchSource
/// Pre-selected relay received from UI when available.
- public var selectorResult: RelaySelectorResult?
+ public var selectedRelay: SelectedRelay?
/// Designated initializer.
- public init(launchSource: LaunchSource, selectorResult: RelaySelectorResult? = nil) {
+ public init(launchSource: LaunchSource, selectedRelay: SelectedRelay? = nil) {
self.launchSource = launchSource
- self.selectorResult = selectorResult
+ self.selectedRelay = selectedRelay
}
/// Returns a brief description suitable for output to tunnel provider log.
public func logFormat() -> String {
var s = "Start the tunnel via \(launchSource)"
- if let selectorResult {
- s += ", connect to \(selectorResult.relay.hostname)"
+ if let selectedRelay {
+ s += ", connect to \(selectedRelay.hostname)"
}
s += "."
return s
diff --git a/ios/PacketTunnelCore/Actor/State+Extensions.swift b/ios/PacketTunnelCore/Actor/State+Extensions.swift
index cfaed6cf07..71a090acb2 100644
--- a/ios/PacketTunnelCore/Actor/State+Extensions.swift
+++ b/ios/PacketTunnelCore/Actor/State+Extensions.swift
@@ -41,7 +41,7 @@ extension State {
func logFormat() -> String {
switch self {
case let .connecting(connState), let .connected(connState), let .reconnecting(connState):
- let hostname = connState.selectedRelay.relay.hostname
+ let hostname = connState.selectedRelay.hostname
return """
\(name) to \(hostname), \
diff --git a/ios/PacketTunnelCore/Actor/State.swift b/ios/PacketTunnelCore/Actor/State.swift
index 2c5cfd13b8..79cfc19ce6 100644
--- a/ios/PacketTunnelCore/Actor/State.swift
+++ b/ios/PacketTunnelCore/Actor/State.swift
@@ -8,7 +8,6 @@
import Foundation
import MullvadTypes
-import struct RelaySelector.RelaySelectorResult
import TunnelObfuscation
import class WireGuardKitTypes.PrivateKey
@@ -100,7 +99,7 @@ public enum NetworkReachability: Equatable {
/// Data associated with states that hold connection data.
public struct ConnectionState {
/// Current selected relay.
- public var selectedRelay: RelaySelectorResult
+ public var selectedRelay: SelectedRelay
/// Last relay constraints read from settings.
/// This is primarily used by packet tunnel for updating constraints in tunnel provider.
@@ -203,7 +202,7 @@ public enum TargetStateForReconnect {
}
/// Describes which relay the tunnel should connect to next.
-public enum NextRelay: Equatable {
+public enum NextRelay: Equatable, Codable {
/// Select next relay randomly.
case random
@@ -211,5 +210,5 @@ public enum NextRelay: Equatable {
case current
/// Use pre-selected relay.
- case preSelected(RelaySelectorResult)
+ case preSelected(SelectedRelay)
}
diff --git a/ios/PacketTunnelCore/IPC/PacketTunnelOptions.swift b/ios/PacketTunnelCore/IPC/PacketTunnelOptions.swift
index 8290895294..742fb1f12f 100644
--- a/ios/PacketTunnelCore/IPC/PacketTunnelOptions.swift
+++ b/ios/PacketTunnelCore/IPC/PacketTunnelOptions.swift
@@ -7,18 +7,15 @@
//
import Foundation
-import RelaySelector
public struct PacketTunnelOptions {
/// Keys for options dictionary
private enum Keys: String {
- /// Option key that holds the `NSData` value with `RelaySelectorResult`
- /// encoded using `JSONEncoder`.
+ /// Option key that holds serialized `SelectedRelay` value encoded using `JSONEncoder`.
/// Used for passing the pre-selected relay in the GUI process to the Packet tunnel process.
- case relaySelectorResult = "relay-selector-result"
+ case selectedRelay = "selected-relay"
- /// Option key that holds the `NSNumber` value, which is when set to `1` indicates that
- /// the tunnel was started by the system.
+ /// Option key that holds an `NSNumber` value, which is when set to `1` indicates that the tunnel was started by the system.
/// System automatically provides that flag to the tunnel.
case isOnDemand = "is-on-demand"
}
@@ -37,14 +34,14 @@ public struct PacketTunnelOptions {
_rawOptions = rawOptions
}
- public func getSelectorResult() throws -> RelaySelectorResult? {
- guard let data = _rawOptions[Keys.relaySelectorResult.rawValue] as? Data else { return nil }
+ public func getSelectedRelay() throws -> SelectedRelay? {
+ guard let data = _rawOptions[Keys.selectedRelay.rawValue] as? Data else { return nil }
- return try Self.decode(RelaySelectorResult.self, data)
+ return try Self.decode(SelectedRelay.self, data)
}
- public mutating func setSelectorResult(_ value: RelaySelectorResult) throws {
- _rawOptions[Keys.relaySelectorResult.rawValue] = try Self.encode(value) as NSData
+ public mutating func setSelectedRelay(_ value: SelectedRelay) throws {
+ _rawOptions[Keys.selectedRelay.rawValue] = try Self.encode(value) as NSData
}
public func isOnDemand() -> Bool {
diff --git a/ios/PacketTunnelCore/IPC/RelaySelectorResult+PacketTunnelRelay.swift b/ios/PacketTunnelCore/IPC/RelaySelectorResult+PacketTunnelRelay.swift
deleted file mode 100644
index 4169f7bca8..0000000000
--- a/ios/PacketTunnelCore/IPC/RelaySelectorResult+PacketTunnelRelay.swift
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// RelaySelectorResult+PacketTunnelRelay.swift
-// PacketTunnelCore
-//
-// Created by pronebird on 20/09/2023.
-// Copyright © 2023 Mullvad VPN AB. All rights reserved.
-//
-
-import Foundation
-import RelaySelector
-
-extension RelaySelectorResult {
- public var packetTunnelRelay: PacketTunnelRelay {
- PacketTunnelRelay(
- ipv4Relay: endpoint.ipv4Relay,
- ipv6Relay: endpoint.ipv6Relay,
- hostname: relay.hostname,
- location: location
- )
- }
-}
diff --git a/ios/PacketTunnelCore/IPC/TunnelProviderMessage.swift b/ios/PacketTunnelCore/IPC/TunnelProviderMessage.swift
index 231c1cd858..7062674437 100644
--- a/ios/PacketTunnelCore/IPC/TunnelProviderMessage.swift
+++ b/ios/PacketTunnelCore/IPC/TunnelProviderMessage.swift
@@ -7,13 +7,11 @@
//
import Foundation
-import RelaySelector
/// Enum describing supported app messages handled by packet tunnel provider.
public enum TunnelProviderMessage: Codable, CustomStringConvertible {
/// Request the tunnel to reconnect.
- /// The packet tunnel reconnects to the current relay when selector result is `nil`.
- case reconnectTunnel(RelaySelectorResult?)
+ case reconnectTunnel(NextRelay)
/// Request the tunnel status.
case getTunnelStatus
diff --git a/ios/PacketTunnelCore/URLRequestProxy/URLRequestProxy.swift b/ios/PacketTunnelCore/URLRequestProxy/URLRequestProxy.swift
index e6f6b38e15..fb4f6cbbfc 100644
--- a/ios/PacketTunnelCore/URLRequestProxy/URLRequestProxy.swift
+++ b/ios/PacketTunnelCore/URLRequestProxy/URLRequestProxy.swift
@@ -8,7 +8,6 @@
import Foundation
import MullvadREST
-import MullvadTransport
import MullvadTypes
/// Network request proxy capable of passing serializable requests and responses over the given transport provider.
diff --git a/ios/PacketTunnelCoreTests/Mocks/RelaySelectorStub.swift b/ios/PacketTunnelCoreTests/Mocks/RelaySelectorStub.swift
index 64f0c7472a..8c69404bdc 100644
--- a/ios/PacketTunnelCoreTests/Mocks/RelaySelectorStub.swift
+++ b/ios/PacketTunnelCoreTests/Mocks/RelaySelectorStub.swift
@@ -7,20 +7,18 @@
//
import Foundation
-@testable import MullvadREST
import MullvadTypes
import PacketTunnelCore
-@testable import RelaySelector
import class WireGuardKitTypes.PrivateKey
/// Relay selector stub that accepts a block that can be used to provide custom implementation.
struct RelaySelectorStub: RelaySelectorProtocol {
- let block: (RelayConstraints, UInt) throws -> RelaySelectorResult
+ let block: (RelayConstraints, UInt) throws -> SelectedRelay
func selectRelay(
with constraints: RelayConstraints,
connectionAttemptFailureCount: UInt
- ) throws -> RelaySelectorResult {
+ ) throws -> SelectedRelay {
return try block(constraints, connectionAttemptFailureCount)
}
}
@@ -31,26 +29,22 @@ extension RelaySelectorStub {
let publicKey = PrivateKey().publicKey.rawValue
return RelaySelectorStub { _, _ in
- return RelaySelectorResult(
+ return SelectedRelay(
endpoint: MullvadEndpoint(
ipv4Relay: IPv4Endpoint(ip: .loopback, port: 1300),
ipv4Gateway: .loopback,
ipv6Gateway: .loopback,
publicKey: publicKey
),
- relay: REST.ServerRelay(
- hostname: "se-got",
- active: true,
- owned: true,
- location: "se-got",
- provider: "",
- weight: 0,
- ipv4AddrIn: .loopback,
- ipv6AddrIn: .loopback,
- publicKey: publicKey,
- includeInCountry: true
- ),
- location: Location(country: "", countryCode: "se", city: "", cityCode: "got", latitude: 0, longitude: 0)
+ hostname: "se-got",
+ location: Location(
+ country: "",
+ countryCode: "se",
+ city: "",
+ cityCode: "got",
+ latitude: 0,
+ longitude: 0
+ )
)
}
}