diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/TunnelShutdownEvent.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/TunnelShutdownEvent.swift index c8c1024bc..de4d2b3b8 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/TunnelShutdownEvent.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Helpers/TunnelShutdownEvent.swift @@ -39,6 +39,7 @@ public struct TunnelShutdownEvent: Codable, CustomStringConvertible { } public enum Action { + case doNothing case signoutImmediately case retryThenSignout } @@ -50,8 +51,10 @@ public struct TunnelShutdownEvent: Codable, CustomStringConvertible { public var action: Action { switch reason { case .stopped(let reason): - if reason == .userInitiated || reason == .userLogout || reason == .userSwitch { + if reason == .userInitiated { return .signoutImmediately + } else if reason == .userLogout || reason == .userSwitch { + return .doNothing } else { return .retryThenSignout } diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/AuthStore.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/AuthStore.swift index c4fe8ef61..88fa384c5 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/AuthStore.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/AuthStore.swift @@ -88,6 +88,9 @@ final class AuthStore: ObservableObject { .sink { [weak self] status in guard let self = self else { return } Task { + if status == .disconnected { + self.handleTunnelDisconnectionEvent() + } if status == .connected { self.resetReconnectionAttemptsRemaining() } @@ -170,26 +173,40 @@ final class AuthStore: ObservableObject { do { try await tunnelStore.start() } catch { - logger.error("\(#function): Error starting tunnel: \(String(describing: error))") - if let tsEvent = TunnelShutdownEvent.loadFromDisk() { - self.logger.log( - "\(#function): Tunnel shutdown event: \(tsEvent, privacy: .public)" + if case TunnelStoreError.startTunnelErrored(let startTunnelError) = error { + logger.error( + "\(#function): Starting tunnel errored: \(String(describing: startTunnelError))" ) - switch tsEvent.action { - case .signoutImmediately: - Task { - await self.signOut() - } - case .retryThenSignout: - self.retryStartTunnel() - } + handleTunnelDisconnectionEvent() } else { - self.logger.log("\(#function): Tunnel shutdown event not found") + logger.error("\(#function): Starting tunnel failed: \(String(describing: error))") + // Disconnection event will be handled in the tunnel status change handler } } } } + func handleTunnelDisconnectionEvent() { + logger.log("\(#function)") + if let tsEvent = TunnelShutdownEvent.loadFromDisk() { + self.logger.log( + "\(#function): Tunnel shutdown event: \(tsEvent, privacy: .public)" + ) + switch tsEvent.action { + case .signoutImmediately: + Task { + await self.signOut() + } + case .retryThenSignout: + self.retryStartTunnel() + case .doNothing: + break + } + } else { + self.logger.log("\(#function): Tunnel shutdown event not found") + } + } + func retryStartTunnel() { // Try to reconnect, but don't try more than 3 times at a time. // If this gets called the third time, sign out. diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/TunnelStore.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/TunnelStore.swift index 6323009b0..99b3386b3 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/TunnelStore.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/TunnelStore.swift @@ -15,6 +15,7 @@ enum TunnelStoreError: Error { case cannotSaveToTunnelWhenConnected case cannotSignOutWhenConnected case stopAlreadyBeingAttempted + case startTunnelErrored(Error) } public struct TunnelProviderKeys { @@ -173,7 +174,11 @@ final class TunnelStore: ObservableObject { try await tunnel.loadFromPreferences() let session = castToSession(tunnel.connection) - try session.startTunnel() + do { + try session.startTunnel() + } catch { + throw TunnelStoreError.startTunnelErrored(error) + } try await withCheckedThrowingContinuation { continuation in self.startTunnelContinuation = continuation }