summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift28
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift4
2 files changed, 19 insertions, 13 deletions
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift
index b16c62f705..56953553dd 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift
@@ -6,17 +6,19 @@
// Copyright © 2023 Mullvad VPN AB. All rights reserved.
//
-import Foundation
+import Combine
import NetworkExtension
import PacketTunnelCore
final class PacketTunnelPathObserver: DefaultPathObserverProtocol {
private weak var packetTunnelProvider: NEPacketTunnelProvider?
private let stateLock = NSLock()
- private var observationToken: NSKeyValueObservation?
+ private var pathUpdatePublisher: AnyCancellable?
+ private let eventQueue: DispatchQueue
- init(packetTunnelProvider: NEPacketTunnelProvider) {
+ init(packetTunnelProvider: NEPacketTunnelProvider, eventQueue: DispatchQueue) {
self.packetTunnelProvider = packetTunnelProvider
+ self.eventQueue = eventQueue
}
var defaultPath: NetworkPath? {
@@ -25,22 +27,26 @@ final class PacketTunnelPathObserver: DefaultPathObserverProtocol {
func start(_ body: @escaping (NetworkPath) -> Void) {
stateLock.withLock {
- observationToken?.invalidate()
+ pathUpdatePublisher?.cancel()
// Normally packet tunnel provider should exist throughout the network extension lifetime.
- observationToken = packetTunnelProvider?.observe(\.defaultPath, options: [.new]) { _, change in
- let nwPath = change.newValue.flatMap { $0 }
- if let nwPath {
- body(nwPath)
+ pathUpdatePublisher = packetTunnelProvider?.publisher(for: \.defaultPath)
+ .removeDuplicates(by: { oldPath, newPath in
+ oldPath?.status == newPath?.status
+ })
+ .throttle(for: .seconds(2), scheduler: eventQueue, latest: true)
+ .sink { change in
+ if let change {
+ body(change)
+ }
}
- }
}
}
func stop() {
stateLock.withLock {
- observationToken?.invalidate()
- observationToken = nil
+ pathUpdatePublisher?.cancel()
+ pathUpdatePublisher = nil
}
}
}
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index 4754887979..96d657ce48 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -61,7 +61,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
eventQueue: internalQueue,
pinger: Pinger(replyQueue: internalQueue),
tunnelDeviceInfo: adapter,
- defaultPathObserver: PacketTunnelPathObserver(packetTunnelProvider: self),
+ defaultPathObserver: PacketTunnelPathObserver(packetTunnelProvider: self, eventQueue: internalQueue),
timings: TunnelMonitorTimings()
)
@@ -78,7 +78,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
timings: PacketTunnelActorTimings(),
tunnelAdapter: adapter,
tunnelMonitor: tunnelMonitor,
- defaultPathObserver: PacketTunnelPathObserver(packetTunnelProvider: self),
+ defaultPathObserver: PacketTunnelPathObserver(packetTunnelProvider: self, eventQueue: internalQueue),
blockedStateErrorMapper: BlockedStateErrorMapper(),
relaySelector: RelaySelectorWrapper(relayCache: relayCache),
settingsReader: SettingsReader()