on-demand: Don't crash on encountering unexpected on-demand rules
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
parent
207f82dd9d
commit
37f8500fe6
|
@ -46,46 +46,59 @@ extension ActivateOnDemandOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
init(from tunnelProviderManager: NETunnelProviderManager) {
|
init(from tunnelProviderManager: NETunnelProviderManager) {
|
||||||
let rules = tunnelProviderManager.onDemandRules ?? []
|
if tunnelProviderManager.isOnDemandEnabled, let onDemandRules = tunnelProviderManager.onDemandRules {
|
||||||
let activateOnDemandOption: ActivateOnDemandOption
|
self = ActivateOnDemandOption.create(from: onDemandRules)
|
||||||
|
} else {
|
||||||
|
self = .off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func create(from rules: [NEOnDemandRule]) -> ActivateOnDemandOption {
|
||||||
switch rules.count {
|
switch rules.count {
|
||||||
case 0:
|
case 0:
|
||||||
activateOnDemandOption = .off
|
return .off
|
||||||
case 1:
|
case 1:
|
||||||
let rule = rules[0]
|
let rule = rules[0]
|
||||||
precondition(rule.action == .connect)
|
guard rule.action == .connect else { return .off }
|
||||||
activateOnDemandOption = .anyInterface(.anySSID)
|
return .anyInterface(.anySSID)
|
||||||
case 2:
|
case 2:
|
||||||
let connectRule = rules.first(where: { $0.action == .connect })!
|
guard let connectRule = rules.first(where: { $0.action == .connect }) else {
|
||||||
let disconnectRule = rules.first(where: { $0.action == .disconnect })!
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but no connect rule.")
|
||||||
|
return .off
|
||||||
|
}
|
||||||
|
guard let disconnectRule = rules.first(where: { $0.action == .disconnect }) else {
|
||||||
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but no disconnect rule.")
|
||||||
|
return .off
|
||||||
|
}
|
||||||
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == nonWiFiInterfaceType {
|
if connectRule.interfaceTypeMatch == .wiFi && disconnectRule.interfaceTypeMatch == nonWiFiInterfaceType {
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.anySSID)
|
return .wiFiInterfaceOnly(.anySSID)
|
||||||
} else if connectRule.interfaceTypeMatch == nonWiFiInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi {
|
} else if connectRule.interfaceTypeMatch == nonWiFiInterfaceType && disconnectRule.interfaceTypeMatch == .wiFi {
|
||||||
activateOnDemandOption = .nonWiFiInterfaceOnly
|
return .nonWiFiInterfaceOnly
|
||||||
} else {
|
} else {
|
||||||
fatalError("Unexpected onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found but interface types are inconsistent.")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
let ssidRule = rules.first(where: { $0.interfaceTypeMatch == .wiFi && $0.ssidMatch != nil })!
|
guard let ssidRule = rules.first(where: { $0.interfaceTypeMatch == .wiFi && $0.ssidMatch != nil }) else { return .off }
|
||||||
let nonWiFiRule = rules.first(where: { $0.interfaceTypeMatch == nonWiFiInterfaceType })!
|
guard let nonWiFiRule = rules.first(where: { $0.interfaceTypeMatch == nonWiFiInterfaceType }) else { return .off }
|
||||||
let ssids = ssidRule.ssidMatch!
|
let ssids = ssidRule.ssidMatch!
|
||||||
switch (ssidRule.action, nonWiFiRule.action) {
|
switch (ssidRule.action, nonWiFiRule.action) {
|
||||||
case (.connect, .connect):
|
case (.connect, .connect):
|
||||||
activateOnDemandOption = .anyInterface(.onlySpecificSSIDs(ssids))
|
return .anyInterface(.onlySpecificSSIDs(ssids))
|
||||||
case (.connect, .disconnect):
|
case (.connect, .disconnect):
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.onlySpecificSSIDs(ssids))
|
return .wiFiInterfaceOnly(.onlySpecificSSIDs(ssids))
|
||||||
case (.disconnect, .connect):
|
case (.disconnect, .connect):
|
||||||
activateOnDemandOption = .anyInterface(.exceptSpecificSSIDs(ssids))
|
return .anyInterface(.exceptSpecificSSIDs(ssids))
|
||||||
case (.disconnect, .disconnect):
|
case (.disconnect, .disconnect):
|
||||||
activateOnDemandOption = .wiFiInterfaceOnly(.exceptSpecificSSIDs(ssids))
|
return .wiFiInterfaceOnly(.exceptSpecificSSIDs(ssids))
|
||||||
default:
|
default:
|
||||||
fatalError("Unexpected SSID onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected onDemandRules set on tunnel provider manager: \(rules.count) rules found")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fatalError("Unexpected number of onDemandRules set on tunnel provider manager")
|
wg_log(.error, message: "Unexpected number of onDemandRules set on tunnel provider manager: \(rules.count) rules found")
|
||||||
|
return .off
|
||||||
}
|
}
|
||||||
|
|
||||||
self = activateOnDemandOption
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue