summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2022-11-09 13:57:29 +0100
committerAndrej Mihajlov <and@mullvad.net>2022-11-09 13:57:29 +0100
commitaf24fbacb6b85f93286e28cea8aefae7c698bf07 (patch)
tree1c62114b50ccecfc8d686e33a2840d75bce9be23
parent2af40170885057f6fa6a40ffb071d2b998265a54 (diff)
parentfcc639078249f8da58c48e2cb3c261dd8a754c84 (diff)
downloadmullvadvpn-af24fbacb6b85f93286e28cea8aefae7c698bf07.tar.xz
mullvadvpn-af24fbacb6b85f93286e28cea8aefae7c698bf07.zip
Merge branch 'no-shared-instances'
-rw-r--r--ios/MullvadREST/AddressCache.swift5
-rw-r--r--ios/MullvadREST/Info.plist5
-rw-r--r--ios/MullvadREST/RESTProxyFactory.swift18
-rw-r--r--ios/MullvadREST/RESTTransportRegistry.swift6
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj10
-rw-r--r--ios/MullvadVPN/AccountDataThrottling.swift2
-rw-r--r--ios/MullvadVPN/AddressCacheTracker.swift14
-rw-r--r--ios/MullvadVPN/AppDelegate.swift112
-rw-r--r--ios/MullvadVPN/DeviceManagementInteractor.swift5
-rw-r--r--ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift8
-rw-r--r--ios/MullvadVPN/Notifications/TunnelStatusNotificationProvider.swift3
-rw-r--r--ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift (renamed from ios/MullvadVPN/RelayCache/RelayCacheTracker.swift)14
-rw-r--r--ios/MullvadVPN/RelayCacheTracker/RelayCacheTrackerObserver.swift (renamed from ios/MullvadVPN/RelayCache/RelayCacheTrackerObserver.swift)0
-rw-r--r--ios/MullvadVPN/SceneDelegate.swift90
-rw-r--r--ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift22
-rw-r--r--ios/MullvadVPN/TransportMonitor/TransportMonitor.swift6
-rw-r--r--ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift10
-rw-r--r--ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift6
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelInteractor.swift3
-rw-r--r--ios/MullvadVPN/TunnelManager/TunnelManager.swift52
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider.swift31
21 files changed, 253 insertions, 169 deletions
diff --git a/ios/MullvadREST/AddressCache.swift b/ios/MullvadREST/AddressCache.swift
index 647c495314..c18709f0ef 100644
--- a/ios/MullvadREST/AddressCache.swift
+++ b/ios/MullvadREST/AddressCache.swift
@@ -12,11 +12,6 @@ import MullvadTypes
extension REST {
public final class AddressCache {
- public static let shared = AddressCache(
- securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier,
- isReadOnly: false
- )!
-
/// Logger.
private let logger = Logger(label: "AddressCache")
diff --git a/ios/MullvadREST/Info.plist b/ios/MullvadREST/Info.plist
index 65663845f1..0c67376eba 100644
--- a/ios/MullvadREST/Info.plist
+++ b/ios/MullvadREST/Info.plist
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
-<dict>
- <key>ApplicationSecurityGroupIdentifier</key>
- <string>$(SECURITY_GROUP_IDENTIFIER)</string>
-</dict>
+<dict/>
</plist>
diff --git a/ios/MullvadREST/RESTProxyFactory.swift b/ios/MullvadREST/RESTProxyFactory.swift
index f1b7d74cc0..211d32b9aa 100644
--- a/ios/MullvadREST/RESTProxyFactory.swift
+++ b/ios/MullvadREST/RESTProxyFactory.swift
@@ -12,25 +12,29 @@ extension REST {
public final class ProxyFactory {
public let configuration: AuthProxyConfiguration
- public static let shared: ProxyFactory = {
- let basicConfiguration = ProxyConfiguration(
- transportRegistry: TransportRegistry.shared,
- addressCacheStore: AddressCache.shared
+ public class func makeProxyFactory(
+ transportRegistry: REST.TransportRegistry,
+ addressCache: AddressCache
+ ) -> ProxyFactory {
+ let basicConfiguration = REST.ProxyConfiguration(
+ transportRegistry: transportRegistry,
+ addressCacheStore: addressCache
)
let authenticationProxy = REST.AuthenticationProxy(
configuration: basicConfiguration
)
- let accessTokenManager = AccessTokenManager(
+ let accessTokenManager = REST.AccessTokenManager(
authenticationProxy: authenticationProxy
)
- let authConfiguration = AuthProxyConfiguration(
+ let authConfiguration = REST.AuthProxyConfiguration(
proxyConfiguration: basicConfiguration,
accessTokenManager: accessTokenManager
)
+
return ProxyFactory(configuration: authConfiguration)
- }()
+ }
public init(configuration: AuthProxyConfiguration) {
self.configuration = configuration
diff --git a/ios/MullvadREST/RESTTransportRegistry.swift b/ios/MullvadREST/RESTTransportRegistry.swift
index b41545fbba..1dcac36962 100644
--- a/ios/MullvadREST/RESTTransportRegistry.swift
+++ b/ios/MullvadREST/RESTTransportRegistry.swift
@@ -10,12 +10,12 @@ import Foundation
extension REST {
public final class TransportRegistry {
- public static let shared = TransportRegistry()
-
private var transport: RESTTransport?
private let nslock = NSLock()
- private init() {}
+ public init(transport: RESTTransport?) {
+ self.transport = transport
+ }
public func setTransport(_ transport: RESTTransport) {
nslock.lock()
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 3e7b6261aa..9f6bd376f1 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -126,7 +126,6 @@
584EBDBD2747C98F00A0C9FD /* NSAttributedString+Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584EBDBC2747C98F00A0C9FD /* NSAttributedString+Markdown.swift */; };
584F99202902CBDD001F858D /* libRelaySelector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D29829017DAC00EB5EBA /* libRelaySelector.a */; };
584F99212902CF35001F858D /* libMullvadTypes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 581943F128F8014500B0CB5E /* libMullvadTypes.a */; };
- 58505FFA290A7F0F00118C23 /* ApplicationConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BFA5CB22A7CE1F00A6173D /* ApplicationConfiguration.swift */; };
5856AD582902BE1A008E5127 /* PacketTunnelRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5898D2B62902A9EA00EB5EBA /* PacketTunnelRelay.swift */; };
5856AD592902BE1A008E5127 /* PacketTunnelStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 585DA89826B0329200B8C587 /* PacketTunnelStatus.swift */; };
5857F24324C8662600CF6F47 /* SelectLocationHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */; };
@@ -1117,13 +1116,13 @@
name = Frameworks;
sourceTree = "<group>";
};
- 585DA87526B0249A00B8C587 /* RelayCache */ = {
+ 585DA87526B0249A00B8C587 /* RelayCacheTracker */ = {
isa = PBXGroup;
children = (
58FB865926EA214400F188BC /* RelayCacheTrackerObserver.swift */,
58BFA5C522A7C97F00A6173D /* RelayCacheTracker.swift */,
);
- path = RelayCache;
+ path = RelayCacheTracker;
sourceTree = "<group>";
};
586A950B2901250A007BAF2B /* Operations */ = {
@@ -1332,8 +1331,8 @@
58F8AC0D25D3F8CE002BE0ED /* ProblemReportReviewViewController.swift */,
58EF580A25D69D7A00AEBA94 /* ProblemReportSubmissionOverlayView.swift */,
58293FAC2510CA58005D0BB5 /* ProblemReportViewController.swift */,
- 585DA87526B0249A00B8C587 /* RelayCache */,
5878A26E2907E7E00096FC88 /* ProblemReportInteractor.swift */,
+ 585DA87526B0249A00B8C587 /* RelayCacheTracker */,
06FAE67828F83CA50033DD93 /* RESTCreateApplePaymentResponse+Localization.swift */,
58F1311427E0B2AB007AC5BC /* Result+Extensions.swift */,
580909D22876D09A0078138D /* RevokedDeviceViewController.swift */,
@@ -2027,7 +2026,6 @@
06799AF128F98E4800ACD94E /* RESTAPIProxy.swift in Sources */,
06799AED28F98E4800ACD94E /* RESTTransportRegistry.swift in Sources */,
06799AE528F98E4800ACD94E /* HTTP.swift in Sources */,
- 58505FFA290A7F0F00118C23 /* ApplicationConfiguration.swift in Sources */,
06799AE028F98E4800ACD94E /* RESTCoding.swift in Sources */,
06799AFC28F98EE300ACD94E /* AddressCache.swift in Sources */,
5897F1762914E62E00AF5695 /* Duration.swift in Sources */,
@@ -2214,8 +2212,8 @@
5878A27729093A4F0096FC88 /* StorePaymentBlockObserver.swift in Sources */,
5868585524054096000B8131 /* AppButton.swift in Sources */,
58E25F812837BBBB002CFB2C /* SceneDelegate.swift in Sources */,
- 585E820327F3285E00939F0E /* SendStoreReceiptOperation.swift in Sources */,
5867771629097C5B006F721F /* ProductState.swift in Sources */,
+ 585E820327F3285E00939F0E /* SendStoreReceiptOperation.swift in Sources */,
584B17AB27637DE40057F3B8 /* ReconnectTunnelOperation.swift in Sources */,
5820676426E771DB00655B05 /* TunnelManagerErrors.swift in Sources */,
585B4B8726D9098900555C4C /* TunnelStatusNotificationProvider.swift in Sources */,
diff --git a/ios/MullvadVPN/AccountDataThrottling.swift b/ios/MullvadVPN/AccountDataThrottling.swift
index 31f0b1f849..f6093beeb2 100644
--- a/ios/MullvadVPN/AccountDataThrottling.swift
+++ b/ios/MullvadVPN/AccountDataThrottling.swift
@@ -30,7 +30,7 @@ struct AccountDataThrottling {
let tunnelManager: TunnelManager
private(set) var lastUpdate: Date?
- init(tunnelManager: TunnelManager = .shared) {
+ init(tunnelManager: TunnelManager) {
self.tunnelManager = tunnelManager
}
diff --git a/ios/MullvadVPN/AddressCacheTracker.swift b/ios/MullvadVPN/AddressCacheTracker.swift
index 1f90030f1f..ee19bc1431 100644
--- a/ios/MullvadVPN/AddressCacheTracker.swift
+++ b/ios/MullvadVPN/AddressCacheTracker.swift
@@ -6,19 +6,13 @@
// Copyright © 2021 Mullvad VPN AB. All rights reserved.
//
-import Foundation
import MullvadLogging
import MullvadREST
import MullvadTypes
import Operations
+import UIKit
final class AddressCacheTracker {
- /// Shared instance.
- static let shared = AddressCacheTracker(
- apiProxy: REST.ProxyFactory.shared.createAPIProxy(),
- store: REST.AddressCache.shared
- )
-
/// Update interval (in seconds).
private static let updateInterval: TimeInterval = 60 * 60 * 24
@@ -27,6 +21,7 @@ final class AddressCacheTracker {
/// Logger.
private let logger = Logger(label: "AddressCache.Tracker")
+ private let application: UIApplication
/// REST API proxy.
private let apiProxy: REST.APIProxy
@@ -54,7 +49,8 @@ final class AddressCacheTracker {
private let nslock = NSLock()
/// Designated initializer
- private init(apiProxy: REST.APIProxy, store: REST.AddressCache) {
+ init(application: UIApplication, apiProxy: REST.APIProxy, store: REST.AddressCache) {
+ self.application = application
self.apiProxy = apiProxy
self.store = store
}
@@ -120,7 +116,7 @@ final class AddressCacheTracker {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Update endpoints",
cancelUponExpiration: true
)
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 34367b96e1..1d5141bc61 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -32,7 +32,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
return operationQueue
}()
- private let transportMonitor = TransportMonitor()
+ private(set) var tunnelManager: TunnelManager!
+ private(set) var addressCache: REST.AddressCache!
+
+ private var proxyFactory: REST.ProxyFactory!
+ private(set) var apiProxy: REST.APIProxy!
+ private(set) var accountsProxy: REST.AccountsProxy!
+ private(set) var devicesProxy: REST.DevicesProxy!
+
+ private(set) var addressCacheTracker: AddressCacheTracker!
+ private(set) var relayCacheTracker: RelayCacheTracker!
+ private(set) var storePaymentManager: StorePaymentManager!
+ private var transportMonitor: TransportMonitor!
// MARK: - Application lifecycle
@@ -47,10 +58,51 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
logger = Logger(label: "AppDelegate")
+ addressCache = REST.AddressCache(
+ securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier,
+ isReadOnly: false
+ )!
+
+ let transportRegistry = REST.TransportRegistry(transport: nil)
+ proxyFactory = REST.ProxyFactory.makeProxyFactory(
+ transportRegistry: transportRegistry,
+ addressCache: addressCache
+ )
+
+ apiProxy = proxyFactory.createAPIProxy()
+ accountsProxy = proxyFactory.createAccountsProxy()
+ devicesProxy = proxyFactory.createDevicesProxy()
+
+ relayCacheTracker = RelayCacheTracker(application: application, apiProxy: apiProxy)
+ addressCacheTracker = AddressCacheTracker(
+ application: application,
+ apiProxy: apiProxy,
+ store: addressCache
+ )
+
+ tunnelManager = TunnelManager(
+ application: application,
+ relayCacheTracker: relayCacheTracker,
+ accountsProxy: accountsProxy,
+ devicesProxy: devicesProxy
+ )
+
+ storePaymentManager = StorePaymentManager(
+ application: application,
+ queue: .default(),
+ apiProxy: apiProxy,
+ accountsProxy: accountsProxy
+ )
+
+ transportMonitor = TransportMonitor(
+ tunnelManager: tunnelManager,
+ transportRegistry: transportRegistry
+ )
+
#if targetEnvironment(simulator)
// Configure mock tunnel provider on simulator
simulatorTunnelProviderHost = SimulatorTunnelProviderHost(
- relayCacheTracker: .shared
+ relayCacheTracker: relayCacheTracker
)
SimulatorTunnelProvider.shared.delegate = simulatorTunnelProviderHost
#endif
@@ -61,7 +113,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
addApplicationNotifications(application: application)
let setupTunnelManagerOperation = AsyncBlockOperation(dispatchQueue: .main) { operation in
- TunnelManager.shared.loadConfiguration { error in
+ self.tunnelManager.loadConfiguration { error in
// TODO: avoid throwing fatal error and show the problem report UI instead.
if let error = error {
fatalError(error.localizedDescription)
@@ -70,7 +122,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
self.logger.debug("Finished initialization.")
NotificationManager.shared.updateNotifications()
- StorePaymentManager.shared.startPaymentQueueMonitoring()
+ self.storePaymentManager.startPaymentQueueMonitoring()
operation.finish()
}
@@ -84,11 +136,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? {
switch intent {
case is StartVPNIntent:
- return StartVPNIntentHandler(tunnelManager: .shared)
+ return StartVPNIntentHandler(tunnelManager: tunnelManager)
case is StopVPNIntent:
- return StopVPNIntentHandler(tunnelManager: .shared)
+ return StopVPNIntentHandler(tunnelManager: tunnelManager)
case is ReconnectVPNIntent:
- return ReconnectVPNIntentHandler(tunnelManager: .shared)
+ return ReconnectVPNIntentHandler(tunnelManager: tunnelManager)
default:
return nil
}
@@ -101,8 +153,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
- // Called when a new scene session is being created.
- // Use this method to select a configuration to create the new scene with.
let sceneConfiguration = UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
@@ -115,27 +165,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
func application(
_ application: UIApplication,
didDiscardSceneSessions sceneSessions: Set<UISceneSession>
- ) {
- // Called when the user discards a scene session.
- // If any sessions were discarded while the application was not running,
- // this will be called shortly after application:didFinishLaunchingWithOptions.
- // Use this method to release any resources that were specific to
- // the discarded scenes, as they will not return.
- }
+ ) {}
// MARK: - Notifications
@objc private func didBecomeActive(_ notification: Notification) {
- TunnelManager.shared.refreshTunnelStatus()
- TunnelManager.shared.startPeriodicPrivateKeyRotation()
- RelayCacheTracker.shared.startPeriodicUpdates()
- AddressCacheTracker.shared.startPeriodicUpdates()
+ tunnelManager.refreshTunnelStatus()
+ tunnelManager.startPeriodicPrivateKeyRotation()
+ relayCacheTracker.startPeriodicUpdates()
+ addressCacheTracker.startPeriodicUpdates()
}
@objc private func willResignActive(_ notification: Notification) {
- TunnelManager.shared.stopPeriodicPrivateKeyRotation()
- RelayCacheTracker.shared.stopPeriodicUpdates()
- AddressCacheTracker.shared.stopPeriodicUpdates()
+ tunnelManager.stopPeriodicPrivateKeyRotation()
+ relayCacheTracker.stopPeriodicUpdates()
+ addressCacheTracker.stopPeriodicUpdates()
}
@objc private func didEnterBackground(_ notification: Notification) {
@@ -155,7 +199,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
forTaskWithIdentifier: ApplicationConfiguration.appRefreshTaskIdentifier,
using: nil
) { task in
- let handle = RelayCacheTracker.shared.updateRelays { completion in
+ let handle = self.relayCacheTracker.updateRelays { completion in
task.setTaskCompleted(success: completion.isSuccess)
}
@@ -178,7 +222,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
forTaskWithIdentifier: ApplicationConfiguration.privateKeyRotationTaskIdentifier,
using: nil
) { task in
- let handle = TunnelManager.shared.rotatePrivateKey(forceRotate: false) { completion in
+ let handle = self.tunnelManager.rotatePrivateKey(forceRotate: false) { completion in
self.scheduleKeyRotationTask()
task.setTaskCompleted(success: completion.isSuccess)
@@ -201,7 +245,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
forTaskWithIdentifier: ApplicationConfiguration.addressCacheUpdateTaskIdentifier,
using: nil
) { task in
- let handle = AddressCacheTracker.shared.updateEndpoints { completion in
+ let handle = self.addressCacheTracker.updateEndpoints { completion in
self.scheduleAddressCacheUpdateTask()
task.setTaskCompleted(success: completion.isSuccess)
@@ -227,7 +271,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
private func scheduleAppRefreshTask() {
do {
- let date = RelayCacheTracker.shared.getNextUpdateDate()
+ let date = relayCacheTracker.getNextUpdateDate()
let request = BGAppRefreshTaskRequest(
identifier: ApplicationConfiguration.appRefreshTaskIdentifier
@@ -247,7 +291,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
private func scheduleKeyRotationTask() {
do {
- guard let date = TunnelManager.shared.getNextKeyRotationDate() else {
+ guard let date = tunnelManager.getNextKeyRotationDate() else {
return
}
@@ -270,7 +314,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
private func scheduleAddressCacheUpdateTask() {
do {
- let date = AddressCacheTracker.shared.nextScheduleDate()
+ let date = addressCacheTracker.nextScheduleDate()
let request = BGProcessingTaskRequest(
identifier: ApplicationConfiguration.addressCacheUpdateTaskIdentifier
@@ -315,14 +359,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}
private func setupPaymentHandler() {
- StorePaymentManager.shared.delegate = self
- StorePaymentManager.shared.addPaymentObserver(TunnelManager.shared)
+ storePaymentManager.delegate = self
+ storePaymentManager.addPaymentObserver(tunnelManager)
}
private func setupNotificationHandler() {
NotificationManager.shared.notificationProviders = [
- AccountExpiryNotificationProvider(),
- TunnelStatusNotificationProvider(),
+ AccountExpiryNotificationProvider(tunnelManager: tunnelManager),
+ TunnelStatusNotificationProvider(tunnelManager: tunnelManager),
]
UNUserNotificationCenter.current().delegate = self
}
@@ -336,7 +380,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
// Since we do not persist the relation between payment and account number between the
// app launches, we assume that all successful purchases belong to the active account
// number.
- return TunnelManager.shared.deviceState.accountData?.number
+ return tunnelManager.deviceState.accountData?.number
}
// MARK: - UNUserNotificationCenterDelegate
diff --git a/ios/MullvadVPN/DeviceManagementInteractor.swift b/ios/MullvadVPN/DeviceManagementInteractor.swift
index 29ab2d1171..87ee7f204a 100644
--- a/ios/MullvadVPN/DeviceManagementInteractor.swift
+++ b/ios/MullvadVPN/DeviceManagementInteractor.swift
@@ -12,11 +12,12 @@ import MullvadTypes
import Operations
class DeviceManagementInteractor {
- private let devicesProxy = REST.ProxyFactory.shared.createDevicesProxy()
+ private let devicesProxy: REST.DevicesProxy
private let accountNumber: String
- init(accountNumber: String) {
+ init(accountNumber: String, devicesProxy: REST.DevicesProxy) {
self.accountNumber = accountNumber
+ self.devicesProxy = devicesProxy
}
@discardableResult
diff --git a/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift b/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
index 83cc888d82..fc6a579661 100644
--- a/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/AccountExpiryNotificationProvider.swift
@@ -10,7 +10,7 @@ import Foundation
import UserNotifications
let accountExpiryNotificationIdentifier = "net.mullvad.MullvadVPN.AccountExpiryNotification"
-let accountExpiryDefaultTriggerInterval = 3
+private let defaultTriggerInterval = 3
class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificationProvider,
InAppNotificationProvider, TunnelObserver
@@ -24,13 +24,13 @@ class AccountExpiryNotificationProvider: NotificationProvider, SystemNotificatio
return accountExpiryNotificationIdentifier
}
- init(triggerInterval: Int = accountExpiryDefaultTriggerInterval) {
+ init(tunnelManager: TunnelManager, triggerInterval: Int = defaultTriggerInterval) {
self.triggerInterval = triggerInterval
super.init()
- TunnelManager.shared.addObserver(self)
- accountExpiry = TunnelManager.shared.deviceState.accountData?.expiry
+ tunnelManager.addObserver(self)
+ accountExpiry = tunnelManager.deviceState.accountData?.expiry
}
private var trigger: UNNotificationTrigger? {
diff --git a/ios/MullvadVPN/Notifications/TunnelStatusNotificationProvider.swift b/ios/MullvadVPN/Notifications/TunnelStatusNotificationProvider.swift
index 59642ccc0c..426d97dbad 100644
--- a/ios/MullvadVPN/Notifications/TunnelStatusNotificationProvider.swift
+++ b/ios/MullvadVPN/Notifications/TunnelStatusNotificationProvider.swift
@@ -31,10 +31,9 @@ class TunnelStatusNotificationProvider: NotificationProvider, InAppNotificationP
}
}
- override init() {
+ init(tunnelManager: TunnelManager) {
super.init()
- let tunnelManager = TunnelManager.shared
tunnelManager.addObserver(self)
handleTunnelStatus(tunnelManager.tunnelStatus)
}
diff --git a/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift
index c6d0b64ef0..ef4bb33733 100644
--- a/ios/MullvadVPN/RelayCache/RelayCacheTracker.swift
+++ b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTracker.swift
@@ -14,7 +14,7 @@ import Operations
import RelayCache
import UIKit
-class RelayCacheTracker {
+final class RelayCacheTracker {
/// Relay update interval (in seconds).
static let relayUpdateInterval: TimeInterval = 60 * 60
@@ -26,6 +26,8 @@ class RelayCacheTracker {
securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier
)!
+ private let application: UIApplication
+
/// Lock used for synchronization.
private let nslock = NSLock()
@@ -43,7 +45,7 @@ class RelayCacheTracker {
private var isPeriodicUpdatesEnabled = false
/// API proxy.
- private let apiProxy = REST.ProxyFactory.shared.createAPIProxy()
+ private let apiProxy: REST.APIProxy
/// Observers.
private let observerList = ObserverList<RelayCacheTrackerObserver>()
@@ -51,10 +53,10 @@ class RelayCacheTracker {
/// Memory cache.
private var cachedRelays: CachedRelays?
- /// A shared instance of `RelayCacheTracker`.
- static let shared = RelayCacheTracker()
+ init(application: UIApplication, apiProxy: REST.APIProxy) {
+ self.application = application
+ self.apiProxy = apiProxy
- private init() {
do {
cachedRelays = try cache.read()
} catch {
@@ -127,7 +129,7 @@ class RelayCacheTracker {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Update relays",
cancelUponExpiration: true
)
diff --git a/ios/MullvadVPN/RelayCache/RelayCacheTrackerObserver.swift b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTrackerObserver.swift
index fcb38b55d6..fcb38b55d6 100644
--- a/ios/MullvadVPN/RelayCache/RelayCacheTrackerObserver.swift
+++ b/ios/MullvadVPN/RelayCacheTracker/RelayCacheTrackerObserver.swift
diff --git a/ios/MullvadVPN/SceneDelegate.swift b/ios/MullvadVPN/SceneDelegate.swift
index dcecff3bab..27fbfa7bf2 100644
--- a/ios/MullvadVPN/SceneDelegate.swift
+++ b/ios/MullvadVPN/SceneDelegate.swift
@@ -38,9 +38,34 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private var connectController: ConnectViewController?
private weak var settingsNavController: SettingsNavigationController?
private var lastLoginAction: LoginAction?
- private var accountDataThrottling = AccountDataThrottling()
+ private lazy var accountDataThrottling = AccountDataThrottling(tunnelManager: tunnelManager)
+
private var outOfTimeTimer: Timer?
+ private var appDelegate: AppDelegate {
+ return UIApplication.shared.delegate as! AppDelegate
+ }
+
+ private var storePaymentManager: StorePaymentManager {
+ return appDelegate.storePaymentManager
+ }
+
+ private var relayCacheTracker: RelayCacheTracker {
+ return appDelegate.relayCacheTracker
+ }
+
+ private var tunnelManager: TunnelManager {
+ return appDelegate.tunnelManager
+ }
+
+ private var apiProxy: REST.APIProxy {
+ return appDelegate.apiProxy
+ }
+
+ private var devicesProxy: REST.DevicesProxy {
+ return appDelegate.devicesProxy
+ }
+
deinit {
clearOutOfTimeTimer()
}
@@ -79,7 +104,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
fatalError()
}
- RelayCacheTracker.shared.addObserver(self)
+ relayCacheTracker.addObserver(self)
NotificationManager.shared.delegate = self
accountDataThrottling.requestUpdate(condition: .always)
@@ -113,15 +138,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
window?.makeKeyAndVisible()
- TunnelManager.shared.addObserver(self)
- if TunnelManager.shared.isConfigurationLoaded {
+ tunnelManager.addObserver(self)
+ if tunnelManager.isConfigurationLoaded {
configureScene()
}
}
- func sceneDidDisconnect(_ scene: UIScene) {
- // no-op
- }
+ func sceneDidDisconnect(_ scene: UIScene) {}
func sceneDidBecomeActive(_ scene: UIScene) {
if isSceneConfigured {
@@ -200,21 +223,23 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
func rootContainerViewAccessibilityPerformMagicTap(_ controller: RootContainerViewController)
-> Bool
{
- guard TunnelManager.shared.deviceState.isLoggedIn else { return false }
+ guard tunnelManager.deviceState.isLoggedIn else { return false }
- switch TunnelManager.shared.tunnelStatus.state {
+ switch tunnelManager.tunnelStatus.state {
case .connected, .connecting, .reconnecting, .waitingForConnectivity:
- TunnelManager.shared.reconnectTunnel(selectNewRelay: true)
+ tunnelManager.reconnectTunnel(selectNewRelay: true)
+
case .disconnecting, .disconnected:
- TunnelManager.shared.startTunnel()
+ tunnelManager.startTunnel()
+
case .pendingReconnect:
break
}
+
return true
}
private func setupPadUI() {
- let tunnelManager = TunnelManager.shared
let selectLocationController = makeSelectLocationController()
let connectController = makeConnectViewController()
@@ -241,7 +266,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
lazy var viewControllers: [UIViewController] = [self.makeLoginController()]
- switch tunnelManager.deviceState {
+ switch self.tunnelManager.deviceState {
case .loggedIn:
let didDismissModalRoot = {
self.handleExpiredAccount()
@@ -313,7 +338,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
var viewControllers: [UIViewController] = [self.makeLoginController()]
- switch TunnelManager.shared.deviceState {
+ switch self.tunnelManager.deviceState {
case .loggedIn:
let connectController = self.makeConnectViewController()
self.connectController = connectController
@@ -346,9 +371,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
{
let navController = SettingsNavigationController(
interactorFactory: SettingsInteractorFactory(
- storePaymentManager: .shared,
- tunnelManager: .shared,
- apiProxy: REST.ProxyFactory.shared.createAPIProxy()
+ storePaymentManager: storePaymentManager,
+ tunnelManager: tunnelManager,
+ apiProxy: apiProxy
)
)
navController.settingsDelegate = self
@@ -370,8 +395,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private func makeOutOfTimeViewController() -> OutOfTimeViewController {
let viewController = OutOfTimeViewController(
interactor: OutOfTimeInteractor(
- storePaymentManager: .shared,
- tunnelManager: .shared
+ storePaymentManager: storePaymentManager,
+ tunnelManager: tunnelManager
)
)
viewController.delegate = self
@@ -380,7 +405,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private func makeConnectViewController() -> ConnectViewController {
let connectController = ConnectViewController(
- interactor: ConnectInteractor(tunnelManager: .shared)
+ interactor: ConnectInteractor(tunnelManager: tunnelManager)
)
connectController.delegate = self
@@ -391,11 +416,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
let selectLocationController = SelectLocationViewController()
selectLocationController.delegate = self
- if let cachedRelays = try? RelayCacheTracker.shared.getCachedRelays() {
+ if let cachedRelays = try? relayCacheTracker.getCachedRelays() {
selectLocationController.setCachedRelays(cachedRelays)
}
- let relayConstraints = TunnelManager.shared.settings.relayConstraints
+ let relayConstraints = tunnelManager.settings.relayConstraints
selectLocationController.setSelectedRelayLocation(
relayConstraints.location.value,
@@ -426,7 +451,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private func makeRevokedDeviceController() -> RevokedDeviceViewController {
let controller = RevokedDeviceViewController(
- interactor: RevokedDeviceInteractor(tunnelManager: .shared)
+ interactor: RevokedDeviceInteractor(tunnelManager: tunnelManager)
)
controller.delegate = self
return controller
@@ -439,7 +464,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
}
private func handleExpiredAccount() {
- guard case let .loggedIn(accountData, _) = TunnelManager.shared.deviceState,
+ guard case let .loggedIn(accountData, _) = tunnelManager.deviceState,
accountData.expiry <= Date() else { return }
switch UIDevice.current.userInterfaceIdiom {
@@ -571,7 +596,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
) {
setEnableSettingsButton(isEnabled: false, from: controller)
- TunnelManager.shared.setAccount(action: action.setAccountAction) { operationCompletion in
+ tunnelManager.setAccount(action: action.setAccountAction) { operationCompletion in
switch operationCompletion {
case .success:
// RootContainer's settings button will be re-enabled in
@@ -587,7 +612,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
self.lastLoginAction = action
let deviceController = DeviceManagementViewController(
- interactor: DeviceManagementInteractor(accountNumber: accountNumber)
+ interactor: DeviceManagementInteractor(
+ accountNumber: accountNumber,
+ devicesProxy: self.devicesProxy
+ )
)
deviceController.delegate = self
@@ -621,7 +649,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
rootContainer.removeSettingsButtonFromPresentationContainer()
setEnableSettingsButton(isEnabled: true, from: controller)
- let relayConstraints = TunnelManager.shared.settings.relayConstraints
+ let relayConstraints = tunnelManager.settings.relayConstraints
selectLocationViewController?.setSelectedRelayLocation(
relayConstraints.location.value,
animated: false,
@@ -650,7 +678,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private func setUpOutOfTimeTimer() {
outOfTimeTimer?.invalidate()
- guard case let .loggedIn(accountData, _) = TunnelManager.shared.deviceState,
+ guard case let .loggedIn(accountData, _) = tunnelManager.deviceState,
accountData.expiry > Date() else { return }
let timer = Timer(
@@ -778,15 +806,15 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, UISplitViewControllerDe
private func selectLocationControllerDidSelectRelayLocation(_ relayLocation: RelayLocation) {
let relayConstraints = RelayConstraints(location: .only(relayLocation))
- TunnelManager.shared.setRelayConstraints(relayConstraints) {
- TunnelManager.shared.startTunnel()
+ tunnelManager.setRelayConstraints(relayConstraints) {
+ self.tunnelManager.startTunnel()
}
}
// MARK: - RevokedDeviceViewControllerDelegate
func revokedDeviceControllerDidRequestLogout(_ controller: RevokedDeviceViewController) {
- TunnelManager.shared.unsetAccount { [weak self] in
+ tunnelManager.unsetAccount { [weak self] in
self?.showLoginViewAfterLogout(dismissController: nil)
}
}
diff --git a/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift b/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift
index fa8963f5b6..d9521bfda6 100644
--- a/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift
+++ b/ios/MullvadVPN/StorePaymentManager/StorePaymentManager.swift
@@ -6,12 +6,12 @@
// Copyright © 2020 Mullvad VPN AB. All rights reserved.
//
-import Foundation
import MullvadLogging
import MullvadREST
import MullvadTypes
import Operations
import StoreKit
+import UIKit
final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
private enum OperationCategory {
@@ -19,13 +19,6 @@ final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
static let productsRequest = "StorePaymentManager.productsRequest"
}
- /// A shared instance of `AppStorePaymentManager`
- static let shared = StorePaymentManager(
- queue: SKPaymentQueue.default(),
- apiProxy: REST.ProxyFactory.shared.createAPIProxy(),
- accountsProxy: REST.ProxyFactory.shared.createAccountsProxy()
- )
-
private let logger = Logger(label: "StorePaymentManager")
private let operationQueue: OperationQueue = {
@@ -34,6 +27,7 @@ final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
return queue
}()
+ private let application: UIApplication
private let paymentQueue: SKPaymentQueue
private let apiProxy: REST.APIProxy
private let accountsProxy: REST.AccountsProxy
@@ -69,7 +63,13 @@ final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
return SKPaymentQueue.canMakePayments()
}
- init(queue: SKPaymentQueue, apiProxy: REST.APIProxy, accountsProxy: REST.AccountsProxy) {
+ init(
+ application: UIApplication,
+ queue: SKPaymentQueue,
+ apiProxy: REST.APIProxy,
+ accountsProxy: REST.AccountsProxy
+ ) {
+ self.application = application
paymentQueue = queue
self.apiProxy = apiProxy
self.accountsProxy = accountsProxy
@@ -201,7 +201,7 @@ final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
}
accountOperation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: "Validate account number",
cancelUponExpiration: false
))
@@ -240,7 +240,7 @@ final class StorePaymentManager: NSObject, SKPaymentTransactionObserver {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Send AppStore receipt",
cancelUponExpiration: true
)
diff --git a/ios/MullvadVPN/TransportMonitor/TransportMonitor.swift b/ios/MullvadVPN/TransportMonitor/TransportMonitor.swift
index 7b0e49f70b..9b98cecfe0 100644
--- a/ios/MullvadVPN/TransportMonitor/TransportMonitor.swift
+++ b/ios/MullvadVPN/TransportMonitor/TransportMonitor.swift
@@ -11,11 +11,13 @@ import MullvadREST
class TransportMonitor: TunnelObserver {
private let tunnelManager: TunnelManager
+ private let transportRegistry: REST.TransportRegistry
private let packetTunnelTransport: PacketTunnelTransport
private let urlSessionTransport: REST.URLSessionTransport
- init(tunnelManager: TunnelManager = .shared) {
+ init(tunnelManager: TunnelManager, transportRegistry: REST.TransportRegistry) {
self.tunnelManager = tunnelManager
+ self.transportRegistry = transportRegistry
packetTunnelTransport = PacketTunnelTransport(tunnelManager: tunnelManager)
urlSessionTransport = REST.URLSessionTransport(urlSession: REST.makeURLSession())
@@ -49,7 +51,7 @@ class TransportMonitor: TunnelObserver {
// MARK: - Private
private func setTransports() {
- REST.TransportRegistry.shared.setTransport(
+ transportRegistry.setTransport(
stateUpdated(
tunnelState: tunnelManager.tunnelStatus.state,
deviceState: tunnelManager.deviceState
diff --git a/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
index fd145e332a..42ed31c941 100644
--- a/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/ReconnectTunnelOperation.swift
@@ -36,15 +36,7 @@ class ReconnectTunnelOperation: ResultOperation<Void, Error> {
}
do {
- var selectorResult: RelaySelectorResult?
-
- if selectNewRelay {
- let cachedRelays = try RelayCacheTracker.shared.getCachedRelays()
- selectorResult = try RelaySelector.evaluate(
- relays: cachedRelays.relays,
- constraints: interactor.settings.relayConstraints
- )
- }
+ let selectorResult = selectNewRelay ? try interactor.selectRelay() : nil
task = tunnel.reconnectTunnel(
relaySelectorResult: selectorResult
diff --git a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
index d646103ce5..e2f9fa1c37 100644
--- a/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
+++ b/ios/MullvadVPN/TunnelManager/StartTunnelOperation.swift
@@ -51,11 +51,7 @@ class StartTunnelOperation: ResultOperation<Void, Error> {
case .disconnected, .pendingReconnect:
do {
- let cachedRelays = try RelayCacheTracker.shared.getCachedRelays()
- let selectorResult = try RelaySelector.evaluate(
- relays: cachedRelays.relays,
- constraints: interactor.settings.relayConstraints
- )
+ let selectorResult = try interactor.selectRelay()
makeTunnelProviderAndStartTunnel(selectorResult: selectorResult) { error in
self.finish(completion: OperationCompletion(error: error))
diff --git a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
index f4fb16079b..eec47e1863 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelInteractor.swift
@@ -7,6 +7,8 @@
//
import Foundation
+import RelayCache
+import RelaySelector
protocol TunnelInteractor {
// MARK: - Tunnel manipulation
@@ -32,4 +34,5 @@ protocol TunnelInteractor {
func startTunnel()
func prepareForVPNConfigurationDeletion()
+ func selectRelay() throws -> RelaySelectorResult
}
diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
index 727c8ecd8f..9bdc4ec8e9 100644
--- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift
+++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift
@@ -12,6 +12,7 @@ import MullvadREST
import MullvadTypes
import NetworkExtension
import Operations
+import RelayCache
import RelaySelector
import StoreKit
import TunnelProviderMessaging
@@ -46,13 +47,10 @@ final class TunnelManager: StorePaymentObserver {
}
}
- static let shared = TunnelManager(
- accountsProxy: REST.ProxyFactory.shared.createAccountsProxy(),
- devicesProxy: REST.ProxyFactory.shared.createDevicesProxy()
- )
-
// MARK: - Internal variables
+ private let application: UIApplication
+ private let relayCacheTracker: RelayCacheTracker
private let accountsProxy: REST.AccountsProxy
private let devicesProxy: REST.DevicesProxy
@@ -87,7 +85,14 @@ final class TunnelManager: StorePaymentObserver {
// MARK: - Initialization
- private init(accountsProxy: REST.AccountsProxy, devicesProxy: REST.DevicesProxy) {
+ init(
+ application: UIApplication,
+ relayCacheTracker: RelayCacheTracker,
+ accountsProxy: REST.AccountsProxy,
+ devicesProxy: REST.DevicesProxy
+ ) {
+ self.application = application
+ self.relayCacheTracker = relayCacheTracker
self.accountsProxy = accountsProxy
self.devicesProxy = devicesProxy
self.operationQueue.name = "TunnelManager.operationQueue"
@@ -106,8 +111,6 @@ final class TunnelManager: StorePaymentObserver {
isRunningPeriodicPrivateKeyRotation = true
updatePrivateKeyRotationTimer()
-
- nslock.unlock()
}
func stopPeriodicPrivateKeyRotation() {
@@ -237,7 +240,7 @@ final class TunnelManager: StorePaymentObserver {
groupOperation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Load tunnel configuration",
cancelUponExpiration: false
)
@@ -290,7 +293,7 @@ final class TunnelManager: StorePaymentObserver {
)
operation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: "Start tunnel",
cancelUponExpiration: true
))
@@ -325,7 +328,7 @@ final class TunnelManager: StorePaymentObserver {
}
operation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: "Stop tunnel",
cancelUponExpiration: true
))
@@ -353,7 +356,7 @@ final class TunnelManager: StorePaymentObserver {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Reconnect tunnel",
cancelUponExpiration: true
)
@@ -385,7 +388,7 @@ final class TunnelManager: StorePaymentObserver {
}
operation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: action.taskName,
cancelUponExpiration: true
))
@@ -423,7 +426,7 @@ final class TunnelManager: StorePaymentObserver {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Update account data",
cancelUponExpiration: true
)
@@ -459,7 +462,7 @@ final class TunnelManager: StorePaymentObserver {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Update device data",
cancelUponExpiration: true
)
@@ -514,7 +517,7 @@ final class TunnelManager: StorePaymentObserver {
operation.addObserver(
BackgroundObserver(
- application: .shared,
+ application: application,
name: "Rotate private key",
cancelUponExpiration: true
)
@@ -799,6 +802,15 @@ final class TunnelManager: StorePaymentObserver {
// MARK: - Private methods
+ fileprivate func selectRelay() throws -> RelaySelectorResult {
+ let cachedRelays = try relayCacheTracker.getCachedRelays()
+
+ return try RelaySelector.evaluate(
+ relays: cachedRelays.relays,
+ constraints: settings.relayConstraints
+ )
+ }
+
fileprivate func prepareForVPNConfigurationDeletion() {
nslock.lock()
defer { nslock.unlock() }
@@ -934,7 +946,7 @@ final class TunnelManager: StorePaymentObserver {
}
operation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: taskName,
cancelUponExpiration: false
))
@@ -970,7 +982,7 @@ final class TunnelManager: StorePaymentObserver {
}
operation.addObserver(BackgroundObserver(
- application: .shared,
+ application: application,
name: taskName,
cancelUponExpiration: false
))
@@ -1068,4 +1080,8 @@ private struct TunnelInteractorProxy: TunnelInteractor {
func prepareForVPNConfigurationDeletion() {
tunnelManager.prepareForVPNConfigurationDeletion()
}
+
+ func selectRelay() throws -> RelaySelectorResult {
+ return try tunnelManager.selectRelay()
+ }
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider.swift
index b222e81720..d91f6b1193 100644
--- a/ios/PacketTunnel/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider.swift
@@ -73,12 +73,13 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
private var tunnelMonitor: TunnelMonitor!
/// Account data request proxy
- private lazy var accountProxy = REST.ProxyFactory.shared.createAccountsProxy()
+ private let accountsProxy: REST.AccountsProxy
/// Device data request proxy
- private lazy var deviceProxy = REST.ProxyFactory.shared.createDevicesProxy()
+ private let devicesProxy: REST.DevicesProxy
- private lazy var checkDeviceStateTask: Cancellable? = nil
+ /// Last device check task.
+ private var checkDeviceStateTask: Cancellable?
/// Internal operation queue.
private let operationQueue = AsyncOperationQueue()
@@ -108,11 +109,21 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
providerLogger = Logger(label: "PacketTunnelProvider")
tunnelLogger = Logger(label: "WireGuard")
- super.init()
-
- REST.TransportRegistry.shared.setTransport(
- REST.URLSessionTransport(urlSession: urlSession)
+ let addressCache = REST.AddressCache(
+ securityGroupIdentifier: ApplicationConfiguration.securityGroupIdentifier,
+ isReadOnly: true
+ )!
+ let transportRegistry = REST.TransportRegistry(
+ transport: REST.URLSessionTransport(urlSession: urlSession)
+ )
+ let proxyFactory = REST.ProxyFactory.makeProxyFactory(
+ transportRegistry: transportRegistry,
+ addressCache: addressCache
)
+ accountsProxy = proxyFactory.createAccountsProxy()
+ devicesProxy = proxyFactory.createDevicesProxy()
+
+ super.init()
adapter = WireGuardAdapter(
with: self,
@@ -172,7 +183,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
} catch {
providerLogger.error(
error: error,
- message: "Failed to start the tunnel."
+ message: "Failed to read tunnel configuration when starting the tunnel."
)
completionHandler(error)
@@ -593,7 +604,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
)
operation.setExecutionBlock { operation in
- let task = self.accountProxy.getAccountData(
+ let task = self.accountsProxy.getAccountData(
accountNumber: accountNumber,
retryStrategy: .noRetry
) { completion in
@@ -614,7 +625,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, TunnelMonitorDelegate {
let operation = ResultBlockOperation<REST.Device, REST.Error>(dispatchQueue: dispatchQueue)
operation.setExecutionBlock { operation in
- let task = self.deviceProxy.getDevice(
+ let task = self.devicesProxy.getDevice(
accountNumber: accountNumber,
identifier: identifier,
retryStrategy: .noRetry