diff options
-rw-r--r-- | WireGuard/WireGuard.xcodeproj/project.pbxproj | 4 | ||||
-rw-r--r-- | WireGuard/WireGuard/Tunnel/TunnelErrors.swift | 91 | ||||
-rw-r--r-- | WireGuard/WireGuard/Tunnel/TunnelsManager.swift | 79 |
3 files changed, 105 insertions, 69 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj index 7bb7d0a..be93450 100644 --- a/WireGuard/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 6F7774EA217229DB006A79B3 /* IPAddressRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E9217229DB006A79B3 /* IPAddressRange.swift */; }; 6F7774EF21722D97006A79B3 /* TunnelsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */; }; 6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */; }; + 6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */; }; 6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */; }; 6F919ED9218C65C50023B400 /* wireguard_doc_logo_22x29.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */; }; 6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */; }; @@ -139,6 +140,7 @@ 6F7774E9217229DB006A79B3 /* IPAddressRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPAddressRange.swift; sourceTree = "<group>"; }; 6F7774EE21722D97006A79B3 /* TunnelsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelsManager.swift; sourceTree = "<group>"; }; 6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditTableViewController.swift; sourceTree = "<group>"; }; + 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelErrors.swift; sourceTree = "<group>"; }; 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; }; 6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_22x29.png; sourceTree = "<group>"; }; 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_44x58.png; sourceTree = "<group>"; }; @@ -303,6 +305,7 @@ 5F4541A821C451D100994C13 /* TunnelStatus.swift */, 6FB1017821C57DE600766195 /* MockTunnels.swift */, 5F4541AD21C7704300994C13 /* NEVPNStatus+CustomStringConvertible.swift */, + 6F7F7E5E21C7D74B00527607 /* TunnelErrors.swift */, ); path = Tunnel; sourceTree = "<group>"; @@ -670,6 +673,7 @@ 6F6899A62180447E0012E523 /* x25519.c in Sources */, 6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */, 6FDEF80021863C0100D8FBF6 /* ioapi.c in Sources */, + 6F7F7E5F21C7D74B00527607 /* TunnelErrors.swift in Sources */, 6FDEF7FC21863B6100D8FBF6 /* zip.c in Sources */, 6F628C3F217F3413003482A3 /* DNSServer.swift in Sources */, 6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */, diff --git a/WireGuard/WireGuard/Tunnel/TunnelErrors.swift b/WireGuard/WireGuard/Tunnel/TunnelErrors.swift new file mode 100644 index 0000000..889f0a7 --- /dev/null +++ b/WireGuard/WireGuard/Tunnel/TunnelErrors.swift @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2018 WireGuard LLC. All Rights Reserved. + +import NetworkExtension + +enum TunnelsManagerError: WireGuardAppError { + case tunnelNameEmpty + case tunnelAlreadyExistsWithThatName + case systemErrorOnListingTunnels(systemError: Error) + case systemErrorOnAddTunnel(systemError: Error) + case systemErrorOnModifyTunnel(systemError: Error) + case systemErrorOnRemoveTunnel(systemError: Error) + + var alertText: AlertText { + switch self { + case .tunnelNameEmpty: + return ("No name provided", "Cannot create tunnel with an empty name") + case .tunnelAlreadyExistsWithThatName: + return ("Name already exists", "A tunnel with that name already exists") + case .systemErrorOnListingTunnels(let systemError): + return ("Unable to list tunnels", systemError.UIString) + case .systemErrorOnAddTunnel(let systemError): + return ("Unable to create tunnel", systemError.UIString) + case .systemErrorOnModifyTunnel(let systemError): + return ("Unable to modify tunnel", systemError.UIString) + case .systemErrorOnRemoveTunnel(let systemError): + return ("Unable to remove tunnel", systemError.UIString) + } + } +} + +enum TunnelsManagerActivationAttemptError: WireGuardAppError { + case tunnelIsNotInactive + case anotherTunnelIsOperational(otherTunnelName: String) + case failedWhileStarting(systemError: Error) // startTunnel() throwed + case failedWhileSaving(systemError: Error) // save config after re-enabling throwed + case failedWhileLoading(systemError: Error) // reloading config throwed + case failedBecauseOfTooManyErrors(lastSystemError: Error) // recursion limit reached + + var alertText: AlertText { + switch self { + case .tunnelIsNotInactive: + return ("Activation failure", "The tunnel is already active or in the process of being activated") + case .anotherTunnelIsOperational(let otherTunnelName): + return ("Activation failure", "Please disconnect '\(otherTunnelName)' before enabling this tunnel.") + case .failedWhileStarting(let systemError), + .failedWhileSaving(let systemError), + .failedWhileLoading(let systemError), + .failedBecauseOfTooManyErrors(let systemError): + return ("Activation failure", "The tunnel could not be activated. " + systemError.UIString) + } + } +} + +enum TunnelsManagerActivationError: WireGuardAppError { + case activationFailed + case activationFailedWithExtensionError(title: String, message: String) + var alertText: AlertText { + switch self { + case .activationFailed: + return ("Activation failure", "The tunnel could not be activated. Please ensure that you are connected to the Internet.") + case .activationFailedWithExtensionError(let title, let message): + return (title, message) + } + } +} + +extension Error { + var UIString: String { + if let systemError = self as? NEVPNError { + switch systemError { + case NEVPNError.configurationInvalid: + return "The configuration is invalid" + case NEVPNError.configurationDisabled: + return "The configuration is disabled" + case NEVPNError.connectionFailed: + return "The connection failed" + case NEVPNError.configurationStale: + return "The configuration is stale" + case NEVPNError.configurationReadWriteFailed: + return "Reading or writing the configuration failed" + case NEVPNError.configurationUnknown: + return "Unknown system error" + default: + return "" + } + } else { + return localizedDescription + } + } +} diff --git a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift index 2785be4..10df606 100644 --- a/WireGuard/WireGuard/Tunnel/TunnelsManager.swift +++ b/WireGuard/WireGuard/Tunnel/TunnelsManager.swift @@ -19,65 +19,6 @@ protocol TunnelsManagerActivationDelegate: class { func tunnelActivationSucceeded(tunnel: TunnelContainer) // status changed to connected } -enum TunnelsManagerActivationAttemptError: WireGuardAppError { - case tunnelIsNotInactive - case anotherTunnelIsOperational(otherTunnelName: String) - case failedWhileStarting // startTunnel() throwed - case failedWhileSaving // save config after re-enabling throwed - case failedWhileLoading // reloading config throwed - case failedBecauseOfTooManyErrors // recursion limit reached - - var alertText: AlertText { - switch self { - case .tunnelIsNotInactive: - return ("Activation failure", "The tunnel is already active or in the process of being activated") - case .anotherTunnelIsOperational(let otherTunnelName): - return ("Activation failure", "Please disconnect '\(otherTunnelName)' before enabling this tunnel.") - case .failedWhileStarting, .failedWhileSaving, .failedWhileLoading, .failedBecauseOfTooManyErrors: - return ("Activation failure", "The tunnel could not be activated.") - } - } -} - -enum TunnelsManagerActivationError: WireGuardAppError { - case activationFailed - case activationFailedWithExtensionError(title: String, message: String) - var alertText: AlertText { - switch self { - case .activationFailed: - return ("Activation failure", "The tunnel could not be activated. Please ensure that you are connected to the Internet.") - case .activationFailedWithExtensionError(let title, let message): - return (title, message) - } - } -} - -enum TunnelsManagerError: WireGuardAppError { - case tunnelNameEmpty - case tunnelAlreadyExistsWithThatName - case systemErrorOnListingTunnels - case systemErrorOnAddTunnel - case systemErrorOnModifyTunnel - case systemErrorOnRemoveTunnel - - var alertText: AlertText { - switch self { - case .tunnelNameEmpty: - return ("No name provided", "Cannot create tunnel with an empty name") - case .tunnelAlreadyExistsWithThatName: - return ("Name already exists", "A tunnel with that name already exists") - case .systemErrorOnListingTunnels: - return ("Unable to list tunnels", "") - case .systemErrorOnAddTunnel: - return ("Unable to create tunnel", "") - case .systemErrorOnModifyTunnel: - return ("Unable to modify tunnel", "") - case .systemErrorOnRemoveTunnel: - return ("Unable to remove tunnel", "") - } - } -} - class TunnelsManager { private var tunnels: [TunnelContainer] weak var tunnelsListDelegate: TunnelsManagerListDelegate? @@ -96,7 +37,7 @@ class TunnelsManager { NETunnelProviderManager.loadAllFromPreferences { managers, error in if let error = error { wg_log(.error, message: "Failed to load tunnel provider managers: \(error)") - completionHandler(.failure(TunnelsManagerError.systemErrorOnListingTunnels)) + completionHandler(.failure(TunnelsManagerError.systemErrorOnListingTunnels(systemError: error))) return } completionHandler(.success(TunnelsManager(tunnelProviders: managers ?? []))) @@ -126,7 +67,7 @@ class TunnelsManager { tunnelProviderManager.saveToPreferences { [weak self] error in guard error == nil else { wg_log(.error, message: "Add: Saving configuration failed: \(error!)") - completionHandler(.failure(TunnelsManagerError.systemErrorOnAddTunnel)) + completionHandler(.failure(TunnelsManagerError.systemErrorOnAddTunnel(systemError: error!))) return } @@ -183,7 +124,7 @@ class TunnelsManager { tunnelProviderManager.saveToPreferences { [weak self] error in guard error == nil else { wg_log(.error, message: "Modify: Saving configuration failed: \(error!)") - completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel) + completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel(systemError: error!)) return } guard let self = self else { return } @@ -209,7 +150,7 @@ class TunnelsManager { tunnel.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled guard error == nil else { wg_log(.error, message: "Modify: Re-loading after saving configuration failed: \(error!)") - completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel) + completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel(systemError: error!)) return } completionHandler(nil) @@ -226,7 +167,7 @@ class TunnelsManager { tunnelProviderManager.removeFromPreferences { [weak self] error in guard error == nil else { wg_log(.error, message: "Remove: Saving configuration failed: \(error!)") - completionHandler(TunnelsManagerError.systemErrorOnRemoveTunnel) + completionHandler(TunnelsManagerError.systemErrorOnRemoveTunnel(systemError: error!)) return } if let self = self { @@ -415,7 +356,7 @@ class TunnelContainer: NSObject { fileprivate func startActivation(recursionCount: UInt = 0, lastError: Error? = nil, activationDelegate: TunnelsManagerActivationDelegate?) { if recursionCount >= 8 { wg_log(.error, message: "startActivation: Failed after 8 attempts. Giving up with \(lastError!)") - activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedBecauseOfTooManyErrors) + activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedBecauseOfTooManyErrors(lastSystemError: lastError!)) return } @@ -432,7 +373,7 @@ class TunnelContainer: NSObject { guard let self = self else { return } if error != nil { wg_log(.error, message: "Error saving tunnel after re-enabling: \(error!)") - activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileSaving) + activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileSaving(systemError: error!)) return } wg_log(.debug, staticMessage: "startActivation: Tunnel saved after re-enabling") @@ -456,13 +397,13 @@ class TunnelContainer: NSObject { guard let systemError = error as? NEVPNError else { wg_log(.error, message: "Failed to activate tunnel: Error: \(error)") status = .inactive - activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileStarting) + activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileStarting(systemError: error)) return } guard systemError.code == NEVPNError.configurationInvalid || systemError.code == NEVPNError.configurationStale else { wg_log(.error, message: "Failed to activate tunnel: VPN Error: \(error)") status = .inactive - activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileStarting) + activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileStarting(systemError: systemError)) return } wg_log(.debug, staticMessage: "startActivation: Will reload tunnel and then try to start it.") @@ -471,7 +412,7 @@ class TunnelContainer: NSObject { if error != nil { wg_log(.error, message: "startActivation: Error reloading tunnel: \(error!)") self.status = .inactive - activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileLoading) + activationDelegate?.tunnelActivationAttemptFailed(tunnel: self, error: .failedWhileLoading(systemError: systemError)) return } wg_log(.debug, staticMessage: "startActivation: Tunnel reloaded") |