iOS Cloak/OVPN SplitTunnel

This commit is contained in:
Mykola Baibuz 2023-10-24 00:28:41 +03:00
parent 22b14dff5f
commit a386d39495

View file

@ -15,7 +15,7 @@ struct Constants {
static let ovpnConfigKey = "ovpn" static let ovpnConfigKey = "ovpn"
static let wireGuardConfigKey = "wireguard" static let wireGuardConfigKey = "wireguard"
static let loggerTag = "NET" static let loggerTag = "NET"
static let kActionStart = "start" static let kActionStart = "start"
static let kActionRestart = "restart" static let kActionRestart = "restart"
static let kActionStop = "stop" static let kActionStop = "stop"
@ -40,7 +40,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
wg_log(logLevel.osLogLevel, message: message) wg_log(logLevel.osLogLevel, message: message)
} }
}() }()
private lazy var ovpnAdapter: OpenVPNAdapter = { private lazy var ovpnAdapter: OpenVPNAdapter = {
let adapter = OpenVPNAdapter() let adapter = OpenVPNAdapter()
adapter.delegate = self adapter.delegate = self
@ -53,9 +53,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
private var openVPNConfig: Data? = nil private var openVPNConfig: Data? = nil
private var SplitTunnelType: String? = nil private var SplitTunnelType: String? = nil
private var SplitTunnelSites: String? = nil private var SplitTunnelSites: String? = nil
let vpnReachability = OpenVPNReachability() let vpnReachability = OpenVPNReachability()
var startHandler: ((Error?) -> Void)? var startHandler: ((Error?) -> Void)?
var stopHandler: (() -> Void)? var stopHandler: (() -> Void)?
var protoType: TunnelProtoType = .none var protoType: TunnelProtoType = .none
@ -74,18 +74,18 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
Logger.global?.log(message: "Failed to serialize message from app") Logger.global?.log(message: "Failed to serialize message from app")
return return
} }
guard let completionHandler = completionHandler else { guard let completionHandler = completionHandler else {
Logger.global?.log(message: "Missing message completion handler") Logger.global?.log(message: "Missing message completion handler")
return return
} }
guard let action = message[Constants.kMessageKeyAction] as? String else { guard let action = message[Constants.kMessageKeyAction] as? String else {
Logger.global?.log(message: "Missing action key in app message") Logger.global?.log(message: "Missing action key in app message")
completionHandler(nil) completionHandler(nil)
return return
} }
if action == Constants.kActionStatus { if action == Constants.kActionStatus {
handleStatusAppMessage(messageData, completionHandler: completionHandler) handleStatusAppMessage(messageData, completionHandler: completionHandler)
} }
@ -102,11 +102,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
Constants.kMessageKeyErrorCode: errorCode ?? NSNull(), Constants.kMessageKeyErrorCode: errorCode ?? NSNull(),
Constants.kMessageKeyTunnelId: 0 Constants.kMessageKeyTunnelId: 0
] ]
completionHandler(try? JSONSerialization.data(withJSONObject: response, options: [])) completionHandler(try? JSONSerialization.data(withJSONObject: response, options: []))
} }
} }
override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) { override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
dispatchQueue.async { dispatchQueue.async {
let activationAttemptId = options?[Constants.kActivationAttemptId] as? String let activationAttemptId = options?[Constants.kActivationAttemptId] as? String
@ -130,8 +130,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
switch self.protoType { switch self.protoType {
case .wireguard: case .wireguard:
self.startWireguard(activationAttemptId: activationAttemptId, self.startWireguard(activationAttemptId: activationAttemptId,
errorNotifier: errorNotifier, errorNotifier: errorNotifier,
completionHandler: completionHandler) completionHandler: completionHandler)
case .openvpn: case .openvpn:
self.startOpenVPN(completionHandler: completionHandler) self.startOpenVPN(completionHandler: completionHandler)
case .shadowsocks: case .shadowsocks:
@ -168,7 +168,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler) handleOpenVPNStatusMessage(messageData, completionHandler: completionHandler)
case .shadowsocks: case .shadowsocks:
break break
// handleShadowSocksAppMessage(messageData, completionHandler: completionHandler) // handleShadowSocksAppMessage(messageData, completionHandler: completionHandler)
case .none: case .none:
break break
@ -180,12 +180,12 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
errorNotifier: ErrorNotifier, errorNotifier: ErrorNotifier,
completionHandler: @escaping (Error?) -> Void) { completionHandler: @escaping (Error?) -> Void) {
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol, guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
let providerConfiguration = protocolConfiguration.providerConfiguration, let providerConfiguration = protocolConfiguration.providerConfiguration,
let wgConfig: Data = providerConfiguration[Constants.wireGuardConfigKey] as? Data else { let wgConfig: Data = providerConfiguration[Constants.wireGuardConfigKey] as? Data else {
wg_log(.error, message: "Can't start WireGuard config missing") wg_log(.error, message: "Can't start WireGuard config missing")
completionHandler(nil) completionHandler(nil)
return return
} }
let wgConfigStr = String(data: wgConfig, encoding: .utf8)! let wgConfigStr = String(data: wgConfig, encoding: .utf8)!
@ -196,26 +196,20 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
return return
} }
wg_log(.error, message: tunnelConfiguration.peers.first!.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", "))
if (tunnelConfiguration.peers.first!.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ") == "0.0.0.0/0, ::/0") {
if (tunnelConfiguration.peers.first!.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", ") == "0.0.0.0/0, ::/0"){
if (SplitTunnelType == "1") { if (SplitTunnelType == "1") {
wg_log(.error, message: SplitTunnelSites!)
for index in tunnelConfiguration.peers.indices { for index in tunnelConfiguration.peers.indices {
tunnelConfiguration.peers[index].allowedIPs.removeAll() tunnelConfiguration.peers[index].allowedIPs.removeAll()
var allowedIPs = [IPAddressRange]() var allowedIPs = [IPAddressRange]()
let STSdata = Data(SplitTunnelSites!.utf8)
let data = Data(SplitTunnelSites!.utf8)
do { do {
let array = try JSONSerialization.jsonObject(with: data) as! [String] let STSArray = try JSONSerialization.jsonObject(with: STSdata) as! [String]
for allowedIPString in array { for allowedIPString in STSArray {
wg_log(.error,message: allowedIPString) if let allowedIP = IPAddressRange(from: allowedIPString) {
guard let allowedIP = IPAddressRange(from: allowedIPString) else { allowedIPs.append(allowedIP)
wg_log(.error,message: "Parse SplitTunnelSites Error")
return
}
allowedIPs.append(allowedIP)
} }
}
} catch { } catch {
wg_log(.error,message: "Parse JSONSerialization Error") wg_log(.error,message: "Parse JSONSerialization Error")
@ -225,22 +219,16 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} else { } else {
if (SplitTunnelType == "2") if (SplitTunnelType == "2")
{ {
wg_log(.error, message: SplitTunnelSites!)
for index in tunnelConfiguration.peers.indices { for index in tunnelConfiguration.peers.indices {
var excludeIPs = [IPAddressRange]() var excludeIPs = [IPAddressRange]()
let STSdata = Data(SplitTunnelSites!.utf8)
let data = Data(SplitTunnelSites!.utf8)
do { do {
let array = try JSONSerialization.jsonObject(with: data) as! [String] let STSarray = try JSONSerialization.jsonObject(with: STSdata) as! [String]
for excludeIPString in array { for excludeIPString in STSarray {
wg_log(.error,message: excludeIPString) if let excludeIP = IPAddressRange(from: excludeIPString) {
guard let excludeIP = IPAddressRange(from: excludeIPString) else { excludeIPs.append(excludeIP)
wg_log(.error,message: "Parse SplitTunnelSites Error")
return
} }
excludeIPs.append(excludeIP) }
}
} catch { } catch {
wg_log(.error,message: "Parse JSONSerialization Error") wg_log(.error,message: "Parse JSONSerialization Error")
} }
@ -250,8 +238,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
} }
wg_log(.error, message: tunnelConfiguration.peers.first!.allowedIPs.map { $0.stringRepresentation }.joined(separator: ", "))
wg_log(.info, message: "Starting wireguard tunnel from the " + (activationAttemptId == nil ? "OS directly, rather than the app" : "app")) wg_log(.info, message: "Starting wireguard tunnel from the " + (activationAttemptId == nil ? "OS directly, rather than the app" : "app"))
// Start the tunnel // Start the tunnel
@ -262,30 +248,30 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
completionHandler(nil) completionHandler(nil)
return return
} }
switch adapterError { switch adapterError {
case .cannotLocateTunnelFileDescriptor: case .cannotLocateTunnelFileDescriptor:
wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor") wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor")
errorNotifier.notify(PacketTunnelProviderError.couldNotDetermineFileDescriptor) errorNotifier.notify(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
completionHandler(PacketTunnelProviderError.couldNotDetermineFileDescriptor) completionHandler(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
case .dnsResolution(let dnsErrors): case .dnsResolution(let dnsErrors):
let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address } let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address }
.joined(separator: ", ") .joined(separator: ", ")
wg_log(.error, message: "DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)") wg_log(.error, message: "DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)")
errorNotifier.notify(PacketTunnelProviderError.dnsResolutionFailure) errorNotifier.notify(PacketTunnelProviderError.dnsResolutionFailure)
completionHandler(PacketTunnelProviderError.dnsResolutionFailure) completionHandler(PacketTunnelProviderError.dnsResolutionFailure)
case .setNetworkSettings(let error): case .setNetworkSettings(let error):
wg_log(.error, message: "Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)") wg_log(.error, message: "Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)")
errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings) errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings)
completionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings) completionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings)
case .startWireGuardBackend(let errorCode): case .startWireGuardBackend(let errorCode):
wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)") wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)")
errorNotifier.notify(PacketTunnelProviderError.couldNotStartBackend) errorNotifier.notify(PacketTunnelProviderError.couldNotStartBackend)
completionHandler(PacketTunnelProviderError.couldNotStartBackend) completionHandler(PacketTunnelProviderError.couldNotStartBackend)
case .invalidState: case .invalidState:
// Must never happen // Must never happen
fatalError() fatalError()
@ -295,27 +281,27 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
private func startOpenVPN(completionHandler: @escaping (Error?) -> Void) { private func startOpenVPN(completionHandler: @escaping (Error?) -> Void) {
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol, guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
let providerConfiguration = protocolConfiguration.providerConfiguration, let providerConfiguration = protocolConfiguration.providerConfiguration,
let ovpnConfiguration: Data = providerConfiguration[Constants.ovpnConfigKey] as? Data else { let ovpnConfiguration: Data = providerConfiguration[Constants.ovpnConfigKey] as? Data else {
// TODO: handle errors properly // TODO: handle errors properly
wg_log(.error, message: "Can't start startOpenVPN()") wg_log(.error, message: "Can't start startOpenVPN()")
return return
} }
setupAndlaunchOpenVPN(withConfig: ovpnConfiguration, completionHandler: completionHandler) setupAndlaunchOpenVPN(withConfig: ovpnConfiguration, completionHandler: completionHandler)
} }
private func stopWireguard(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { private func stopWireguard(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
wg_log(.info, staticMessage: "Stopping tunnel") wg_log(.info, staticMessage: "Stopping tunnel")
wgAdapter.stop { error in wgAdapter.stop { error in
ErrorNotifier.removeLastErrorFile() ErrorNotifier.removeLastErrorFile()
if let error = error { if let error = error {
wg_log(.error, message: "Failed to stop WireGuard adapter: \(error.localizedDescription)") wg_log(.error, message: "Failed to stop WireGuard adapter: \(error.localizedDescription)")
} }
completionHandler() completionHandler()
#if os(macOS) #if os(macOS)
// HACK: This is a filthy hack to work around Apple bug 32073323 (dup'd by us as 47526107). // HACK: This is a filthy hack to work around Apple bug 32073323 (dup'd by us as 47526107).
// Remove it when they finally fix this upstream and the fix has been rolled out to // Remove it when they finally fix this upstream and the fix has been rolled out to
@ -332,7 +318,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
ovpnAdapter.disconnect() ovpnAdapter.disconnect()
} }
func handleWireguardStatusMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) { func handleWireguardStatusMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
guard let completionHandler = completionHandler else { return } guard let completionHandler = completionHandler else { return }
wgAdapter.getRuntimeConfiguration { settings in wgAdapter.getRuntimeConfiguration { settings in
@ -347,8 +333,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
for component in components{ for component in components{
let pair = component.components(separatedBy: "=") let pair = component.components(separatedBy: "=")
if pair.count == 2 { if pair.count == 2 {
settingsDictionary[pair[0]] = pair[1] settingsDictionary[pair[0]] = pair[1]
} }
} }
let response: [String: Any] = [ let response: [String: Any] = [
@ -378,7 +364,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
completionHandler(nil) completionHandler(nil)
return return
} }
do { do {
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: configString) let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: configString)
wgAdapter.update(tunnelConfiguration: tunnelConfiguration) { error in wgAdapter.update(tunnelConfiguration: tunnelConfiguration) { error in
@ -387,7 +373,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
completionHandler(nil) completionHandler(nil)
return return
} }
self.wgAdapter.getRuntimeConfiguration { settings in self.wgAdapter.getRuntimeConfiguration { settings in
var data: Data? var data: Data?
if let settings = settings { if let settings = settings {
@ -403,76 +389,76 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
completionHandler(nil) completionHandler(nil)
} }
} }
private func handleOpenVPNStatusMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) { private func handleOpenVPNStatusMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)? = nil) {
guard let completionHandler = completionHandler else { return } guard let completionHandler = completionHandler else { return }
let bytesin = ovpnAdapter.transportStatistics.bytesIn let bytesin = ovpnAdapter.transportStatistics.bytesIn
let bytesout = ovpnAdapter.transportStatistics.bytesOut let bytesout = ovpnAdapter.transportStatistics.bytesOut
let response: [String: Any] = [ let response: [String: Any] = [
"rx_bytes" : bytesin, "rx_bytes" : bytesin,
"tx_bytes" : bytesout "tx_bytes" : bytesout
] ]
completionHandler(try? JSONSerialization.data(withJSONObject: response, options: [])) completionHandler(try? JSONSerialization.data(withJSONObject: response, options: []))
} }
// TODO review // TODO review
private func setupAndlaunchOpenVPN(withConfig ovpnConfiguration: Data, withShadowSocks viaSS: Bool = false, completionHandler: @escaping (Error?) -> Void) { private func setupAndlaunchOpenVPN(withConfig ovpnConfiguration: Data, withShadowSocks viaSS: Bool = false, completionHandler: @escaping (Error?) -> Void) {
wg_log(.info, message: "setupAndlaunchOpenVPN") wg_log(.info, message: "setupAndlaunchOpenVPN")
let str = String(decoding: ovpnConfiguration, as: UTF8.self) let str = String(decoding: ovpnConfiguration, as: UTF8.self)
let configuration = OpenVPNConfiguration() let configuration = OpenVPNConfiguration()
configuration.fileContent = ovpnConfiguration configuration.fileContent = ovpnConfiguration
if(str.contains("cloak")){ if(str.contains("cloak")){
configuration.setPTCloak(); configuration.setPTCloak();
} }
let evaluation: OpenVPNConfigurationEvaluation let evaluation: OpenVPNConfigurationEvaluation
do { do {
evaluation = try ovpnAdapter.apply(configuration: configuration) evaluation = try ovpnAdapter.apply(configuration: configuration)
} catch { } catch {
completionHandler(error) completionHandler(error)
return return
} }
if !evaluation.autologin { if !evaluation.autologin {
wg_log(.info, message: "Implement login with user credentials") wg_log(.info, message: "Implement login with user credentials")
} }
vpnReachability.startTracking { [weak self] status in vpnReachability.startTracking { [weak self] status in
guard status == .reachableViaWiFi else { return } guard status == .reachableViaWiFi else { return }
self?.ovpnAdapter.reconnect(afterTimeInterval: 5) self?.ovpnAdapter.reconnect(afterTimeInterval: 5)
} }
startHandler = completionHandler startHandler = completionHandler
ovpnAdapter.connect(using: packetFlow) ovpnAdapter.connect(using: packetFlow)
// let ifaces = Interface.allInterfaces() // let ifaces = Interface.allInterfaces()
// .filter { $0.family == .ipv4 } // .filter { $0.family == .ipv4 }
// .map { iface in iface.name } // .map { iface in iface.name }
// wg_log(.error, message: "Available TUN Interfaces: \(ifaces)") // wg_log(.error, message: "Available TUN Interfaces: \(ifaces)")
} }
// MARK: -- Network observing methods // MARK: -- Network observing methods
private func startListeningForNetworkChanges() { private func startListeningForNetworkChanges() {
stopListeningForNetworkChanges() stopListeningForNetworkChanges()
addObserver(self, forKeyPath: Constants.kDefaultPathKey, options: .old, context: nil) addObserver(self, forKeyPath: Constants.kDefaultPathKey, options: .old, context: nil)
} }
private func stopListeningForNetworkChanges() { private func stopListeningForNetworkChanges() {
removeObserver(self, forKeyPath: Constants.kDefaultPathKey) removeObserver(self, forKeyPath: Constants.kDefaultPathKey)
} }
override func observeValue(forKeyPath keyPath: String?, override func observeValue(forKeyPath keyPath: String?,
of object: Any?, of object: Any?,
change: [NSKeyValueChangeKey : Any]?, change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) { context: UnsafeMutableRawPointer?) {
guard Constants.kDefaultPathKey != keyPath else { return } guard Constants.kDefaultPathKey != keyPath else { return }
// Since iOS 11, we have observed that this KVO event fires repeatedly when connecting over Wifi, // Since iOS 11, we have observed that this KVO event fires repeatedly when connecting over Wifi,
// even though the underlying network has not changed (i.e. `isEqualToPath` returns false), // even though the underlying network has not changed (i.e. `isEqualToPath` returns false),
@ -481,28 +467,28 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
guard let lastPath: NWPath = change?[.oldKey] as? NWPath, guard let lastPath: NWPath = change?[.oldKey] as? NWPath,
let defPath = defaultPath, let defPath = defaultPath,
lastPath != defPath || lastPath.description != defPath.description else { lastPath != defPath || lastPath.description != defPath.description else {
return return
} }
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let `self` = self, self.defaultPath != nil else { return } guard let `self` = self, self.defaultPath != nil else { return }
self.handle(networkChange: self.defaultPath!) { _ in } self.handle(networkChange: self.defaultPath!) { _ in }
} }
} }
private func handle(networkChange changePath: NWPath, completion: @escaping (Error?) -> Void) { private func handle(networkChange changePath: NWPath, completion: @escaping (Error?) -> Void) {
wg_log(.info, message: "Tunnel restarted.") wg_log(.info, message: "Tunnel restarted.")
startTunnel(options: nil, completionHandler: completion) startTunnel(options: nil, completionHandler: completion)
} }
private func startEmptyTunnel(completionHandler: @escaping (Error?) -> Void) { private func startEmptyTunnel(completionHandler: @escaping (Error?) -> Void) {
dispatchPrecondition(condition: .onQueue(dispatchQueue)) dispatchPrecondition(condition: .onQueue(dispatchQueue))
let emptyTunnelConfiguration = TunnelConfiguration( let emptyTunnelConfiguration = TunnelConfiguration(
name: nil, name: nil,
interface: InterfaceConfiguration(privateKey: PrivateKey()), interface: InterfaceConfiguration(privateKey: PrivateKey()),
peers: [] peers: []
) )
wgAdapter.start(tunnelConfiguration: emptyTunnelConfiguration) { error in wgAdapter.start(tunnelConfiguration: emptyTunnelConfiguration) { error in
self.dispatchQueue.async { self.dispatchQueue.async {
if let error { if let error {
@ -514,9 +500,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
} }
} }
} }
let settings = NETunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1") let settings = NETunnelNetworkSettings(tunnelRemoteAddress: "1.1.1.1")
self.setTunnelNetworkSettings(settings) { error in self.setTunnelNetworkSettings(settings) { error in
completionHandler(error) completionHandler(error)
} }
@ -547,6 +533,50 @@ extension PacketTunnelProvider: OpenVPNAdapterDelegate {
// send empty string to NEDNSSettings.matchDomains // send empty string to NEDNSSettings.matchDomains
networkSettings?.dnsSettings?.matchDomains = [""] networkSettings?.dnsSettings?.matchDomains = [""]
if (SplitTunnelType == "1") {
var ipv4IncludedRoutes = [NEIPv4Route]()
let STSdata = Data(SplitTunnelSites!.utf8)
do {
let STSarray = try JSONSerialization.jsonObject(with: STSdata) as! [String]
for allowedIPString in STSarray {
if let allowedIP = IPAddressRange(from: allowedIPString){
ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(allowedIP.address)", subnetMask: "\(allowedIP.subnetMask())"))
}
}
} catch {
wg_log(.error,message: "Parse JSONSerialization Error")
}
networkSettings?.ipv4Settings?.includedRoutes = ipv4IncludedRoutes
} else {
if (SplitTunnelType == "2")
{
var ipv4ExcludedRoutes = [NEIPv4Route]()
var ipv4IncludedRoutes = [NEIPv4Route]()
var ipv6IncludedRoutes = [NEIPv6Route]()
let STSdata = Data(SplitTunnelSites!.utf8)
do {
let STSarray = try JSONSerialization.jsonObject(with: STSdata) as! [String]
for excludeIPString in STSarray {
if let excludeIP = IPAddressRange(from: excludeIPString) {
ipv4ExcludedRoutes.append(NEIPv4Route(destinationAddress: "\(excludeIP.address)", subnetMask: "\(excludeIP.subnetMask())"))
}
}
} catch {
wg_log(.error,message: "Parse JSONSerialization Error")
}
if let allIPv4 = IPAddressRange(from: "0.0.0.0/0"){
ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(allIPv4.address)", subnetMask: "\(allIPv4.subnetMask())"))
}
if let allIPv6 = IPAddressRange(from: "::/0") {
ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(allIPv6.address)", networkPrefixLength: NSNumber(value: allIPv6.networkPrefixLength)))
}
networkSettings?.ipv4Settings?.includedRoutes = ipv4IncludedRoutes
networkSettings?.ipv6Settings?.includedRoutes = ipv6IncludedRoutes
networkSettings?.ipv4Settings?.excludedRoutes = ipv4ExcludedRoutes
}
}
// Set the network settings for the current tunneling session. // Set the network settings for the current tunneling session.
setTunnelNetworkSettings(networkSettings, completionHandler: completionHandler) setTunnelNetworkSettings(networkSettings, completionHandler: completionHandler)
} }
@ -607,7 +637,7 @@ extension PacketTunnelProvider: OpenVPNAdapterDelegate {
wg_log(.info, message: logMessage) wg_log(.info, message: logMessage)
} }
} }
extension WireGuardLogLevel { extension WireGuardLogLevel {
var osLogLevel: OSLogType { var osLogLevel: OSLogType {
switch self { switch self {