mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +07:00
feat: add Xray split tunnel support for iOS PacketTunnelProvider (#2332)
This commit is contained in:
@@ -21,6 +21,44 @@ extension Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension PacketTunnelProvider {
|
extension PacketTunnelProvider {
|
||||||
|
private func applyXraySplitTunnel(_ xrayConfig: XrayConfig,
|
||||||
|
settings: NEPacketTunnelNetworkSettings) {
|
||||||
|
guard let splitTunnelType = xrayConfig.splitTunnelType else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let splitTunnelSites = xrayConfig.splitTunnelSites else {
|
||||||
|
xrayLog(.error, message: "Split tunnel sites are not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if splitTunnelType == 1 {
|
||||||
|
var ipv4IncludedRoutes = [NEIPv4Route]()
|
||||||
|
|
||||||
|
for allowedIPString in splitTunnelSites {
|
||||||
|
if let allowedIP = IPAddressRange(from: allowedIPString) {
|
||||||
|
ipv4IncludedRoutes.append(NEIPv4Route(
|
||||||
|
destinationAddress: "\(allowedIP.address)",
|
||||||
|
subnetMask: "\(allowedIP.subnetMask())"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.ipv4Settings?.includedRoutes = ipv4IncludedRoutes
|
||||||
|
} else if splitTunnelType == 2 {
|
||||||
|
var ipv4ExcludedRoutes = [NEIPv4Route]()
|
||||||
|
|
||||||
|
for excludedIPString in splitTunnelSites {
|
||||||
|
if let excludedIP = IPAddressRange(from: excludedIPString) {
|
||||||
|
ipv4ExcludedRoutes.append(NEIPv4Route(
|
||||||
|
destinationAddress: "\(excludedIP.address)",
|
||||||
|
subnetMask: "\(excludedIP.subnetMask())"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.ipv4Settings?.excludedRoutes = ipv4ExcludedRoutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func startXray(completionHandler: @escaping (Error?) -> Void) {
|
func startXray(completionHandler: @escaping (Error?) -> Void) {
|
||||||
|
|
||||||
// Xray configuration
|
// Xray configuration
|
||||||
@@ -72,6 +110,7 @@ extension PacketTunnelProvider {
|
|||||||
settings.dnsSettings = !dnsArray.isEmpty
|
settings.dnsSettings = !dnsArray.isEmpty
|
||||||
? NEDNSSettings(servers: dnsArray)
|
? NEDNSSettings(servers: dnsArray)
|
||||||
: NEDNSSettings(servers: ["1.1.1.1"])
|
: NEDNSSettings(servers: ["1.1.1.1"])
|
||||||
|
applyXraySplitTunnel(xrayConfig, settings: settings)
|
||||||
|
|
||||||
let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ import Foundation
|
|||||||
struct XrayConfig: Decodable {
|
struct XrayConfig: Decodable {
|
||||||
let dns1: String?
|
let dns1: String?
|
||||||
let dns2: String?
|
let dns2: String?
|
||||||
|
let splitTunnelType: Int?
|
||||||
|
let splitTunnelSites: [String]?
|
||||||
let config: String
|
let config: String
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -684,6 +684,15 @@ bool IosController::setupXray()
|
|||||||
QJsonObject finalConfig;
|
QJsonObject finalConfig;
|
||||||
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1].toString());
|
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1].toString());
|
||||||
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2].toString());
|
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2].toString());
|
||||||
|
finalConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||||
|
|
||||||
|
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
||||||
|
|
||||||
|
for(int index = 0; index < splitTunnelSites.count(); index++) {
|
||||||
|
splitTunnelSites[index] = splitTunnelSites[index].toString().remove(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
finalConfig.insert(config_key::splitTunnelSites, splitTunnelSites);
|
||||||
finalConfig.insert(config_key::config, xrayConfigStr);
|
finalConfig.insert(config_key::config, xrayConfigStr);
|
||||||
|
|
||||||
QJsonDocument finalConfigDoc(finalConfig);
|
QJsonDocument finalConfigDoc(finalConfig);
|
||||||
|
|||||||
Reference in New Issue
Block a user