diff options
| author | Steffen <steffen.ernst@mullvad.net> | 2025-08-04 13:55:01 +0200 |
|---|---|---|
| committer | Jon Petersson <jon.petersson@mullvad.net> | 2025-08-12 14:49:43 +0200 |
| commit | eb18a74782980b0bc65986191c57fc5901dc1ebf (patch) | |
| tree | c35b9ee2a82ca14de6fe1d1abecac4f30d83b5f3 /ios | |
| parent | 63cb6f5a0b27d6d54769e8afb98ed291254d1123 (diff) | |
| download | mullvadvpn-eb18a74782980b0bc65986191c57fc5901dc1ebf.tar.xz mullvadvpn-eb18a74782980b0bc65986191c57fc5901dc1ebf.zip | |
Separate access method rotation request from state
Diffstat (limited to 'ios')
8 files changed, 44 insertions, 19 deletions
diff --git a/ios/MullvadMockData/MullvadREST/AccessMethodRepository+Stub.swift b/ios/MullvadMockData/MullvadREST/AccessMethodRepository+Stub.swift index 6e7dbb93ef..148927711f 100644 --- a/ios/MullvadMockData/MullvadREST/AccessMethodRepository+Stub.swift +++ b/ios/MullvadMockData/MullvadREST/AccessMethodRepository+Stub.swift @@ -28,7 +28,7 @@ public struct AccessMethodRepositoryStub: AccessMethodRepositoryDataSource, @unc passthroughSubject.value } - public func saveLastReachable(_ method: PersistentAccessMethod) {} + public func requestAccessMethod(_ method: PersistentAccessMethod) {} public func fetchLastReachable() -> PersistentAccessMethod { directAccess diff --git a/ios/MullvadREST/Transport/AccessMethodIterator.swift b/ios/MullvadREST/Transport/AccessMethodIterator.swift index 91de54bbd7..d1672ad8fb 100644 --- a/ios/MullvadREST/Transport/AccessMethodIterator.swift +++ b/ios/MullvadREST/Transport/AccessMethodIterator.swift @@ -8,10 +8,13 @@ import Combine import Foundation +import MullvadLogging import MullvadSettings import MullvadTypes final class AccessMethodIterator: @unchecked Sendable, SwiftConnectionModeProviding { + private let logger = Logger(label: "AccessMethodIterator") + private let dataSource: AccessMethodRepositoryDataSource private var index = 0 @@ -47,13 +50,14 @@ final class AccessMethodIterator: @unchecked Sendable, SwiftConnectionModeProvid index = firstIndex } - dataSource.saveLastReachable(pick()) + let newAccessMethod = pick() + dataSource.requestAccessMethod(newAccessMethod) } func rotate() { let (partial, isOverflow) = index.addingReportingOverflow(1) index = isOverflow ? 0 : partial - dataSource.saveLastReachable(pick()) + dataSource.requestAccessMethod(pick()) } func pick() -> PersistentAccessMethod { diff --git a/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift b/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift index c683a10af6..bb94759717 100644 --- a/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift +++ b/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift @@ -17,12 +17,12 @@ public class MullvadAccessMethodReceiver { public init( apiContext: MullvadApiContext, accessMethodsDataSource: AnyPublisher<[PersistentAccessMethod], Never>, - lastReachableDataSource: AnyPublisher<PersistentAccessMethod, Never> + requestDataSource: AnyPublisher<PersistentAccessMethod, Never> ) { self.apiContext = apiContext - lastReachableDataSource.sink { [weak self] in - self?.saveLastReachable($0) + requestDataSource.sink { [weak self] latestReachable in + self?.saveLastReachable(latestReachable) } .store(in: &cancellables) diff --git a/ios/MullvadSettings/AccessMethodRepository.swift b/ios/MullvadSettings/AccessMethodRepository.swift index b01c966b1a..07e1ad2a61 100644 --- a/ios/MullvadSettings/AccessMethodRepository.swift +++ b/ios/MullvadSettings/AccessMethodRepository.swift @@ -46,23 +46,37 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked accessMethodsSubject.eraseToAnyPublisher() } - private let lastReachableAccessMethodSubject: CurrentValueSubject<PersistentAccessMethod, Never> - public var lastReachableAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { - lastReachableAccessMethodSubject.eraseToAnyPublisher() + private let requestAccessMethodSubject: PassthroughSubject<PersistentAccessMethod, Never> + public var requestAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { + requestAccessMethodSubject.eraseToAnyPublisher() + } + + private let currentAccessMethodSubject: CurrentValueSubject<PersistentAccessMethod, Never> + public var currentAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { + currentAccessMethodSubject.eraseToAnyPublisher() } public var directAccess: PersistentAccessMethod { direct } + private var cancellables: Set<Combine.AnyCancellable> = [] + public init() { accessMethodsSubject = CurrentValueSubject([]) - lastReachableAccessMethodSubject = CurrentValueSubject(direct) + requestAccessMethodSubject = PassthroughSubject() + currentAccessMethodSubject = CurrentValueSubject(direct) addDefaultsMethods() accessMethodsSubject.send(fetchAll()) - lastReachableAccessMethodSubject.send(fetchLastReachable()) + requestAccessMethodSubject.send(fetchLastReachable()) + + currentAccessMethodPublisher + .removeDuplicates() + .sink { [weak self] currentAccessMethod in + self?.saveCurrentAccessMethod(currentAccessMethod) + }.store(in: &cancellables) } public func save(_ method: PersistentAccessMethod, notifyingAPI: Bool = false) { @@ -87,13 +101,16 @@ public class AccessMethodRepository: AccessMethodRepositoryProtocol, @unchecked } } - public func saveLastReachable(_ method: PersistentAccessMethod) { + public func requestAccessMethod(_ method: PersistentAccessMethod) { + requestAccessMethodSubject.send(method) + } + + private func saveCurrentAccessMethod(_ method: PersistentAccessMethod) { var methodStore = readApiAccessMethodStore() methodStore.lastReachableAccessMethod = method do { try writeApiAccessMethodStore(methodStore) - lastReachableAccessMethodSubject.send(method) } catch { logger.error("Could not save last reachable access method: \(method) \nError: \(error)") } @@ -184,6 +201,10 @@ extension AccessMethodRepository: MullvadAccessMethodChangeListening { logger.warning("Change reported to method with unknown ID: \(uuid)") return } - save(method) + + Task { + print("Mullvad API changed access method to \(method.name)") + currentAccessMethodSubject.send(method) + } } } diff --git a/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift b/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift index 3f108a85bc..d44f009911 100644 --- a/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift +++ b/ios/MullvadSettings/AccessMethodRepositoryProtocol.swift @@ -21,7 +21,7 @@ public protocol AccessMethodRepositoryDataSource: Sendable { func fetchAll() -> [PersistentAccessMethod] /// Save last reachable access method to the persistent store. - func saveLastReachable(_ method: PersistentAccessMethod) + func requestAccessMethod(_ method: PersistentAccessMethod) /// Fetch last reachable access method from the persistent store. func fetchLastReachable() -> PersistentAccessMethod @@ -29,7 +29,7 @@ public protocol AccessMethodRepositoryDataSource: Sendable { public protocol AccessMethodRepositoryProtocol: AccessMethodRepositoryDataSource { /// Publisher that propagates a snapshot of last reachable access method upon modifications. - var lastReachableAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { get } + var currentAccessMethodPublisher: AnyPublisher<PersistentAccessMethod, Never> { get } /// Add new access method. /// - Parameter method: persistent access method model. diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift index dee24eaa89..9758a60fc0 100644 --- a/ios/MullvadVPN/AppDelegate.swift +++ b/ios/MullvadVPN/AppDelegate.swift @@ -116,7 +116,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD accessMethodReceiver = MullvadAccessMethodReceiver( apiContext: apiContext, accessMethodsDataSource: accessMethodRepository.accessMethodsPublisher, - lastReachableDataSource: accessMethodRepository.lastReachableAccessMethodPublisher + requestDataSource: accessMethodRepository.requestAccessMethodPublisher ) apiContext.accessMethodChangeListener = accessMethodRepository diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/List/ListAccessMethodInteractor.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/List/ListAccessMethodInteractor.swift index 702922b9c0..cfd5ef9eed 100644 --- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/List/ListAccessMethodInteractor.swift +++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/List/ListAccessMethodInteractor.swift @@ -28,7 +28,7 @@ struct ListAccessMethodInteractor: ListAccessMethodInteractorProtocol { } var itemInUsePublisher: AnyPublisher<ListAccessMethodItem?, Never> { - repository.lastReachableAccessMethodPublisher + repository.currentAccessMethodPublisher .receive(on: RunLoop.main) .map { $0.toListItem() } .eraseToAnyPublisher() diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift index e949a36709..cf405b9701 100644 --- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift +++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift @@ -273,7 +273,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable { accessMethodReceiver = MullvadAccessMethodReceiver( apiContext: apiContext, accessMethodsDataSource: accessMethodRepository.accessMethodsPublisher, - lastReachableDataSource: accessMethodRepository.lastReachableAccessMethodPublisher + requestDataSource: accessMethodRepository.requestAccessMethodPublisher ) encryptedDNSTransport = EncryptedDNSTransport(urlSession: urlSession) |
