diff options
| -rw-r--r-- | ios/PacketTunnel/PacketTunnelProvider/PacketTunnelPathObserver.swift | 28 | ||||
| -rw-r--r-- | ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift | 4 |
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() |
