diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2023-03-03 17:54:03 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2023-03-06 17:00:55 +0100 |
| commit | f63f74220553333e0236f6c22e95f42b8be37d73 (patch) | |
| tree | f0f2ba2d2f87993657d3504a7cdd2393a6b4dcc3 | |
| parent | a9bd2196c06646f7cbd486dda9fc29bfb7a2702e (diff) | |
| download | mullvadvpn-f63f74220553333e0236f6c22e95f42b8be37d73.tar.xz mullvadvpn-f63f74220553333e0236f6c22e95f42b8be37d73.zip | |
Add background observer for IPC operations
| -rw-r--r-- | ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift | 29 | ||||
| -rw-r--r-- | ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift | 4 |
2 files changed, 31 insertions, 2 deletions
diff --git a/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift b/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift index b7fafa326d..16a0ea1a1c 100644 --- a/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift +++ b/ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift @@ -6,11 +6,11 @@ // Copyright © 2022 Mullvad VPN AB. All rights reserved. // -import Foundation import MullvadTypes import NetworkExtension import Operations import TunnelProviderMessaging +import UIKit /// Delay for sending tunnel provider messages to the tunnel when in connecting state. /// Used to workaround a bug when talking to the tunnel too early during startup may cause it @@ -23,6 +23,7 @@ private let defaultTimeout: TimeInterval = 5 final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output> { typealias DecoderHandler = (Data?) throws -> Output + private let application: UIApplication private let tunnel: Tunnel private let message: TunnelProviderMessage private let timeout: TimeInterval @@ -37,12 +38,14 @@ final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output> init( dispatchQueue: DispatchQueue, + application: UIApplication, tunnel: Tunnel, message: TunnelProviderMessage, timeout: TimeInterval? = nil, decoderHandler: @escaping DecoderHandler, completionHandler: CompletionHandler? ) { + self.application = application self.tunnel = tunnel self.message = message self.timeout = timeout ?? defaultTimeout @@ -54,6 +57,14 @@ final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output> completionQueue: dispatchQueue, completionHandler: completionHandler ) + + addObserver( + BackgroundObserver( + application: application, + name: "Send tunnel provider message: \(message)", + cancelUponExpiration: true + ) + ) } override func main() { @@ -184,6 +195,11 @@ final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output> return } + guard application.backgroundTimeRemaining > timeout else { + finish(result: .failure(SendTunnelProviderMessageError.notEnoughBackgroundTime)) + return + } + // Send IPC message. do { try tunnel.sendProviderMessage(messageData) { [weak self] responseData in @@ -204,6 +220,7 @@ final class SendTunnelProviderMessageOperation<Output>: ResultOperation<Output> extension SendTunnelProviderMessageOperation where Output: Codable { convenience init( dispatchQueue: DispatchQueue, + application: UIApplication, tunnel: Tunnel, message: TunnelProviderMessage, timeout: TimeInterval? = nil, @@ -211,6 +228,7 @@ extension SendTunnelProviderMessageOperation where Output: Codable { ) { self.init( dispatchQueue: dispatchQueue, + application: application, tunnel: tunnel, message: message, timeout: timeout, @@ -229,6 +247,7 @@ extension SendTunnelProviderMessageOperation where Output: Codable { extension SendTunnelProviderMessageOperation where Output == Void { convenience init( dispatchQueue: DispatchQueue, + application: UIApplication, tunnel: Tunnel, message: TunnelProviderMessage, timeout: TimeInterval? = nil, @@ -236,6 +255,7 @@ extension SendTunnelProviderMessageOperation where Output == Void { ) { self.init( dispatchQueue: dispatchQueue, + application: application, tunnel: tunnel, message: message, timeout: timeout, @@ -255,12 +275,17 @@ enum SendTunnelProviderMessageError: LocalizedError, WrappingError { /// System error. case system(Error) + /// Not enough background time to accommodate the operation. + case notEnoughBackgroundTime + var errorDescription: String? { switch self { case let .tunnelDown(status): return "Tunnel is either down or about to go down (status: \(status))." case .timeout: return "Send timeout." + case .notEnoughBackgroundTime: + return "Not enough background time to accommodate the operation." case let .system(error): return "System error: \(error.localizedDescription)" } @@ -270,7 +295,7 @@ enum SendTunnelProviderMessageError: LocalizedError, WrappingError { switch self { case let .system(error): return error - case .timeout, .tunnelDown: + case .timeout, .tunnelDown, .notEnoughBackgroundTime: return nil } } diff --git a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift index 7dea6451f6..9859da99b8 100644 --- a/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift +++ b/ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift @@ -31,6 +31,7 @@ extension Tunnel { ) -> Cancellable { let operation = SendTunnelProviderMessageOperation( dispatchQueue: dispatchQueue, + application: .shared, tunnel: self, message: .reconnectTunnel(relaySelectorResult), completionHandler: completionHandler @@ -47,6 +48,7 @@ extension Tunnel { ) -> Cancellable { let operation = SendTunnelProviderMessageOperation( dispatchQueue: dispatchQueue, + application: .shared, tunnel: self, message: .getTunnelStatus, completionHandler: completionHandler @@ -64,6 +66,7 @@ extension Tunnel { ) -> Cancellable { let operation = SendTunnelProviderMessageOperation( dispatchQueue: dispatchQueue, + application: .shared, tunnel: self, message: .sendURLRequest(proxyRequest), timeout: proxyRequestTimeout, @@ -76,6 +79,7 @@ extension Tunnel { let cancelOperation = SendTunnelProviderMessageOperation( dispatchQueue: dispatchQueue, + application: .shared, tunnel: self, message: .cancelURLRequest(proxyRequest.id), completionHandler: nil |
