on-demand: Simplify OS-specific code for interface type selection

Previously, the enum values themselves were different for iOS and macOS.
With this commit, the enum values are common, and only how they're handled
is specific to iOS and macOS.
This commit is contained in:
Roopesh Chander 2019-02-23 14:24:30 +05:30 committed by Jason A. Donenfeld
parent 7610dc94d4
commit 94ba22945e
4 changed files with 43 additions and 71 deletions

View File

@ -10,18 +10,19 @@ struct ActivateOnDemandSetting {
enum ActivateOnDemandOption { enum ActivateOnDemandOption {
case none // Valid only when isActivateOnDemandEnabled is false case none // Valid only when isActivateOnDemandEnabled is false
case useOnDemandOverWiFiOnly case wiFiInterfaceOnly
#if os(iOS) case nonWiFiInterfaceOnly
case useOnDemandOverWiFiOrCellular case anyInterface
case useOnDemandOverCellularOnly
#elseif os(macOS)
case useOnDemandOverWiFiOrEthernet
case useOnDemandOverEthernetOnly
#else
#error("Unimplemented")
#endif
} }
#if os(iOS)
private let nonWiFiInterfaceType: NEOnDemandRuleInterfaceType = .cellular
#elseif os(macOS)
private let nonWiFiInterfaceType: NEOnDemandRuleInterfaceType = .ethernet
#else
#error("Unimplemented")
#endif
extension ActivateOnDemandSetting { extension ActivateOnDemandSetting {
func apply(on tunnelProviderManager: NETunnelProviderManager) { func apply(on tunnelProviderManager: NETunnelProviderManager) {
tunnelProviderManager.isOnDemandEnabled = isActivateOnDemandEnabled tunnelProviderManager.isOnDemandEnabled = isActivateOnDemandEnabled
@ -31,48 +32,22 @@ extension ActivateOnDemandSetting {
switch activateOnDemandOption { switch activateOnDemandOption {
case .none: case .none:
rules = nil rules = nil
#if os(iOS) case .wiFiInterfaceOnly:
case .useOnDemandOverWiFiOrCellular:
rules = [connectRule]
case .useOnDemandOverWiFiOnly:
connectRule.interfaceTypeMatch = .wiFi connectRule.interfaceTypeMatch = .wiFi
disconnectRule.interfaceTypeMatch = .cellular disconnectRule.interfaceTypeMatch = nonWiFiInterfaceType
rules = [connectRule, disconnectRule] rules = [connectRule, disconnectRule]
case .useOnDemandOverCellularOnly: case .nonWiFiInterfaceOnly:
connectRule.interfaceTypeMatch = .cellular connectRule.interfaceTypeMatch = nonWiFiInterfaceType
disconnectRule.interfaceTypeMatch = .wiFi disconnectRule.interfaceTypeMatch = .wiFi
rules = [connectRule, disconnectRule] rules = [connectRule, disconnectRule]
#elseif os(macOS) case .anyInterface:
case .useOnDemandOverWiFiOrEthernet:
rules = [connectRule] rules = [connectRule]
case .useOnDemandOverWiFiOnly:
connectRule.interfaceTypeMatch = .wiFi
disconnectRule.interfaceTypeMatch = .ethernet
rules = [connectRule, disconnectRule]
case .useOnDemandOverEthernetOnly:
connectRule.interfaceTypeMatch = .ethernet
disconnectRule.interfaceTypeMatch = .wiFi
rules = [connectRule, disconnectRule]
#else
#error("Unimplemented")
#endif
} }
tunnelProviderManager.onDemandRules = rules tunnelProviderManager.onDemandRules = rules
} }
init(from tunnelProviderManager: NETunnelProviderManager) { init(from tunnelProviderManager: NETunnelProviderManager) {
let rules = tunnelProviderManager.onDemandRules ?? [] let rules = tunnelProviderManager.onDemandRules ?? []
#if os(iOS)
let otherInterfaceType: NEOnDemandRuleInterfaceType = .cellular
let useWiFiOrOtherOption: ActivateOnDemandOption = .useOnDemandOverWiFiOrCellular
let useOtherOnlyOption: ActivateOnDemandOption = .useOnDemandOverCellularOnly
#elseif os(macOS)
let otherInterfaceType: NEOnDemandRuleInterfaceType = .ethernet
let useWiFiOrOtherOption: ActivateOnDemandOption = .useOnDemandOverWiFiOrEthernet
let useOtherOnlyOption: ActivateOnDemandOption = .useOnDemandOverEthernetOnly
#else
#error("Unimplemented")
#endif
let activateOnDemandOption: ActivateOnDemandOption let activateOnDemandOption: ActivateOnDemandOption
switch rules.count { switch rules.count {
case 0: case 0:
@ -80,14 +55,14 @@ extension ActivateOnDemandSetting {
case 1: case 1:
let rule = rules[0] let rule = rules[0]
precondition(rule.action == .connect) precondition(rule.action == .connect)
activateOnDemandOption = useWiFiOrOtherOption activateOnDemandOption = .anyInterface
case 2: case 2:
let connectRule = rules.first(where: { $0.action == .connect })! let connectRule = rules.first(where: { $0.action == .connect })!
let disconnectRule = rules.first(where: { $0.action == .disconnect })! let disconnectRule = rules.first(where: { $0.action == .disconnect })!
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == otherInterfaceType { if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == nonWiFiInterfaceType {
activateOnDemandOption = .useOnDemandOverWiFiOnly activateOnDemandOption = .wiFiInterfaceOnly
} else if connectRule.interfaceTypeMatch == otherInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi { } else if connectRule.interfaceTypeMatch == nonWiFiInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi {
activateOnDemandOption = useOtherOnlyOption activateOnDemandOption = .nonWiFiInterfaceOnly
} else { } else {
fatalError("Unexpected onDemandRules set on tunnel provider manager") fatalError("Unexpected onDemandRules set on tunnel provider manager")
} }

View File

@ -627,21 +627,24 @@ extension TunnelViewModel {
switch activateOnDemandOption { switch activateOnDemandOption {
case .none: case .none:
return tr("tunnelOnDemandOptionOff") return tr("tunnelOnDemandOptionOff")
case .useOnDemandOverWiFiOnly: case .wiFiInterfaceOnly:
return tr("tunnelOnDemandOptionWiFiOnly") return tr("tunnelOnDemandOptionWiFiOnly")
#if os(iOS) case .nonWiFiInterfaceOnly:
case .useOnDemandOverWiFiOrCellular: #if os(iOS)
return tr("tunnelOnDemandOptionWiFiOrCellular")
case .useOnDemandOverCellularOnly:
return tr("tunnelOnDemandOptionCellularOnly") return tr("tunnelOnDemandOptionCellularOnly")
#elseif os(macOS) #elseif os(macOS)
case .useOnDemandOverWiFiOrEthernet:
return tr("tunnelOnDemandOptionWiFiOrEthernet")
case .useOnDemandOverEthernetOnly:
return tr("tunnelOnDemandOptionEthernetOnly") return tr("tunnelOnDemandOptionEthernetOnly")
#else #else
#error("Unimplemented") #error("Unimplemented")
#endif #endif
case .anyInterface:
#if os(iOS)
return tr("tunnelOnDemandOptionWiFiOrCellular")
#elseif os(macOS)
return tr("tunnelOnDemandOptionWiFiOrEthernet")
#else
#error("Unimplemented")
#endif
} }
} }
@ -658,13 +661,7 @@ extension TunnelViewModel {
} }
static func defaultActivateOnDemandOption() -> ActivateOnDemandOption { static func defaultActivateOnDemandOption() -> ActivateOnDemandOption {
#if os(iOS) return .anyInterface
return .useOnDemandOverWiFiOrCellular
#elseif os(macOS)
return .useOnDemandOverWiFiOrEthernet
#else
#error("Unimplemented")
#endif
} }
} }

View File

@ -44,9 +44,9 @@ class TunnelEditTableViewController: UITableViewController {
] ]
let activateOnDemandOptions: [ActivateOnDemandOption] = [ let activateOnDemandOptions: [ActivateOnDemandOption] = [
.useOnDemandOverWiFiOrCellular, .anyInterface,
.useOnDemandOverWiFiOnly, .wiFiInterfaceOnly,
.useOnDemandOverCellularOnly .nonWiFiInterfaceOnly
] ]
let tunnelsManager: TunnelsManager let tunnelsManager: TunnelsManager

View File

@ -82,9 +82,9 @@ class TunnelEditViewController: NSViewController {
let activateOnDemandOptions: [ActivateOnDemandOption] = [ let activateOnDemandOptions: [ActivateOnDemandOption] = [
.none, .none,
.useOnDemandOverWiFiOrEthernet, .anyInterface,
.useOnDemandOverWiFiOnly, .wiFiInterfaceOnly,
.useOnDemandOverEthernetOnly .nonWiFiInterfaceOnly
] ]
let tunnelsManager: TunnelsManager let tunnelsManager: TunnelsManager