Skip to content

Commit

Permalink
Merge branch 'introduce-a-state-that-means-we-are-exchanging-keys-in-…
Browse files Browse the repository at this point in the history
…ios-530'
  • Loading branch information
buggmagnet committed Mar 11, 2024
2 parents 579945f + 8ab109d commit 517de3a
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 76 deletions.
5 changes: 5 additions & 0 deletions ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,11 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
case .connected, .connecting, .reconnecting, .waitingForConnectivity(.noConnection), .error:
tunnelManager.reconnectTunnel(selectNewRelay: true)

#if DEBUG
case .negotiatingKey:
tunnelManager.reconnectTunnel(selectNewRelay: true)
#endif

case .disconnecting, .disconnected:
tunnelManager.startTunnel()

Expand Down
16 changes: 11 additions & 5 deletions ios/MullvadVPN/TunnelManager/MapConnectionStatusOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,27 @@ class MapConnectionStatusOperation: AsyncOperation {
fetchTunnelStatus(tunnel: tunnel) { observedState in
switch observedState {
case let .connected(connectionState):
return connectionState.isNetworkReachable
connectionState.isNetworkReachable
? .connected(connectionState.selectedRelay)
: .waitingForConnectivity(.noConnection)
case let .connecting(connectionState):
return connectionState.isNetworkReachable
connectionState.isNetworkReachable
? .connecting(connectionState.selectedRelay)
: .waitingForConnectivity(.noConnection)
#if DEBUG
case let .negotiatingKey(connectionState):
connectionState.isNetworkReachable
? .negotiatingKey(connectionState.selectedRelay)
: .waitingForConnectivity(.noConnection)
#endif
case let .reconnecting(connectionState):
return connectionState.isNetworkReachable
connectionState.isNetworkReachable
? .reconnecting(connectionState.selectedRelay)
: .waitingForConnectivity(.noConnection)
case let .error(blockedState):
return .error(blockedState.reason)
.error(blockedState.reason)
case .initial, .disconnecting, .disconnected:
return .none
.none
}
}
return
Expand Down
43 changes: 26 additions & 17 deletions ios/MullvadVPN/TunnelManager/StopTunnelOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,36 @@ class StopTunnelOperation: ResultOperation<Void> {
finish(result: .success(()))

case .connected, .connecting, .reconnecting, .waitingForConnectivity(.noConnection), .error:
guard let tunnel = interactor.tunnel else {
finish(result: .failure(UnsetTunnelError()))
return
}
doShutDownTunnel()

// Disable on-demand when stopping the tunnel to prevent it from coming back up
tunnel.isOnDemandEnabled = false

tunnel.saveToPreferences { error in
self.dispatchQueue.async {
if let error {
self.finish(result: .failure(error))
} else {
tunnel.stop()
self.finish(result: .success(()))
}
}
}
#if DEBUG
case .negotiatingKey:
doShutDownTunnel()
#endif

case .disconnected, .disconnecting, .pendingReconnect, .waitingForConnectivity(.noNetwork):
finish(result: .success(()))
}
}

private func doShutDownTunnel() {
guard let tunnel = interactor.tunnel else {
finish(result: .failure(UnsetTunnelError()))
return
}

// Disable on-demand when stopping the tunnel to prevent it from coming back up
tunnel.isOnDemandEnabled = false

tunnel.saveToPreferences { error in
self.dispatchQueue.async {
if let error {
self.finish(result: .failure(error))
} else {
tunnel.stop()
self.finish(result: .success(()))
}
}
}
}
}
5 changes: 5 additions & 0 deletions ios/MullvadVPN/TunnelManager/TunnelManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,11 @@ final class TunnelManager: StorePaymentObserver {
// while the tunnel process is trying to connect.
startPollingTunnelStatus(interval: establishingTunnelStatusPollInterval)

#if DEBUG
case .negotiatingKey:
startPollingTunnelStatus(interval: establishingTunnelStatusPollInterval)
#endif

case .connected, .waitingForConnectivity(.noConnection):
// Start polling tunnel status to keep connectivity status up to date.
startPollingTunnelStatus(interval: establishedTunnelStatusPollInterval)
Expand Down
49 changes: 33 additions & 16 deletions ios/MullvadVPN/TunnelManager/TunnelState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ enum TunnelState: Equatable, CustomStringConvertible {
/// Connecting the tunnel.
case connecting(SelectedRelay?)

#if DEBUG
/// Negotiating a key for post-quantum resistance
case negotiatingKey(SelectedRelay)
#endif

/// Connected the tunnel
case connected(SelectedRelay)

Expand All @@ -75,46 +80,58 @@ enum TunnelState: Equatable, CustomStringConvertible {
var description: String {
switch self {
case .pendingReconnect:
return "pending reconnect after disconnect"
"pending reconnect after disconnect"
case let .connecting(tunnelRelay):
if let tunnelRelay {
return "connecting to \(tunnelRelay.hostname)"
"connecting to \(tunnelRelay.hostname)"
} else {
return "connecting, fetching relay"
"connecting, fetching relay"
}
case let .connected(tunnelRelay):
return "connected to \(tunnelRelay.hostname)"
"connected to \(tunnelRelay.hostname)"
case let .disconnecting(actionAfterDisconnect):
return "disconnecting and then \(actionAfterDisconnect)"
"disconnecting and then \(actionAfterDisconnect)"
case .disconnected:
return "disconnected"
"disconnected"
case let .reconnecting(tunnelRelay):
return "reconnecting to \(tunnelRelay.hostname)"
"reconnecting to \(tunnelRelay.hostname)"
case .waitingForConnectivity:
return "waiting for connectivity"
"waiting for connectivity"
case let .error(blockedStateReason):
return "error state: \(blockedStateReason)"
"error state: \(blockedStateReason)"
#if DEBUG
case let .negotiatingKey(tunnelRelay):
"negotiating key with \(tunnelRelay.hostname)"
#endif
}
}

var isSecured: Bool {
switch self {
case .reconnecting, .connecting, .connected, .waitingForConnectivity(.noConnection), .error(.accountExpired),
.error(.deviceRevoked):
return true
true
case .pendingReconnect, .disconnecting, .disconnected, .waitingForConnectivity(.noNetwork), .error:
return false
false
#if DEBUG
case .negotiatingKey:
false
#endif
}
}

var relay: SelectedRelay? {
switch self {
case let .connected(relay), let .reconnecting(relay):
return relay
relay
case let .connecting(relay):
return relay
relay
#if DEBUG
case let .negotiatingKey(relay):
relay
#endif
case .disconnecting, .disconnected, .waitingForConnectivity, .pendingReconnect, .error:
return nil
nil
}
}
}
Expand All @@ -130,9 +147,9 @@ enum ActionAfterDisconnect: CustomStringConvertible {
var description: String {
switch self {
case .nothing:
return "do nothing"
"do nothing"
case .reconnect:
return "reconnect"
"reconnect"
}
}
}
Loading

0 comments on commit 517de3a

Please sign in to comment.