Skip to content

Commit

Permalink
Add pixels for our main VPN funnels (#698)
Browse files Browse the repository at this point in the history
Task/Issue URL: https://app.asana.com/0/0/1206737255908394/f

macOS PR: duckduckgo/macos-browser#2304
iOS PR: duckduckgo/iOS#2543

## Description

Add pixels to better track all main VPN funnels.  For BSK this means:
- VPN Tunnel Start
- VPN Tunnel Update (change location, etc)
  • Loading branch information
diegoreymendez authored Mar 7, 2024
1 parent 045a878 commit d9de416
Showing 1 changed file with 56 additions and 38 deletions.
94 changes: 56 additions & 38 deletions Sources/NetworkProtection/PacketTunnelProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,23 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
public enum Event {
case userBecameActive
case reportConnectionAttempt(attempt: ConnectionAttempt)
case tunnelStartAttempt(_ step: TunnelStartAttemptStep)
case tunnelUpdateAttempt(_ step: TunnelUpdateAttemptStep)
case reportTunnelFailure(result: NetworkProtectionTunnelFailureMonitor.Result)
case reportLatency(result: NetworkProtectionLatencyMonitor.Result)
case rekeyCompleted
case rekeyAttempt(_ step: RekeyAttemptStep)
}

public enum AttemptStep {
case begin
case success
case failure(_ error: Error)
}

public typealias TunnelStartAttemptStep = AttemptStep
public typealias TunnelUpdateAttemptStep = AttemptStep
public typealias RekeyAttemptStep = AttemptStep

public enum ConnectionAttempt {
case connecting
case success
Expand Down Expand Up @@ -181,12 +193,14 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
}

os_log("Rekeying...", log: .networkProtectionKeyManagement)
providerEvents.fire(.rekeyAttempt(.begin))

do {
try await updateTunnelConfiguration(reassert: false, regenerateKey: true)
providerEvents.fire(.rekeyCompleted)
providerEvents.fire(.rekeyAttempt(.success))
} catch {
os_log("Rekey attempt failed. This is not an error if you're using debug Key Management options: %{public}@", log: .networkProtectionKeyManagement, type: .error, String(describing: error))
providerEvents.fire(.rekeyAttempt(.failure(error)))
}
}

Expand Down Expand Up @@ -480,6 +494,7 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {

open override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
Task { @MainActor in
providerEvents.fire(.tunnelStartAttempt(.begin))
prepareToConnect(using: tunnelProviderProtocol)

connectionStatus = .connecting
Expand All @@ -489,26 +504,21 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {

resetIssueStateOnTunnelStart(startupOptions)

let startTime = DispatchTime.now()

let internalCompletionHandler = { [weak self] (error: Error?) in
guard let self else {
completionHandler(error)
return
}

let internalCompletionHandler = { [weak self, providerEvents] (error: Error?) in
guard let error else {
completionHandler(nil)
providerEvents.fire(.tunnelStartAttempt(.success))
return
}

let handler = {
let errorDescription = (error as? LocalizedError)?.localizedDescription ?? String(describing: error)

os_log("Tunnel startup error: %{public}@", type: .error, errorDescription)
self.controllerErrorStore.lastErrorMessage = errorDescription
self.connectionStatus = .disconnected
self?.controllerErrorStore.lastErrorMessage = errorDescription
self?.connectionStatus = .disconnected

providerEvents.fire(.tunnelStartAttempt(.failure(error)))
completionHandler(error)
}

Expand Down Expand Up @@ -708,43 +718,51 @@ open class PacketTunnelProvider: NEPacketTunnelProvider {
reassert: Bool,
regenerateKey: Bool = false) async throws {

providerEvents.fire(.tunnelUpdateAttempt(.begin))

if reassert {
await stopMonitors()
}

let tunnelConfiguration = try await generateTunnelConfiguration(environment: environment,
serverSelectionMethod: serverSelectionMethod,
includedRoutes: includedRoutes ?? [],
excludedRoutes: settings.excludedRanges,
regenerateKey: regenerateKey)

try await withCheckedThrowingContinuation { [weak self] (continuation: CheckedContinuation<Void, Error>) in
guard let self = self else {
continuation.resume()
return
}

self.adapter.update(tunnelConfiguration: tunnelConfiguration, reassert: reassert) { [weak self] error in
if let error = error {
os_log("🔵 Failed to update the configuration: %{public}@", type: .error, error.localizedDescription)
self?.debugEvents?.fire(error.networkProtectionError)
continuation.resume(throwing: error)
do {
let tunnelConfiguration = try await generateTunnelConfiguration(environment: environment,
serverSelectionMethod: serverSelectionMethod,
includedRoutes: includedRoutes ?? [],
excludedRoutes: settings.excludedRanges,
regenerateKey: regenerateKey)

try await withCheckedThrowingContinuation { [weak self] (continuation: CheckedContinuation<Void, Error>) in
guard let self = self else {
continuation.resume()
return
}

Task { [weak self] in
if reassert {
do {
try await self?.handleAdapterStarted(startReason: .reconnected)
} catch {
continuation.resume(throwing: error)
return
}
self.adapter.update(tunnelConfiguration: tunnelConfiguration, reassert: reassert) { [weak self] error in
if let error = error {
os_log("🔵 Failed to update the configuration: %{public}@", type: .error, error.localizedDescription)
self?.debugEvents?.fire(error.networkProtectionError)
continuation.resume(throwing: error)
return
}

continuation.resume()
Task { [weak self] in
if reassert {
do {
try await self?.handleAdapterStarted(startReason: .reconnected)
} catch {
continuation.resume(throwing: error)
return
}
}

continuation.resume()
}
}
}

providerEvents.fire(.tunnelUpdateAttempt(.success))
} catch {
providerEvents.fire(.tunnelUpdateAttempt(.failure(error)))
}
}

Expand Down

0 comments on commit d9de416

Please sign in to comment.