Tons more swiftlint warnings fixed. Still a few remaining.

This commit is contained in:
Eric Kuck 2018-12-12 12:28:27 -06:00
parent fa558a4019
commit ea29a0c7d1
21 changed files with 222 additions and 237 deletions

View File

@ -17,15 +17,15 @@ extension Endpoint {
init?(from string: String) {
// Separation of host and port is based on 'parse_endpoint' function in
// https://git.zx2c4.com/WireGuard/tree/src/tools/config.c
guard (!string.isEmpty) else { return nil }
guard !string.isEmpty else { return nil }
let startOfPort: String.Index
let hostString: String
if (string.first! == "[") {
if string.first! == "[" {
// Look for IPv6-style endpoint, like [::1]:80
let startOfHost = string.index(after: string.startIndex)
guard let endOfHost = string.dropFirst().firstIndex(of: "]") else { return nil }
let afterEndOfHost = string.index(after: endOfHost)
guard (string[afterEndOfHost] == ":") else { return nil }
guard string[afterEndOfHost] == ":" else { return nil }
startOfPort = string.index(after: afterEndOfHost)
hostString = String(string[startOfHost ..< endOfHost])
} else {
@ -38,12 +38,12 @@ extension Endpoint {
let invalidCharacterIndex = hostString.unicodeScalars.firstIndex { char in
return !CharacterSet.urlHostAllowed.contains(char)
}
guard (invalidCharacterIndex == nil) else { return nil }
guard invalidCharacterIndex == nil else { return nil }
host = NWEndpoint.Host(hostString)
port = endpointPort
}
func stringRepresentation() -> String {
switch (host) {
switch host {
case .name(let hostname, _):
return "\(hostname):\(port)"
case .ipv4(let address):
@ -78,7 +78,7 @@ extension Endpoint: Codable {
extension Endpoint {
func hasHostAsIPAddress() -> Bool {
switch (host) {
switch host {
case .name:
return false
case .ipv4:
@ -89,7 +89,7 @@ extension Endpoint {
}
func hostname() -> String? {
switch (host) {
switch host {
case .name(let hostname, _):
return hostname
case .ipv4:

View File

@ -122,29 +122,29 @@ class WgQuickConfigFileParser {
attributes[key] = value
}
} else {
if (lowercasedLine != "[interface]" && lowercasedLine != "[peer]") {
if lowercasedLine != "[interface]" && lowercasedLine != "[peer]" {
throw ParseError.invalidLine(line)
}
}
let isLastLine: Bool = (lineIndex == lines.count - 1)
if (isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]") {
if isLastLine || lowercasedLine == "[interface]" || lowercasedLine == "[peer]" {
// Previous section has ended; process the attributes collected so far
if (parserState == .inInterfaceSection) {
if parserState == .inInterfaceSection {
guard let interface = collate(interfaceAttributes: attributes) else { throw ParseError.invalidInterface }
guard (interfaceConfiguration == nil) else { throw ParseError.multipleInterfaces }
guard interfaceConfiguration == nil else { throw ParseError.multipleInterfaces }
interfaceConfiguration = interface
} else if (parserState == .inPeerSection) {
} else if parserState == .inPeerSection {
guard let peer = collate(peerAttributes: attributes) else { throw ParseError.invalidPeer }
peerConfigurations.append(peer)
}
}
if (lowercasedLine == "[interface]") {
if lowercasedLine == "[interface]" {
parserState = .inInterfaceSection
attributes.removeAll()
} else if (lowercasedLine == "[peer]") {
} else if lowercasedLine == "[peer]" {
parserState = .inPeerSection
attributes.removeAll()
}
@ -152,7 +152,7 @@ class WgQuickConfigFileParser {
let peerPublicKeysArray = peerConfigurations.map { $0.publicKey }
let peerPublicKeysSet = Set<Data>(peerPublicKeysArray)
if (peerPublicKeysArray.count != peerPublicKeysSet.count) {
if peerPublicKeysArray.count != peerPublicKeysSet.count {
throw ParseError.multiplePeersWithSamePublicKey
}

View File

@ -4,18 +4,18 @@
import UIKit
class WgQuickConfigFileWriter {
static func writeConfigFile(from tc: TunnelConfiguration) -> Data? {
let interface = tc.interface
static func writeConfigFile(from configuration: TunnelConfiguration) -> Data? {
let interface = configuration.interface
var output = "[Interface]\n"
output.append("PrivateKey = \(interface.privateKey.base64EncodedString())\n")
if let listenPort = interface.listenPort {
output.append("ListenPort = \(listenPort)\n")
}
if (!interface.addresses.isEmpty) {
if !interface.addresses.isEmpty {
let addressString = interface.addresses.map { $0.stringRepresentation() }.joined(separator: ", ")
output.append("Address = \(addressString)\n")
}
if (!interface.dns.isEmpty) {
if !interface.dns.isEmpty {
let dnsString = interface.dns.map { $0.stringRepresentation() }.joined(separator: ", ")
output.append("DNS = \(dnsString)\n")
}
@ -23,13 +23,13 @@ class WgQuickConfigFileWriter {
output.append("MTU = \(mtu)\n")
}
for peer in tc.peers {
for peer in configuration.peers {
output.append("\n[Peer]\n")
output.append("PublicKey = \(peer.publicKey.base64EncodedString())\n")
if let preSharedKey = peer.preSharedKey {
output.append("PresharedKey = \(preSharedKey.base64EncodedString())\n")
}
if (!peer.allowedIPs.isEmpty) {
if !peer.allowedIPs.isEmpty {
let allowedIPsString = peer.allowedIPs.map { $0.stringRepresentation() }.joined(separator: ", ")
output.append("AllowedIPs = \(allowedIPsString)\n")
}

View File

@ -43,7 +43,7 @@ class TunnelViewModel {
subscript(field: InterfaceField) -> String {
get {
if (scratchpad.isEmpty) {
if scratchpad.isEmpty {
// When starting to read a config, setup the scratchpad.
// The scratchpad shall serve as a cache of what we want to show in the UI.
populateScratchpad()
@ -51,18 +51,18 @@ class TunnelViewModel {
return scratchpad[field] ?? ""
}
set(stringValue) {
if (scratchpad.isEmpty) {
if scratchpad.isEmpty {
// When starting to edit a config, setup the scratchpad and remove the configuration.
// The scratchpad shall be the sole source of the being-edited configuration.
populateScratchpad()
}
validatedConfiguration = nil
if (stringValue.isEmpty) {
if stringValue.isEmpty {
scratchpad.removeValue(forKey: field)
} else {
scratchpad[field] = stringValue
}
if (field == .privateKey) {
if field == .privateKey {
if (stringValue.count == TunnelViewModel.keyLengthInBase64),
let privateKey = Data(base64Encoded: stringValue),
privateKey.count == TunnelConfiguration.keyLength {
@ -81,7 +81,7 @@ class TunnelViewModel {
scratchpad[.name] = config.name
scratchpad[.privateKey] = config.privateKey.base64EncodedString()
scratchpad[.publicKey] = config.publicKey.base64EncodedString()
if (!config.addresses.isEmpty) {
if !config.addresses.isEmpty {
scratchpad[.addresses] = config.addresses.map { $0.stringRepresentation() }.joined(separator: ", ")
}
if let listenPort = config.listenPort {
@ -90,7 +90,7 @@ class TunnelViewModel {
if let mtu = config.mtu {
scratchpad[.mtu] = String(mtu)
}
if (!config.dns.isEmpty) {
if !config.dns.isEmpty {
scratchpad[.dns] = config.dns.map { $0.stringRepresentation() }.joined(separator: ", ")
}
}
@ -158,16 +158,15 @@ class TunnelViewModel {
config.dns = dnsServers
}
guard (errorMessages.isEmpty) else {
return .error(errorMessages.first!)
}
guard errorMessages.isEmpty else { return .error(errorMessages.first!) }
validatedConfiguration = config
return .saved(config)
}
func filterFieldsWithValueOrControl(interfaceFields: [InterfaceField]) -> [InterfaceField] {
return interfaceFields.filter { (field) -> Bool in
if (TunnelViewModel.interfaceFieldsWithControl.contains(field)) {
if TunnelViewModel.interfaceFieldsWithControl.contains(field) {
return true
}
return (!self[field].isEmpty)
@ -193,7 +192,7 @@ class TunnelViewModel {
subscript(field: PeerField) -> String {
get {
if (scratchpad.isEmpty) {
if scratchpad.isEmpty {
// When starting to read a config, setup the scratchpad.
// The scratchpad shall serve as a cache of what we want to show in the UI.
populateScratchpad()
@ -201,18 +200,18 @@ class TunnelViewModel {
return scratchpad[field] ?? ""
}
set(stringValue) {
if (scratchpad.isEmpty) {
if scratchpad.isEmpty {
// When starting to edit a config, setup the scratchpad and remove the configuration.
// The scratchpad shall be the sole source of the being-edited configuration.
populateScratchpad()
}
validatedConfiguration = nil
if (stringValue.isEmpty) {
if stringValue.isEmpty {
scratchpad.removeValue(forKey: field)
} else {
scratchpad[field] = stringValue
}
if (field == .allowedIPs) {
if field == .allowedIPs {
updateExcludePrivateIPsFieldState()
}
}
@ -225,7 +224,7 @@ class TunnelViewModel {
if let preSharedKey = config.preSharedKey {
scratchpad[.preSharedKey] = preSharedKey.base64EncodedString()
}
if (!config.allowedIPs.isEmpty) {
if !config.allowedIPs.isEmpty {
scratchpad[.allowedIPs] = config.allowedIPs.map { $0.stringRepresentation() }.joined(separator: ", ")
}
if let endpoint = config.endpoint {
@ -291,16 +290,15 @@ class TunnelViewModel {
}
}
guard (errorMessages.isEmpty) else {
return .error(errorMessages.first!)
}
guard errorMessages.isEmpty else { return .error(errorMessages.first!) }
validatedConfiguration = config
return .saved(config)
}
func filterFieldsWithValueOrControl(peerFields: [PeerField]) -> [PeerField] {
return peerFields.filter { (field) -> Bool in
if (TunnelViewModel.peerFieldsWithControl.contains(field)) {
if TunnelViewModel.peerFieldsWithControl.contains(field) {
return true
}
return (!self[field].isEmpty)
@ -319,12 +317,12 @@ class TunnelViewModel {
]
func updateExcludePrivateIPsFieldState() {
guard (numberOfPeers == 1) else {
guard numberOfPeers == 1 else {
shouldAllowExcludePrivateIPsControl = false
excludePrivateIPsValue = false
return
}
if (scratchpad.isEmpty) {
if scratchpad.isEmpty {
populateScratchpad()
}
let allowedIPStrings = Set<String>(
@ -332,10 +330,10 @@ class TunnelViewModel {
.split(separator: ",")
.map { $0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) }
)
if (allowedIPStrings.contains(TunnelViewModel.PeerData.ipv4DefaultRouteString)) {
if allowedIPStrings.contains(TunnelViewModel.PeerData.ipv4DefaultRouteString) {
shouldAllowExcludePrivateIPsControl = true
excludePrivateIPsValue = false
} else if (allowedIPStrings.isSuperset(of: TunnelViewModel.PeerData.ipv4DefaultRouteModRFC1918String)) {
} else if allowedIPStrings.isSuperset(of: TunnelViewModel.PeerData.ipv4DefaultRouteModRFC1918String) {
shouldAllowExcludePrivateIPsControl = true
excludePrivateIPsValue = true
} else {
@ -353,7 +351,7 @@ class TunnelViewModel {
.map { $0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) }
let ipv6Addresses = allowedIPStrings.filter { $0.contains(":") }
let modifiedAllowedIPStrings: [String]
if (isOn) {
if isOn {
modifiedAllowedIPStrings = ipv6Addresses +
TunnelViewModel.PeerData.ipv4DefaultRouteModRFC1918String + dnsServerStrings
} else {
@ -421,14 +419,14 @@ class TunnelViewModel {
let interfaceSaveResult = interfaceData.save()
let peerSaveResults = peersData.map { $0.save() }
// Collate the results
switch (interfaceSaveResult) {
switch interfaceSaveResult {
case .error(let errorMessage):
return .error(errorMessage)
case .saved(let interfaceConfiguration):
var peerConfigurations: [PeerConfiguration] = []
peerConfigurations.reserveCapacity(peerSaveResults.count)
for peerSaveResult in peerSaveResults {
switch (peerSaveResult) {
switch peerSaveResult {
case .error(let errorMessage):
return .error(errorMessage)
case .saved(let peerConfiguration):
@ -438,7 +436,7 @@ class TunnelViewModel {
let peerPublicKeysArray = peerConfigurations.map { $0.publicKey }
let peerPublicKeysSet = Set<Data>(peerPublicKeysArray)
if (peerPublicKeysArray.count != peerPublicKeysSet.count) {
if peerPublicKeysArray.count != peerPublicKeysSet.count {
return .error("Two or more peers cannot have the same public key")
}
@ -452,7 +450,7 @@ class TunnelViewModel {
extension TunnelViewModel {
static func activateOnDemandOptionText(for activateOnDemandOption: ActivateOnDemandOption) -> String {
switch (activateOnDemandOption) {
switch activateOnDemandOption {
case .none:
return "Off"
case .useOnDemandOverWiFiOrCellular:
@ -466,7 +464,7 @@ extension TunnelViewModel {
static func activateOnDemandDetailText(for activateOnDemandSetting: ActivateOnDemandSetting?) -> String {
if let activateOnDemandSetting = activateOnDemandSetting {
if (activateOnDemandSetting.isActivateOnDemandEnabled) {
if activateOnDemandSetting.isActivateOnDemandEnabled {
return TunnelViewModel.activateOnDemandOptionText(for: activateOnDemandSetting.activateOnDemandOption)
} else {
return TunnelViewModel.activateOnDemandOptionText(for: .none)

View File

@ -53,7 +53,7 @@ extension AppDelegate {
viewControllerWithRestorationIdentifierPath identifierComponents: [String],
coder: NSCoder) -> UIViewController? {
guard let vcIdentifier = identifierComponents.last else { return nil }
if (vcIdentifier.hasPrefix("TunnelDetailVC:")) {
if vcIdentifier.hasPrefix("TunnelDetailVC:") {
let tunnelName = String(vcIdentifier.suffix(vcIdentifier.count - "TunnelDetailVC:".count))
if let tunnelsManager = mainVC?.tunnelsManager {
if let tunnel = tunnelsManager.tunnel(named: tunnelName) {

View File

@ -81,7 +81,7 @@ extension MainViewController {
let tunnelDetailNC = UINavigationController(rootViewController: tunnelDetailVC)
tunnelDetailNC.restorationIdentifier = "DetailNC"
if let self = self {
if (animated) {
if animated {
self.showDetailViewController(tunnelDetailNC, sender: self)
} else {
UIView.performWithoutAnimation {

View File

@ -40,8 +40,8 @@ class SettingsTableViewController: UITableViewController {
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.allowsSelection = false
self.tableView.register(TunnelSettingsTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelSettingsTableViewKeyValueCell.id)
self.tableView.register(TunnelSettingsTableViewButtonCell.self, forCellReuseIdentifier: TunnelSettingsTableViewButtonCell.id)
self.tableView.register(TunnelSettingsTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelSettingsTableViewKeyValueCell.reuseIdentifier)
self.tableView.register(TunnelSettingsTableViewButtonCell.self, forCellReuseIdentifier: TunnelSettingsTableViewButtonCell.reuseIdentifier)
let logo = UIImageView(image: UIImage(named: "wireguard.pdf", in: Bundle.main, compatibleWith: nil)!)
logo.contentMode = .scaleAspectFit
@ -99,9 +99,9 @@ class SettingsTableViewController: UITableViewController {
DispatchQueue.global(qos: .userInitiated).async {
if (FileManager.default.fileExists(atPath: destinationURL.path)) {
if FileManager.default.fileExists(atPath: destinationURL.path) {
let isDeleted = FileManager.deleteFile(at: destinationURL)
if (!isDeleted) {
if !isDeleted {
ErrorPresenter.showErrorAlert(title: "No log available", message: "The pre-existing log could not be cleared", from: self)
return
}
@ -149,7 +149,7 @@ extension SettingsTableViewController {
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch (section) {
switch section {
case 0:
return "About"
case 1:
@ -163,21 +163,21 @@ extension SettingsTableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let field = settingsFieldsBySection[indexPath.section][indexPath.row]
if (field == .iosAppVersion || field == .goBackendVersion) {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewKeyValueCell.id, for: indexPath) as! TunnelSettingsTableViewKeyValueCell
if field == .iosAppVersion || field == .goBackendVersion {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewKeyValueCell.reuseIdentifier, for: indexPath) as! TunnelSettingsTableViewKeyValueCell
cell.key = field.rawValue
if (field == .iosAppVersion) {
if field == .iosAppVersion {
var appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown version"
if let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
appVersion += " (\(appBuild))"
}
cell.value = appVersion
} else if (field == .goBackendVersion) {
} else if field == .goBackendVersion {
cell.value = WIREGUARD_GO_VERSION
}
return cell
} else if (field == .exportZipArchive) {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewButtonCell.id, for: indexPath) as! TunnelSettingsTableViewButtonCell
} else if field == .exportZipArchive {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewButtonCell.reuseIdentifier, for: indexPath) as! TunnelSettingsTableViewButtonCell
cell.buttonText = field.rawValue
cell.onTapped = { [weak self] in
self?.exportConfigurationsAsZipFile(sourceView: cell.button)
@ -185,7 +185,7 @@ extension SettingsTableViewController {
return cell
} else {
assert(field == .exportLogFile)
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewButtonCell.id, for: indexPath) as! TunnelSettingsTableViewButtonCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelSettingsTableViewButtonCell.reuseIdentifier, for: indexPath) as! TunnelSettingsTableViewButtonCell
cell.buttonText = field.rawValue
cell.onTapped = { [weak self] in
self?.exportLogForLastActivatedTunnel(sourceView: cell.button)
@ -196,7 +196,7 @@ extension SettingsTableViewController {
}
class TunnelSettingsTableViewKeyValueCell: UITableViewCell {
static let id: String = "TunnelSettingsTableViewKeyValueCell"
static let reuseIdentifier = "TunnelSettingsTableViewKeyValueCell"
var key: String {
get { return textLabel?.text ?? "" }
set(value) { textLabel?.text = value }
@ -207,7 +207,7 @@ class TunnelSettingsTableViewKeyValueCell: UITableViewCell {
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .value1, reuseIdentifier: TunnelSettingsTableViewKeyValueCell.id)
super.init(style: .value1, reuseIdentifier: TunnelSettingsTableViewKeyValueCell.reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
@ -222,7 +222,7 @@ class TunnelSettingsTableViewKeyValueCell: UITableViewCell {
}
class TunnelSettingsTableViewButtonCell: UITableViewCell {
static let id: String = "TunnelSettingsTableViewButtonCell"
static let reuseIdentifier = "TunnelSettingsTableViewButtonCell"
var buttonText: String {
get { return button.title(for: .normal) ?? "" }
set(value) { button.setTitle(value, for: .normal) }

View File

@ -40,10 +40,10 @@ class TunnelDetailTableViewController: UITableViewController {
self.tableView.estimatedRowHeight = 44
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.allowsSelection = false
self.tableView.register(TunnelDetailTableViewStatusCell.self, forCellReuseIdentifier: TunnelDetailTableViewStatusCell.id)
self.tableView.register(TunnelDetailTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelDetailTableViewKeyValueCell.id)
self.tableView.register(TunnelDetailTableViewButtonCell.self, forCellReuseIdentifier: TunnelDetailTableViewButtonCell.id)
self.tableView.register(TunnelDetailTableViewActivateOnDemandCell.self, forCellReuseIdentifier: TunnelDetailTableViewActivateOnDemandCell.id)
self.tableView.register(TunnelDetailTableViewStatusCell.self, forCellReuseIdentifier: TunnelDetailTableViewStatusCell.reuseIdentifier)
self.tableView.register(TunnelDetailTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelDetailTableViewKeyValueCell.reuseIdentifier)
self.tableView.register(TunnelDetailTableViewButtonCell.self, forCellReuseIdentifier: TunnelDetailTableViewButtonCell.reuseIdentifier)
self.tableView.register(TunnelDetailTableViewActivateOnDemandCell.self, forCellReuseIdentifier: TunnelDetailTableViewActivateOnDemandCell.reuseIdentifier)
// State restoration
self.restorationIdentifier = "TunnelDetailVC:\(tunnel.name)"
@ -99,17 +99,17 @@ extension TunnelDetailTableViewController {
let interfaceData = tunnelViewModel.interfaceData
let numberOfPeerSections = tunnelViewModel.peersData.count
if (section == 0) {
if section == 0 {
// Status
return 1
} else if (section == 1) {
} else if section == 1 {
// Interface
return interfaceData.filterFieldsWithValueOrControl(interfaceFields: interfaceFields).count
} else if ((numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections))) {
} else if (numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections)) {
// Peer
let peerData = tunnelViewModel.peersData[section - 2]
return peerData.filterFieldsWithValueOrControl(peerFields: peerFields).count
} else if (section < (3 + numberOfPeerSections)) {
} else if section < (3 + numberOfPeerSections) {
// Activate on demand
return 1
} else {
@ -122,16 +122,16 @@ extension TunnelDetailTableViewController {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let numberOfPeerSections = tunnelViewModel.peersData.count
if (section == 0) {
if section == 0 {
// Status
return "Status"
} else if (section == 1) {
} else if section == 1 {
// Interface
return "Interface"
} else if ((numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections))) {
} else if (numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections)) {
// Peer
return "Peer"
} else if (section < (3 + numberOfPeerSections)) {
} else if section < (3 + numberOfPeerSections) {
// On-Demand Activation
return "On-Demand Activation"
} else {
@ -147,13 +147,13 @@ extension TunnelDetailTableViewController {
let section = indexPath.section
let row = indexPath.row
if (section == 0) {
if section == 0 {
// Status
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewStatusCell.id, for: indexPath) as! TunnelDetailTableViewStatusCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewStatusCell.reuseIdentifier, for: indexPath) as! TunnelDetailTableViewStatusCell
cell.tunnel = self.tunnel
cell.onSwitchToggled = { [weak self] isOn in
guard let self = self else { return }
if (isOn) {
if isOn {
self.tunnelsManager.startActivation(of: self.tunnel) { [weak self] error in
if let error = error {
ErrorPresenter.showErrorAlert(error: error, from: self, onPresented: {
@ -168,33 +168,33 @@ extension TunnelDetailTableViewController {
}
}
return cell
} else if (section == 1) {
} else if section == 1 {
// Interface
let field = interfaceData.filterFieldsWithValueOrControl(interfaceFields: interfaceFields)[row]
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.id, for: indexPath) as! TunnelDetailTableViewKeyValueCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.reuseIdentifier, for: indexPath) as! TunnelDetailTableViewKeyValueCell
// Set key and value
cell.key = field.rawValue
cell.value = interfaceData[field]
return cell
} else if ((numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections))) {
} else if (numberOfPeerSections > 0) && (section < (2 + numberOfPeerSections)) {
// Peer
let peerData = tunnelViewModel.peersData[section - 2]
let field = peerData.filterFieldsWithValueOrControl(peerFields: peerFields)[row]
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.id, for: indexPath) as! TunnelDetailTableViewKeyValueCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.reuseIdentifier, for: indexPath) as! TunnelDetailTableViewKeyValueCell
// Set key and value
cell.key = field.rawValue
cell.value = peerData[field]
return cell
} else if (section < (3 + numberOfPeerSections)) {
} else if section < (3 + numberOfPeerSections) {
// On-Demand Activation
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewActivateOnDemandCell.id, for: indexPath) as! TunnelDetailTableViewActivateOnDemandCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewActivateOnDemandCell.reuseIdentifier, for: indexPath) as! TunnelDetailTableViewActivateOnDemandCell
cell.tunnel = self.tunnel
return cell
} else {
assert(section == (3 + numberOfPeerSections))
// Delete configuration
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewButtonCell.id, for: indexPath) as! TunnelDetailTableViewButtonCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewButtonCell.reuseIdentifier, for: indexPath) as! TunnelDetailTableViewButtonCell
cell.buttonText = "Delete tunnel"
cell.hasDestructiveAction = true
cell.onTapped = { [weak self] in
@ -202,7 +202,7 @@ extension TunnelDetailTableViewController {
self.showConfirmationAlert(message: "Delete this tunnel?", buttonTitle: "Delete", from: cell) { [weak self] in
guard let tunnelsManager = self?.tunnelsManager, let tunnel = self?.tunnel else { return }
tunnelsManager.remove(tunnel: tunnel) { (error) in
if (error != nil) {
if error != nil {
print("Error removing tunnel: \(String(describing: error))")
return
}
@ -216,7 +216,7 @@ extension TunnelDetailTableViewController {
}
class TunnelDetailTableViewStatusCell: UITableViewCell {
static let id: String = "TunnelDetailTableViewStatusCell"
static let reuseIdentifier = "TunnelDetailTableViewStatusCell"
var tunnel: TunnelContainer? {
didSet(value) {
@ -238,14 +238,14 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
statusSwitch = UISwitch()
super.init(style: .default, reuseIdentifier: TunnelDetailTableViewKeyValueCell.id)
super.init(style: .default, reuseIdentifier: TunnelDetailTableViewKeyValueCell.reuseIdentifier)
accessoryView = statusSwitch
statusSwitch.addTarget(self, action: #selector(switchToggled), for: .valueChanged)
}
@objc func switchToggled() {
if (isOnSwitchToggledHandlerEnabled) {
if isOnSwitchToggledHandlerEnabled {
onSwitchToggled?(statusSwitch.isOn)
}
}
@ -256,7 +256,7 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
return
}
let text: String
switch (status) {
switch status {
case .inactive:
text = "Inactive"
case .activating:
@ -297,7 +297,7 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
}
class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
static let id: String = "TunnelDetailTableViewKeyValueCell"
static let reuseIdentifier = "TunnelDetailTableViewKeyValueCell"
var key: String {
get { return keyLabel.text ?? "" }
set(value) { keyLabel.text = value }
@ -357,9 +357,9 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
func configureForContentSize() {
var constraints: [NSLayoutConstraint] = []
if (self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory) {
if self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
// Stack vertically
if (!isStackedVertically) {
if !isStackedVertically {
constraints = [
valueLabel.topAnchor.constraint(equalToSystemSpacingBelow: keyLabel.bottomAnchor, multiplier: 0.5),
valueLabel.leftAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leftAnchor),
@ -370,7 +370,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
}
} else {
// Stack horizontally
if (!isStackedHorizontally) {
if !isStackedHorizontally {
constraints = [
contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: keyLabel.bottomAnchor, multiplier: 0.5),
valueLabel.leftAnchor.constraint(equalToSystemSpacingAfter: keyLabel.rightAnchor, multiplier: 1),
@ -380,7 +380,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
isStackedVertically = false
}
}
if (!constraints.isEmpty) {
if !constraints.isEmpty {
NSLayoutConstraint.deactivate(self.contentSizeBasedConstraints)
NSLayoutConstraint.activate(constraints)
self.contentSizeBasedConstraints = constraints
@ -400,7 +400,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
}
class TunnelDetailTableViewButtonCell: UITableViewCell {
static let id: String = "TunnelDetailTableViewButtonCell"
static let reuseIdentifier = "TunnelDetailTableViewButtonCell"
var buttonText: String {
get { return button.title(for: .normal) ?? "" }
set(value) { button.setTitle(value, for: .normal) }
@ -447,7 +447,7 @@ class TunnelDetailTableViewButtonCell: UITableViewCell {
}
class TunnelDetailTableViewActivateOnDemandCell: UITableViewCell {
static let id: String = "TunnelDetailTableViewActivateOnDemandCell"
static let reuseIdentifier = "TunnelDetailTableViewActivateOnDemandCell"
var tunnel: TunnelContainer? {
didSet(value) {

View File

@ -82,7 +82,7 @@ class TunnelEditTableViewController: UITableViewController {
@objc func saveTapped() {
self.tableView.endEditing(false)
let tunnelSaveResult = tunnelViewModel.save()
switch (tunnelSaveResult) {
switch tunnelSaveResult {
case .error(let errorMessage):
let erroringConfiguration = (tunnelViewModel.interfaceData.validatedConfiguration == nil) ? "Interface" : "Peer"
ErrorPresenter.showErrorAlert(title: "Invalid \(erroringConfiguration)", message: errorMessage, from: self)
@ -130,21 +130,21 @@ extension TunnelEditTableViewController {
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (section < interfaceSectionCount) {
if section < interfaceSectionCount {
// Interface
return interfaceFieldsBySection[section].count
} else if ((peerSectionCount > 0) && (section < (interfaceSectionCount + peerSectionCount))) {
} else if (peerSectionCount > 0) && (section < (interfaceSectionCount + peerSectionCount)) {
// Peer
let peerIndex = (section - interfaceSectionCount)
let peerData = tunnelViewModel.peersData[peerIndex]
let peerFieldsToShow = peerData.shouldAllowExcludePrivateIPsControl ? peerFields : peerFields.filter { $0 != .excludePrivateIPs }
return peerFieldsToShow.count
} else if (section < (interfaceSectionCount + peerSectionCount + 1)) {
} else if section < (interfaceSectionCount + peerSectionCount + 1) {
// Add peer
return 1
} else {
// On-Demand Rules
if (activateOnDemandSetting.isActivateOnDemandEnabled) {
if activateOnDemandSetting.isActivateOnDemandEnabled {
return 4
} else {
return 1
@ -153,13 +153,13 @@ extension TunnelEditTableViewController {
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if (section < interfaceSectionCount) {
if section < interfaceSectionCount {
// Interface
return (section == 0) ? "Interface" : nil
} else if ((peerSectionCount > 0) && (section < (interfaceSectionCount + peerSectionCount))) {
} else if (peerSectionCount > 0) && (section < (interfaceSectionCount + peerSectionCount)) {
// Peer
return "Peer"
} else if (section == (interfaceSectionCount + peerSectionCount)) {
} else if section == (interfaceSectionCount + peerSectionCount) {
// Add peer
return nil
} else {
@ -169,11 +169,11 @@ extension TunnelEditTableViewController {
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if (indexPath.section < interfaceSectionCount) {
if indexPath.section < interfaceSectionCount {
return interfaceFieldCell(for: tableView, at: indexPath)
} else if ((peerSectionCount > 0) && (indexPath.section < (interfaceSectionCount + peerSectionCount))) {
} else if (peerSectionCount > 0) && (indexPath.section < (interfaceSectionCount + peerSectionCount)) {
return peerCell(for: tableView, at: indexPath)
} else if (indexPath.section == (interfaceSectionCount + peerSectionCount)) {
} else if indexPath.section == (interfaceSectionCount + peerSectionCount) {
return addPeerCell(for: tableView, at: indexPath)
} else {
return onDemandCell(for: tableView, at: indexPath)
@ -183,7 +183,7 @@ extension TunnelEditTableViewController {
private func interfaceFieldCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell {
let interfaceData = tunnelViewModel.interfaceData
let field = interfaceFieldsBySection[indexPath.section][indexPath.row]
if (field == .generateKeyPair) {
if field == .generateKeyPair {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelEditTableViewButtonCell.reuseIdentifier, for: indexPath) as! TunnelEditTableViewButtonCell
cell.buttonText = field.rawValue
cell.onTapped = { [weak self, weak interfaceData] in
@ -550,9 +550,9 @@ class TunnelEditTableViewKeyValueCell: UITableViewCell {
func configureForContentSize() {
var constraints: [NSLayoutConstraint] = []
if (self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory) {
if self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory {
// Stack vertically
if (!isStackedVertically) {
if !isStackedVertically {
constraints = [
valueTextField.topAnchor.constraint(equalToSystemSpacingBelow: keyLabel.bottomAnchor, multiplier: 0.5),
valueTextField.leftAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leftAnchor),
@ -563,7 +563,7 @@ class TunnelEditTableViewKeyValueCell: UITableViewCell {
}
} else {
// Stack horizontally
if (!isStackedHorizontally) {
if !isStackedHorizontally {
constraints = [
contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: keyLabel.bottomAnchor, multiplier: 0.5),
valueTextField.leftAnchor.constraint(equalToSystemSpacingAfter: keyLabel.rightAnchor, multiplier: 1),
@ -573,7 +573,7 @@ class TunnelEditTableViewKeyValueCell: UITableViewCell {
isStackedVertically = false
}
}
if (!constraints.isEmpty) {
if !constraints.isEmpty {
NSLayoutConstraint.deactivate(self.contentSizeBasedConstraints)
NSLayoutConstraint.activate(constraints)
self.contentSizeBasedConstraints = constraints
@ -604,7 +604,7 @@ extension TunnelEditTableViewKeyValueCell: UITextFieldDelegate {
}
func textFieldDidEndEditing(_ textField: UITextField) {
let isModified = (textField.text ?? "" != textFieldValueOnBeginEditing)
guard (isModified) else { return }
guard isModified else { return }
if let onValueChanged = onValueChanged {
onValueChanged(textField.text ?? "")
}

View File

@ -43,7 +43,7 @@ class TunnelsListTableViewController: UIViewController {
}
func setTunnelsManager(tunnelsManager: TunnelsManager) {
if (self.tunnelsManager != nil) {
if self.tunnelsManager != nil {
// If a tunnels manager is already set, do nothing
return
}
@ -54,7 +54,7 @@ class TunnelsListTableViewController: UIViewController {
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableView.automaticDimension
tableView.separatorStyle = .none
tableView.register(TunnelsListTableViewCell.self, forCellReuseIdentifier: TunnelsListTableViewCell.id)
tableView.register(TunnelsListTableViewCell.self, forCellReuseIdentifier: TunnelsListTableViewCell.reuseIdentifier)
self.view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
@ -103,7 +103,7 @@ class TunnelsListTableViewController: UIViewController {
}
@objc func addButtonTapped(sender: AnyObject) {
if (self.tunnelsManager == nil) { return } // Do nothing until we've loaded the tunnels
if self.tunnelsManager == nil { return } // Do nothing until we've loaded the tunnels
let alert = UIAlertController(title: "", message: "Add a new WireGuard tunnel", preferredStyle: .actionSheet)
let importFileAction = UIAlertAction(title: "Create from file or archive", style: .default) { [weak self] (_) in
self?.presentViewControllerForFileImport()
@ -136,7 +136,7 @@ class TunnelsListTableViewController: UIViewController {
}
@objc func settingsButtonTapped(sender: UIBarButtonItem!) {
if (self.tunnelsManager == nil) { return } // Do nothing until we've loaded the tunnels
if self.tunnelsManager == nil { return } // Do nothing until we've loaded the tunnels
let settingsVC = SettingsTableViewController(tunnelsManager: tunnelsManager)
let settingsNC = UINavigationController(rootViewController: settingsVC)
settingsNC.modalPresentationStyle = .formSheet
@ -167,7 +167,7 @@ class TunnelsListTableViewController: UIViewController {
func importFromFile(url: URL, completionHandler: (() -> Void)?) {
guard let tunnelsManager = tunnelsManager else { return }
if (url.pathExtension == "zip") {
if url.pathExtension == "zip" {
ZipImporter.importConfigFiles(from: url) { [weak self] result in
if let error = result.error {
ErrorPresenter.showErrorAlert(error: error, from: self)
@ -241,13 +241,13 @@ extension TunnelsListTableViewController: UITableViewDataSource {
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelsListTableViewCell.id, for: indexPath) as! TunnelsListTableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelsListTableViewCell.reuseIdentifier, for: indexPath) as! TunnelsListTableViewCell
if let tunnelsManager = tunnelsManager {
let tunnel = tunnelsManager.tunnel(at: indexPath.row)
cell.tunnel = tunnel
cell.onSwitchToggled = { [weak self] isOn in
guard let self = self, let tunnelsManager = self.tunnelsManager else { return }
if (isOn) {
if isOn {
tunnelsManager.startActivation(of: tunnel) { [weak self] error in
if let error = error {
ErrorPresenter.showErrorAlert(error: error, from: self, onPresented: {
@ -285,7 +285,7 @@ extension TunnelsListTableViewController: UITableViewDelegate {
guard let tunnelsManager = self?.tunnelsManager else { return }
let tunnel = tunnelsManager.tunnel(at: indexPath.row)
tunnelsManager.remove(tunnel: tunnel, completionHandler: { (error) in
if (error != nil) {
if error != nil {
ErrorPresenter.showErrorAlert(error: error!, from: self)
completionHandler(false)
} else {
@ -309,7 +309,7 @@ extension TunnelsListTableViewController: TunnelsManagerListDelegate {
tableView?.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
func tunnelMoved(at oldIndex: Int, to newIndex: Int) {
func tunnelMoved(from oldIndex: Int, to newIndex: Int) {
tableView?.moveRow(at: IndexPath(row: oldIndex, section: 0), to: IndexPath(row: newIndex, section: 0))
}
@ -320,7 +320,7 @@ extension TunnelsListTableViewController: TunnelsManagerListDelegate {
}
class TunnelsListTableViewCell: UITableViewCell {
static let id: String = "TunnelsListTableViewCell"
static let reuseIdentifier = "TunnelsListTableViewCell"
var tunnel: TunnelContainer? {
didSet(value) {
// Bind to the tunnel's name
@ -396,7 +396,7 @@ class TunnelsListTableViewCell: UITableViewCell {
guard let statusSwitch = statusSwitch, let busyIndicator = busyIndicator else { return }
statusSwitch.isOn = !(status == .deactivating || status == .inactive)
statusSwitch.isUserInteractionEnabled = (status == .inactive || status == .active)
if (status == .inactive || status == .active) {
if status == .inactive || status == .active {
busyIndicator.stopAnimating()
} else {
busyIndicator.startAnimating()

View File

@ -21,7 +21,7 @@ extension ActivateOnDemandSetting {
let rules: [NEOnDemandRule]?
let connectRule = NEOnDemandRuleConnect()
let disconnectRule = NEOnDemandRuleDisconnect()
switch (activateOnDemandOption) {
switch activateOnDemandOption {
case .none:
rules = nil
case .useOnDemandOverWiFiOrCellular:
@ -41,7 +41,7 @@ extension ActivateOnDemandSetting {
init(from tunnelProviderManager: NETunnelProviderManager) {
let rules = tunnelProviderManager.onDemandRules ?? []
let activateOnDemandOption: ActivateOnDemandOption
switch (rules.count) {
switch rules.count {
case 0:
activateOnDemandOption = .none
case 1:
@ -51,9 +51,9 @@ extension ActivateOnDemandSetting {
case 2:
let connectRule = rules.first(where: { $0.action == .connect })!
let disconnectRule = rules.first(where: { $0.action == .disconnect })!
if (connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == .cellular) {
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == .cellular {
activateOnDemandOption = .useOnDemandOverWiFiOnly
} else if (connectRule.interfaceTypeMatch == .cellular && disconnectRule.interfaceTypeMatch == .wiFi) {
} else if connectRule.interfaceTypeMatch == .cellular && disconnectRule.interfaceTypeMatch == .wiFi {
activateOnDemandOption = .useOnDemandOverCellularOnly
} else {
fatalError("Unexpected onDemandRules set on tunnel provider manager")
@ -62,7 +62,7 @@ extension ActivateOnDemandSetting {
fatalError("Unexpected number of onDemandRules set on tunnel provider manager")
}
self.activateOnDemandOption = activateOnDemandOption
if (activateOnDemandOption == .none) {
if activateOnDemandOption == .none {
self.isActivateOnDemandEnabled = false
} else {
self.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled

View File

@ -39,8 +39,8 @@ class InternetReachability {
extension InternetReachability.Status {
init(reachabilityFlags flags: SCNetworkReachabilityFlags) {
var status: InternetReachability.Status = .notReachable
if (flags.contains(.reachable)) {
if (flags.contains(.isWWAN)) {
if flags.contains(.reachable) {
if flags.contains(.isWWAN) {
status = .reachableOverCellular
} else {
status = .reachableOverWiFi

View File

@ -6,10 +6,10 @@ import NetworkExtension
import os.log
protocol TunnelsManagerListDelegate: class {
func tunnelAdded(at: Int)
func tunnelModified(at: Int)
func tunnelMoved(at oldIndex: Int, to newIndex: Int)
func tunnelRemoved(at: Int)
func tunnelAdded(at index: Int)
func tunnelModified(at index: Int)
func tunnelMoved(from oldIndex: Int, to newIndex: Int)
func tunnelRemoved(at index: Int)
}
protocol TunnelsManagerActivationDelegate: class {
@ -33,7 +33,7 @@ enum TunnelsManagerError: WireGuardAppError {
case tunnelActivationFailedNoInternetConnection // startTunnel() succeeded, but activation failed since no internet
func alertText() -> (String, String)? {
switch (self) {
switch self {
case .tunnelNameEmpty:
return ("No name provided", "Can't create tunnel with an empty name")
case .tunnelAlreadyExistsWithThatName:
@ -113,7 +113,7 @@ class TunnelsManager {
activateOnDemandSetting.apply(on: tunnelProviderManager)
tunnelProviderManager.saveToPreferences { [weak self] (error) in
guard (error == nil) else {
guard error == nil else {
os_log("Add: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
completionHandler(.failure(TunnelsManagerError.vpnSystemErrorOnAddTunnel))
return
@ -155,7 +155,7 @@ class TunnelsManager {
let tunnelProviderManager = tunnel.tunnelProvider
let isNameChanged = (tunnelName != tunnelProviderManager.localizedDescription)
if (isNameChanged) {
if isNameChanged {
if self.tunnels.contains(where: { $0.name == tunnelName }) {
completionHandler(TunnelsManagerError.tunnelAlreadyExistsWithThatName)
return
@ -170,33 +170,33 @@ class TunnelsManager {
activateOnDemandSetting.apply(on: tunnelProviderManager)
tunnelProviderManager.saveToPreferences { [weak self] (error) in
guard (error == nil) else {
guard error == nil else {
os_log("Modify: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
completionHandler(TunnelsManagerError.vpnSystemErrorOnModifyTunnel)
return
}
if let self = self {
if (isNameChanged) {
if isNameChanged {
let oldIndex = self.tunnels.firstIndex(of: tunnel)!
self.tunnels.sort { $0.name < $1.name }
let newIndex = self.tunnels.firstIndex(of: tunnel)!
self.tunnelsListDelegate?.tunnelMoved(at: oldIndex, to: newIndex)
self.tunnelsListDelegate?.tunnelMoved(from: oldIndex, to: newIndex)
}
self.tunnelsListDelegate?.tunnelModified(at: self.tunnels.firstIndex(of: tunnel)!)
if (tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting) {
if tunnel.status == .active || tunnel.status == .activating || tunnel.status == .reasserting {
// Turn off the tunnel, and then turn it back on, so the changes are made effective
let session = (tunnel.tunnelProvider.connection as! NETunnelProviderSession)
tunnel.status = .restarting
session.stopTunnel()
}
if (isActivatingOnDemand) {
if isActivatingOnDemand {
// Reload tunnel after saving.
// Without this, the tunnel stopes getting updates on the tunnel status from iOS.
tunnelProviderManager.loadFromPreferences { (error) in
tunnel.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled
guard (error == nil) else {
guard error == nil else {
os_log("Modify: Re-loading after saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
completionHandler(TunnelsManagerError.vpnSystemErrorOnModifyTunnel)
return
@ -214,7 +214,7 @@ class TunnelsManager {
let tunnelProviderManager = tunnel.tunnelProvider
tunnelProviderManager.removeFromPreferences { [weak self] (error) in
guard (error == nil) else {
guard error == nil else {
os_log("Remove: Saving configuration failed: %{public}@", log: OSLog.default, type: .error, "\(error!)")
completionHandler(TunnelsManagerError.vpnSystemErrorOnRemoveTunnel)
return
@ -242,7 +242,7 @@ class TunnelsManager {
func startActivation(of tunnel: TunnelContainer, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
guard tunnels.contains(tunnel) else { return } // Ensure it's not deleted
guard (tunnel.status == .inactive) else {
guard tunnel.status == .inactive else {
completionHandler(TunnelsManagerError.attemptingActivationWhenTunnelIsNotInactive)
return
}
@ -257,7 +257,7 @@ class TunnelsManager {
}
func startDeactivation(of tunnel: TunnelContainer) {
if (tunnel.status == .inactive || tunnel.status == .deactivating) {
if tunnel.status == .inactive || tunnel.status == .deactivating {
return
}
tunnel.startDeactivation()
@ -268,7 +268,7 @@ class TunnelsManager {
}
private func startObservingTunnelStatuses() {
if (statusObservationToken != nil) { return }
if statusObservationToken != nil { return }
statusObservationToken = NotificationCenter.default.addObserver(
forName: .NEVPNStatusDidChange,
object: nil,
@ -282,22 +282,22 @@ class TunnelsManager {
log: OSLog.default, type: .debug, tunnel.name, "\(tunnel.tunnelProvider.connection.status)")
// In case our attempt to start the tunnel, didn't succeed
if (tunnel == self.tunnelBeingActivated) {
if (session.status == .disconnected) {
if (InternetReachability.currentStatus() == .notReachable) {
if tunnel == self.tunnelBeingActivated {
if session.status == .disconnected {
if InternetReachability.currentStatus() == .notReachable {
let error = TunnelsManagerError.tunnelActivationFailedNoInternetConnection
self.activationDelegate?.tunnelActivationFailed(tunnel: tunnel, error: error)
}
self.tunnelBeingActivated = nil
} else if (session.status == .connected) {
} else if session.status == .connected {
self.tunnelBeingActivated = nil
}
}
// In case we're restarting the tunnel
if ((tunnel.status == .restarting) && (session.status == .disconnected || session.status == .disconnecting)) {
if (tunnel.status == .restarting) && (session.status == .disconnected || session.status == .disconnecting) {
// Don't change tunnel.status when disconnecting for a restart
if (session.status == .disconnected) {
if session.status == .disconnected {
self.tunnelBeingActivated = tunnel
tunnel.startActivation(completionHandler: { _ in })
}
@ -364,7 +364,7 @@ class TunnelContainer: NSObject {
lastError: Error? = nil,
tunnelConfiguration: TunnelConfiguration,
completionHandler: @escaping (TunnelsManagerError?) -> Void) {
if (recursionCount >= 8) {
if recursionCount >= 8 {
os_log("startActivation: Failed after 8 attempts. Giving up with %{public}@", log: OSLog.default, type: .error, "\(lastError!)")
completionHandler(TunnelsManagerError.tunnelActivationAttemptFailed)
return
@ -372,13 +372,13 @@ class TunnelContainer: NSObject {
os_log("startActivation: Entering (tunnel: %{public}@)", log: OSLog.default, type: .debug, self.name)
guard (tunnelProvider.isEnabled) else {
guard tunnelProvider.isEnabled else {
// In case the tunnel had gotten disabled, re-enable and save it,
// then call this function again.
os_log("startActivation: Tunnel is disabled. Re-enabling and saving", log: OSLog.default, type: .info)
tunnelProvider.isEnabled = true
tunnelProvider.saveToPreferences { [weak self] (error) in
if (error != nil) {
if error != nil {
os_log("Error saving tunnel after re-enabling: %{public}@", log: OSLog.default, type: .error, "\(error!)")
completionHandler(TunnelsManagerError.tunnelActivationAttemptFailed)
return
@ -398,23 +398,22 @@ class TunnelContainer: NSObject {
try session.startTunnel()
os_log("startActivation: Success", log: OSLog.default, type: .debug)
completionHandler(nil)
} catch (let error) {
} catch let error {
guard let vpnError = error as? NEVPNError else {
os_log("Failed to activate tunnel: Error: %{public}@", log: OSLog.default, type: .debug, "\(error)")
status = .inactive
completionHandler(TunnelsManagerError.tunnelActivationAttemptFailed)
return
}
guard (vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale) else {
guard vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale else {
os_log("Failed to activate tunnel: VPN Error: %{public}@", log: OSLog.default, type: .debug, "\(error)")
status = .inactive
completionHandler(TunnelsManagerError.tunnelActivationAttemptFailed)
return
}
assert(vpnError.code == NEVPNError.configurationInvalid || vpnError.code == NEVPNError.configurationStale)
os_log("startActivation: Will reload tunnel and then try to start it. ", log: OSLog.default, type: .info)
tunnelProvider.loadFromPreferences { [weak self] (error) in
if (error != nil) {
if error != nil {
os_log("startActivation: Error reloading tunnel: %{public}@", log: OSLog.default, type: .debug, "\(error!)")
self?.status = .inactive
completionHandler(TunnelsManagerError.tunnelActivationAttemptFailed)
@ -443,7 +442,7 @@ class TunnelContainer: NSObject {
case restarting // Restarting tunnel (done after saving modifications to an active tunnel)
init(from vpnStatus: NEVPNStatus) {
switch (vpnStatus) {
switch vpnStatus {
case .connected:
self = .active
case .connecting:
@ -462,7 +461,7 @@ class TunnelContainer: NSObject {
extension TunnelStatus: CustomDebugStringConvertible {
public var debugDescription: String {
switch (self) {
switch self {
case .inactive: return "inactive"
case .activating: return "activating"
case .active: return "active"
@ -475,7 +474,7 @@ extension TunnelStatus: CustomDebugStringConvertible {
extension NEVPNStatus: CustomDebugStringConvertible {
public var debugDescription: String {
switch (self) {
switch self {
case .connected: return "connected"
case .connecting: return "connecting"
case .disconnected: return "disconnected"

View File

@ -6,21 +6,21 @@ enum WireGuardResult<T> {
case failure(_ error: WireGuardAppError)
var value: T? {
switch (self) {
switch self {
case .success(let value): return value
case .failure: return nil
}
}
var error: WireGuardAppError? {
switch (self) {
switch self {
case .success: return nil
case .failure(let error): return error
}
}
var isSuccess: Bool {
switch (self) {
switch self {
case .success: return true
case .failure: return false
}

View File

@ -9,7 +9,7 @@ enum ZipArchiveError: WireGuardAppError {
case badArchive
func alertText() -> (String, String)? {
switch (self) {
switch self {
case .cantOpenInputZipFile:
return ("Unable to read zip archive", "The zip archive could not be read.")
case .cantOpenOutputZipFileForWriting:
@ -49,15 +49,11 @@ class ZipArchive {
defer {
unzClose(zipFile)
}
guard (unzGoToFirstFile(zipFile) == UNZ_OK) else {
throw ZipArchiveError.badArchive
}
guard unzGoToFirstFile(zipFile) == UNZ_OK else { throw ZipArchiveError.badArchive }
var resultOfGoToNextFile: Int32
repeat {
guard (unzOpenCurrentFile(zipFile) == UNZ_OK) else {
throw ZipArchiveError.badArchive
}
guard unzOpenCurrentFile(zipFile) == UNZ_OK else { throw ZipArchiveError.badArchive }
let bufferSize = 16384 // 16 KiB
var fileNameBuffer = UnsafeMutablePointer<Int8>.allocate(capacity: bufferSize)
@ -68,38 +64,33 @@ class ZipArchive {
dataBuffer.deallocate()
}
guard (unzGetCurrentFileInfo64(zipFile, nil, fileNameBuffer, UInt(bufferSize), nil, 0, nil, 0) == UNZ_OK) else {
throw ZipArchiveError.badArchive
}
guard unzGetCurrentFileInfo64(zipFile, nil, fileNameBuffer, UInt(bufferSize), nil, 0, nil, 0) == UNZ_OK else { throw ZipArchiveError.badArchive }
let lastChar = String(cString: fileNameBuffer).suffix(1)
let isDirectory = (lastChar == "/" || lastChar == "\\")
let fileURL = URL(fileURLWithFileSystemRepresentation: fileNameBuffer, isDirectory: isDirectory, relativeTo: nil)
if (!isDirectory && requiredFileExtensions.contains(fileURL.pathExtension)) {
if !isDirectory && requiredFileExtensions.contains(fileURL.pathExtension) {
var unzippedData = Data()
var bytesRead: Int32 = 0
repeat {
bytesRead = unzReadCurrentFile(zipFile, dataBuffer, UInt32(bufferSize))
if (bytesRead > 0) {
if bytesRead > 0 {
let dataRead = dataBuffer.withMemoryRebound(to: UInt8.self, capacity: bufferSize) {
(buf: UnsafeMutablePointer<UInt8>) -> Data in
return Data(bytes: buf, count: Int(bytesRead))
return Data(bytes: $0, count: Int(bytesRead))
}
unzippedData.append(dataRead)
}
} while (bytesRead > 0)
} while bytesRead > 0
results.append((fileBaseName: fileURL.deletingPathExtension().lastPathComponent, contents: unzippedData))
}
guard (unzCloseCurrentFile(zipFile) == UNZ_OK) else {
throw ZipArchiveError.badArchive
}
guard unzCloseCurrentFile(zipFile) == UNZ_OK else { throw ZipArchiveError.badArchive }
resultOfGoToNextFile = unzGoToNextFile(zipFile)
} while (resultOfGoToNextFile == UNZ_OK)
} while resultOfGoToNextFile == UNZ_OK
if (resultOfGoToNextFile == UNZ_END_OF_LIST_OF_FILE) {
if resultOfGoToNextFile == UNZ_END_OF_LIST_OF_FILE {
return results
} else {
throw ZipArchiveError.badArchive

View File

@ -7,7 +7,7 @@ enum ZipExporterError: WireGuardAppError {
case noTunnelsToExport
func alertText() -> (String, String)? {
switch (self) {
switch self {
case .noTunnelsToExport:
return ("Nothing to export", "There are no tunnels to export")
}
@ -18,7 +18,7 @@ class ZipExporter {
static func exportConfigFiles(tunnelConfigurations: [TunnelConfiguration], to url: URL,
completion: @escaping (WireGuardAppError?) -> Void) {
guard (!tunnelConfigurations.isEmpty) else {
guard !tunnelConfigurations.isEmpty else {
completion(ZipExporterError.noTunnelsToExport)
return
}
@ -28,14 +28,14 @@ class ZipExporter {
for tunnelConfiguration in tunnelConfigurations {
if let contents = WgQuickConfigFileWriter.writeConfigFile(from: tunnelConfiguration) {
let name = tunnelConfiguration.interface.name
if (name.isEmpty || name == lastTunnelName) { continue }
if name.isEmpty || name == lastTunnelName { continue }
inputsToArchiver.append((fileName: "\(name).conf", contents: contents))
lastTunnelName = name
}
}
do {
try ZipArchive.archive(inputs: inputsToArchiver, to: url)
} catch (let error as WireGuardAppError) {
} catch let error as WireGuardAppError {
DispatchQueue.main.async { completion(error) }
return
} catch {

View File

@ -7,7 +7,7 @@ enum ZipImporterError: WireGuardAppError {
case noTunnelsInZipArchive
func alertText() -> (String, String)? {
switch (self) {
switch self {
case .noTunnelsInZipArchive:
return ("No tunnels in zip archive", "No .conf tunnel files were found inside the zip archive.")
}
@ -23,17 +23,17 @@ class ZipImporter {
for (index, unarchivedFile) in unarchivedFiles.enumerated().reversed() {
let fileBaseName = unarchivedFile.fileBaseName
let trimmedName = fileBaseName.trimmingCharacters(in: .whitespacesAndNewlines)
if (!trimmedName.isEmpty) {
if !trimmedName.isEmpty {
unarchivedFiles[index].fileBaseName = trimmedName
} else {
unarchivedFiles.remove(at: index)
}
}
if (unarchivedFiles.isEmpty) {
if unarchivedFiles.isEmpty {
throw ZipImporterError.noTunnelsInZipArchive
}
} catch (let error as WireGuardAppError) {
} catch let error as WireGuardAppError {
DispatchQueue.main.async { completion(.failure(error)) }
return
} catch {
@ -41,9 +41,9 @@ class ZipImporter {
}
unarchivedFiles.sort { $0.fileBaseName < $1.fileBaseName }
var configs = Array<TunnelConfiguration?>(repeating: nil, count: unarchivedFiles.count)
var configs: [TunnelConfiguration?] = Array(repeating: nil, count: unarchivedFiles.count)
for (index, file) in unarchivedFiles.enumerated() {
if (index > 0 && file == unarchivedFiles[index - 1]) {
if index > 0 && file == unarchivedFiles[index - 1] {
continue
}
guard let fileContents = String(data: file.contents, encoding: .utf8) else {

View File

@ -13,7 +13,7 @@ class DNSResolver {
static func isAllEndpointsAlreadyResolved(endpoints: [Endpoint?]) -> Bool {
for endpoint in endpoints {
guard let endpoint = endpoint else { continue }
if (!endpoint.hasHostAsIPAddress()) {
if !endpoint.hasHostAsIPAddress() {
return false
}
}
@ -23,14 +23,14 @@ class DNSResolver {
static func resolveSync(endpoints: [Endpoint?]) throws -> [Endpoint?] {
let dispatchGroup: DispatchGroup = DispatchGroup()
if (isAllEndpointsAlreadyResolved(endpoints: endpoints)) {
if isAllEndpointsAlreadyResolved(endpoints: endpoints) {
return endpoints
}
var resolvedEndpoints: [Endpoint?] = Array<Endpoint?>(repeating: nil, count: endpoints.count)
var resolvedEndpoints: [Endpoint?] = Array(repeating: nil, count: endpoints.count)
for (index, endpoint) in endpoints.enumerated() {
guard let endpoint = endpoint else { continue }
if (endpoint.hasHostAsIPAddress()) {
if endpoint.hasHostAsIPAddress() {
resolvedEndpoints[index] = endpoint
} else {
let workItem = DispatchWorkItem {
@ -48,14 +48,14 @@ class DNSResolver {
let endpoint = tuple.0
let resolvedEndpoint = tuple.1
if let endpoint = endpoint {
if (resolvedEndpoint == nil) {
if resolvedEndpoint == nil {
// DNS resolution failed
guard let hostname = endpoint.hostname() else { fatalError() }
hostnamesWithDnsResolutionFailure.append(hostname)
}
}
}
if (!hostnamesWithDnsResolutionFailure.isEmpty) {
if !hostnamesWithDnsResolutionFailure.isEmpty {
throw DNSResolverError.dnsResolutionFailed(hostnames: hostnamesWithDnsResolutionFailure)
}
return resolvedEndpoints
@ -76,7 +76,7 @@ extension DNSResolver {
ai_addr: nil,
ai_next: nil)
var resultPointer = UnsafeMutablePointer<addrinfo>(OpaquePointer(bitPattern: 0))
switch (endpoint.host) {
switch endpoint.host {
case .name(let name, _):
// The endpoint is a hostname and needs DNS resolution
let returnValue = getaddrinfo(
@ -84,29 +84,29 @@ extension DNSResolver {
"\(endpoint.port)".cString(using: .utf8), // Port
&hints,
&resultPointer)
if (returnValue == 0) {
if returnValue == 0 {
// getaddrinfo succeeded
let ipv4Buffer = UnsafeMutablePointer<Int8>.allocate(capacity: Int(INET_ADDRSTRLEN))
let ipv6Buffer = UnsafeMutablePointer<Int8>.allocate(capacity: Int(INET6_ADDRSTRLEN))
var ipv4AddressString: String?
var ipv6AddressString: String?
while (resultPointer != nil) {
while resultPointer != nil {
let result = resultPointer!.pointee
resultPointer = result.ai_next
if (result.ai_family == AF_INET && result.ai_addrlen == MemoryLayout<sockaddr_in>.size) {
if result.ai_family == AF_INET && result.ai_addrlen == MemoryLayout<sockaddr_in>.size {
var sa4 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in.self).pointee
if (inet_ntop(result.ai_family, &sa4.sin_addr, ipv4Buffer, socklen_t(INET_ADDRSTRLEN)) != nil) {
if inet_ntop(result.ai_family, &sa4.sin_addr, ipv4Buffer, socklen_t(INET_ADDRSTRLEN)) != nil {
ipv4AddressString = String(cString: ipv4Buffer)
// If we found an IPv4 address, we can stop
break
}
} else if (result.ai_family == AF_INET6 && result.ai_addrlen == MemoryLayout<sockaddr_in6>.size) {
if (ipv6AddressString != nil) {
} else if result.ai_family == AF_INET6 && result.ai_addrlen == MemoryLayout<sockaddr_in6>.size {
if ipv6AddressString != nil {
// If we already have an IPv6 address, we can skip this one
continue
}
var sa6 = UnsafeRawPointer(result.ai_addr)!.assumingMemoryBound(to: sockaddr_in6.self).pointee
if (inet_ntop(result.ai_family, &sa6.sin6_addr, ipv6Buffer, socklen_t(INET6_ADDRSTRLEN)) != nil) {
if inet_ntop(result.ai_family, &sa6.sin6_addr, ipv6Buffer, socklen_t(INET6_ADDRSTRLEN)) != nil {
ipv6AddressString = String(cString: ipv6Buffer)
}
}

View File

@ -5,7 +5,7 @@ import NetworkExtension
class ErrorNotifier {
static func errorMessage(for error: PacketTunnelProviderError) -> (String, String)? {
switch (error) {
switch error {
case .savedProtocolConfigurationIsInvalid:
return ("Activation failure", "Could not retrieve tunnel information from the saved configuration")
case .dnsResolutionFailure:

View File

@ -75,13 +75,12 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
// Setup packetTunnelSettingsGenerator
let packetTunnelSettingsGenerator = PacketTunnelSettingsGenerator(tunnelConfiguration: tunnelConfiguration,
resolvedEndpoints: resolvedEndpoints)
let packetTunnelSettingsGenerator = PacketTunnelSettingsGenerator(tunnelConfiguration: tunnelConfiguration, resolvedEndpoints: resolvedEndpoints)
// Bring up wireguard-go backend
let fd = packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32
if fd < 0 {
let fileDescriptor = packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32
if fileDescriptor < 0 {
wg_log(.error, staticMessage: "Starting tunnel failed: Could not determine file descriptor")
ErrorNotifier.notify(PacketTunnelProviderError.couldNotStartWireGuard, from: self)
startTunnelCompletionHandler(PacketTunnelProviderError.couldNotStartWireGuard)
@ -111,7 +110,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
}
networkMonitor?.start(queue: DispatchQueue(label: "NetworkMonitor"))
handle = connect(interfaceName: tunnelConfiguration.interface.name, settings: wireguardSettings, fd: fd)
handle = connect(interfaceName: tunnelConfiguration.interface.name, settings: wireguardSettings, fileDescriptor: fileDescriptor)
if handle < 0 {
wg_log(.error, staticMessage: "Starting tunnel failed: Could not start WireGuard")
@ -187,9 +186,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
}
}
private func connect(interfaceName: String, settings: String, fd: Int32) -> Int32 { // swiftlint:disable:this cyclomatic_complexity
private func connect(interfaceName: String, settings: String, fileDescriptor: Int32) -> Int32 {
return withStringsAsGoStrings(interfaceName, settings) { (nameGoStr, settingsGoStr) -> Int32 in
return wgTurnOn(nameGoStr, settingsGoStr, fd)
return wgTurnOn(nameGoStr, settingsGoStr, fileDescriptor)
}
}
@ -237,7 +236,7 @@ private func file_log(type: OSLogType, message: String) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS: "
var msgLine = formatter.string(from: Date()) + message
if (msgLine.last! != "\n") {
if msgLine.last! != "\n" {
msgLine.append("\n")
}
let data = msgLine.data(using: .utf8)

View File

@ -36,7 +36,7 @@ class PacketTunnelSettingsGenerator {
if let listenPort = tunnelConfiguration.interface.listenPort {
wgSettings.append("listen_port=\(listenPort)\n")
}
if (tunnelConfiguration.peers.count > 0) {
if tunnelConfiguration.peers.count > 0 {
wgSettings.append("replace_peers=true\n")
}
assert(tunnelConfiguration.peers.count == resolvedEndpoints.count)
@ -51,11 +51,9 @@ class PacketTunnelSettingsGenerator {
}
let persistentKeepAlive = peer.persistentKeepAlive ?? 0
wgSettings.append("persistent_keepalive_interval=\(persistentKeepAlive)\n")
if (!peer.allowedIPs.isEmpty) {
if !peer.allowedIPs.isEmpty {
wgSettings.append("replace_allowed_ips=true\n")
for ip in peer.allowedIPs {
wgSettings.append("allowed_ip=\(ip.stringRepresentation())\n")
}
peer.allowedIPs.forEach { wgSettings.append("allowed_ip=\($0.stringRepresentation())\n") }
}
}
return wgSettings
@ -74,7 +72,7 @@ class PacketTunnelSettingsGenerator {
var remoteAddress: String = "0.0.0.0"
let endpointsCompact = resolvedEndpoints.compactMap({ $0 })
if endpointsCompact.count == 1 {
switch (endpointsCompact.first!.host) {
switch endpointsCompact.first!.host {
case .ipv4(let address):
remoteAddress = "\(address)"
case .ipv6(let address):
@ -96,7 +94,7 @@ class PacketTunnelSettingsGenerator {
// MTU
let mtu = tunnelConfiguration.interface.mtu ?? 0
if (mtu == 0) {
if mtu == 0 {
// 0 imples automatic MTU, where we set overhead as 80 bytes, which is the worst case for WireGuard
networkSettings.tunnelOverheadBytes = 80
} else {
@ -112,10 +110,10 @@ class PacketTunnelSettingsGenerator {
var ipv6NetworkPrefixLengths: [NSNumber] = []
for addressRange in tunnelConfiguration.interface.addresses {
if (addressRange.address is IPv4Address) {
if addressRange.address is IPv4Address {
ipv4Addresses.append("\(addressRange.address)")
ipv4SubnetMasks.append(PacketTunnelSettingsGenerator.ipv4SubnetMaskString(of: addressRange))
} else if (addressRange.address is IPv6Address) {
} else if addressRange.address is IPv6Address {
ipv6Addresses.append("\(addressRange.address)")
ipv6NetworkPrefixLengths.append(NSNumber(value: addressRange.networkPrefixLength))
}
@ -131,10 +129,10 @@ class PacketTunnelSettingsGenerator {
for peer in tunnelConfiguration.peers {
for addressRange in peer.allowedIPs {
if (addressRange.address is IPv4Address) {
if addressRange.address is IPv4Address {
ipv4IncludedRouteAddresses.append("\(addressRange.address)")
ipv4IncludedRouteSubnetMasks.append(PacketTunnelSettingsGenerator.ipv4SubnetMaskString(of: addressRange))
} else if (addressRange.address is IPv6Address) {
} else if addressRange.address is IPv6Address {
ipv6IncludedRouteAddresses.append("\(addressRange.address)")
ipv6IncludedRouteNetworkPrefixLengths.append(NSNumber(value: addressRange.networkPrefixLength))
}
@ -151,7 +149,7 @@ class PacketTunnelSettingsGenerator {
for endpoint in resolvedEndpoints {
guard let endpoint = endpoint else { continue }
switch (endpoint.host) {
switch endpoint.host {
case .ipv4(let address):
ipv4ExcludedRouteAddresses.append("\(address)")
ipv4ExcludedRouteSubnetMasks.append("255.255.255.255") // A single IPv4 address