aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2018-12-17 18:56:26 +0530
committerRoopesh Chander <roop@roopc.net>2018-12-17 19:04:17 +0530
commit2582ddd6f665c930e21f0a064da4f50d35b25aa9 (patch)
tree92bbc0b056cd70ebe81051946842e6644f3449bc
parentVersion bump (diff)
downloadwireguard-apple-2582ddd6f665c930e21f0a064da4f50d35b25aa9.tar.xz
wireguard-apple-2582ddd6f665c930e21f0a064da4f50d35b25aa9.zip
Error handling: Add info on the underlying system error to error alerts
Signed-off-by: Roopesh Chander <roop@roopc.net>
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/Tunnel/TunnelErrors.swift91
-rw-r--r--WireGuard/WireGuard/Tunnel/TunnelsManager.swift79
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")