summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-03-03 17:54:03 +0100
committerAndrej Mihajlov <and@mullvad.net>2023-03-06 17:00:55 +0100
commitf63f74220553333e0236f6c22e95f42b8be37d73 (patch)
treef0f2ba2d2f87993657d3504a7cdd2393a6b4dcc3
parenta9bd2196c06646f7cbd486dda9fc29bfb7a2702e (diff)
downloadmullvadvpn-f63f74220553333e0236f6c22e95f42b8be37d73.tar.xz
mullvadvpn-f63f74220553333e0236f6c22e95f42b8be37d73.zip
Add background observer for IPC operations
-rw-r--r--ios/MullvadVPN/TunnelManager/SendTunnelProviderMessageOperation.swift29
-rw-r--r--ios/MullvadVPN/TunnelManager/Tunnel+Messaging.swift4
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