mirror of
https://github.com/outbackdingo/amnezia-client.git
synced 2026-01-27 10:18:14 +00:00
Setup MTU for iOS
This commit is contained in:
@@ -38,7 +38,7 @@ struct Log {
|
||||
init(_ str: String) {
|
||||
self.records = str.split(whereSeparator: \.isNewline)
|
||||
.compactMap {
|
||||
Record(String($0))!
|
||||
Record(String($0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,40 +18,32 @@ extension PacketTunnelProvider: OpenVPNAdapterDelegate {
|
||||
// send empty string to NEDNSSettings.matchDomains
|
||||
networkSettings?.dnsSettings?.matchDomains = [""]
|
||||
|
||||
if splitTunnelType == "1" {
|
||||
if splitTunnelType == 1 {
|
||||
var ipv4IncludedRoutes = [NEIPv4Route]()
|
||||
let STSdata = Data(splitTunnelSites!.utf8)
|
||||
do {
|
||||
guard let STSArray = try JSONSerialization.jsonObject(with: STSdata) as? [String] else { return }
|
||||
for allowedIPString in STSArray {
|
||||
if let allowedIP = IPAddressRange(from: allowedIPString) {
|
||||
ipv4IncludedRoutes.append(NEIPv4Route(
|
||||
destinationAddress: "\(allowedIP.address)",
|
||||
subnetMask: "\(allowedIP.subnetMask())"))
|
||||
}
|
||||
|
||||
for allowedIPString in splitTunnelSites {
|
||||
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" {
|
||||
if splitTunnelType == 2 {
|
||||
var ipv4ExcludedRoutes = [NEIPv4Route]()
|
||||
var ipv4IncludedRoutes = [NEIPv4Route]()
|
||||
var ipv6IncludedRoutes = [NEIPv6Route]()
|
||||
let STSdata = Data(splitTunnelSites!.utf8)
|
||||
do {
|
||||
guard let STSArray = try JSONSerialization.jsonObject(with: STSdata) as? [String] else { return }
|
||||
for excludeIPString in STSArray {
|
||||
if let excludeIP = IPAddressRange(from: excludeIPString) {
|
||||
ipv4ExcludedRoutes.append(NEIPv4Route(
|
||||
destinationAddress: "\(excludeIP.address)",
|
||||
subnetMask: "\(excludeIP.subnetMask())"))
|
||||
}
|
||||
|
||||
for excludeIPString in splitTunnelSites {
|
||||
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)",
|
||||
|
||||
@@ -50,8 +50,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
private let dispatchQueue = DispatchQueue(label: "PacketTunnel", qos: .utility)
|
||||
|
||||
private var openVPNConfig: Data?
|
||||
var splitTunnelType: String?
|
||||
var splitTunnelSites: String?
|
||||
var splitTunnelType: Int!
|
||||
var splitTunnelSites: [String]!
|
||||
|
||||
let vpnReachability = OpenVPNReachability()
|
||||
|
||||
@@ -83,8 +83,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
}
|
||||
|
||||
if action == Constants.kActionStart {
|
||||
splitTunnelType = message[Constants.kMessageKeySplitTunnelType] as? String
|
||||
splitTunnelSites = message[Constants.kMessageKeySplitTunnelSites] as? String
|
||||
// splitTunnelType = message[Constants.kMessageKeySplitTunnelType] as? String
|
||||
// splitTunnelSites = message[Constants.kMessageKeySplitTunnelSites] as? String
|
||||
}
|
||||
|
||||
let callbackWrapper: (NSNumber?) -> Void = { errorCode in
|
||||
@@ -169,110 +169,118 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
completionHandler: @escaping (Error?) -> Void) {
|
||||
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
||||
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
||||
let wgConfig: Data = providerConfiguration[Constants.wireGuardConfigKey] as? Data else {
|
||||
let wgConfigData: Data = providerConfiguration[Constants.wireGuardConfigKey] as? Data else {
|
||||
wg_log(.error, message: "Can't start WireGuard config missing")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard let wgConfigStr = try? JSONDecoder().decode(WGConfig.self, from: wgConfig).wg,
|
||||
let tunnelConfiguration = try? TunnelConfiguration(fromWgQuickConfig: wgConfigStr)
|
||||
else {
|
||||
wg_log(.error, message: "Can't parse WireGuard config")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
do {
|
||||
let wgConfig = try JSONDecoder().decode(WGConfig.self, from: wgConfigData)
|
||||
let wgConfigStr = wgConfig.str
|
||||
log(.info, message: "wgConfig: \(wgConfig.redux.replacingOccurrences(of: "\n", with: " "))")
|
||||
|
||||
log(.info, message: "wgConfig: \(wgConfigStr.replacingOccurrences(of: "\n", with: " "))")
|
||||
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: wgConfigStr)
|
||||
|
||||
if tunnelConfiguration.peers.first!.allowedIPs
|
||||
.map({ $0.stringRepresentation })
|
||||
.joined(separator: ", ") == "0.0.0.0/0, ::/0" {
|
||||
if splitTunnelType == "1" {
|
||||
for index in tunnelConfiguration.peers.indices {
|
||||
tunnelConfiguration.peers[index].allowedIPs.removeAll()
|
||||
var allowedIPs = [IPAddressRange]()
|
||||
let STSdata = Data(splitTunnelSites!.utf8)
|
||||
do {
|
||||
guard let STSArray = try JSONSerialization.jsonObject(with: STSdata) as? [String] else { return }
|
||||
for allowedIPString in STSArray {
|
||||
if tunnelConfiguration.peers.first!.allowedIPs
|
||||
.map({ $0.stringRepresentation })
|
||||
.joined(separator: ", ") == "0.0.0.0/0, ::/0" {
|
||||
if wgConfig.splitTunnelType == 1 {
|
||||
for index in tunnelConfiguration.peers.indices {
|
||||
tunnelConfiguration.peers[index].allowedIPs.removeAll()
|
||||
var allowedIPs = [IPAddressRange]()
|
||||
|
||||
for allowedIPString in wgConfig.splitTunnelSites {
|
||||
if let allowedIP = IPAddressRange(from: allowedIPString) {
|
||||
allowedIPs.append(allowedIP)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
wg_log(.error, message: "Parse JSONSerialization Error")
|
||||
|
||||
tunnelConfiguration.peers[index].allowedIPs = allowedIPs
|
||||
}
|
||||
tunnelConfiguration.peers[index].allowedIPs = allowedIPs
|
||||
}
|
||||
} else if splitTunnelType == "2" {
|
||||
for index in tunnelConfiguration.peers.indices {
|
||||
var excludeIPs = [IPAddressRange]()
|
||||
let STSdata = Data(splitTunnelSites!.utf8)
|
||||
do {
|
||||
guard let STSArray = try JSONSerialization.jsonObject(with: STSdata) as? [String] else { return }
|
||||
for excludeIPString in STSArray {
|
||||
} else if wgConfig.splitTunnelType == 2 {
|
||||
for index in tunnelConfiguration.peers.indices {
|
||||
var excludeIPs = [IPAddressRange]()
|
||||
|
||||
for excludeIPString in wgConfig.splitTunnelSites {
|
||||
if let excludeIP = IPAddressRange(from: excludeIPString) {
|
||||
excludeIPs.append(excludeIP)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
wg_log(.error, message: "Parse JSONSerialization Error")
|
||||
|
||||
tunnelConfiguration.peers[index].excludeIPs = excludeIPs
|
||||
}
|
||||
tunnelConfiguration.peers[index].excludeIPs = excludeIPs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
wgAdapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
||||
guard let adapterError else {
|
||||
let interfaceName = self.wgAdapter.interfaceName ?? "unknown"
|
||||
wg_log(.info, message: "Tunnel interface is \(interfaceName)")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
switch adapterError {
|
||||
case .cannotLocateTunnelFileDescriptor:
|
||||
wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
|
||||
completionHandler(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
|
||||
case .dnsResolution(let dnsErrors):
|
||||
let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address }
|
||||
.joined(separator: ", ")
|
||||
wg_log(.error, message:
|
||||
"DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.dnsResolutionFailure)
|
||||
completionHandler(PacketTunnelProviderError.dnsResolutionFailure)
|
||||
case .setNetworkSettings(let error):
|
||||
wg_log(.error, message:
|
||||
"Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||
completionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||
case .startWireGuardBackend(let errorCode):
|
||||
wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotStartBackend)
|
||||
completionHandler(PacketTunnelProviderError.couldNotStartBackend)
|
||||
case .invalidState:
|
||||
fatalError()
|
||||
// Start the tunnel
|
||||
wgAdapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
||||
guard let adapterError else {
|
||||
let interfaceName = self.wgAdapter.interfaceName ?? "unknown"
|
||||
wg_log(.info, message: "Tunnel interface is \(interfaceName)")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
switch adapterError {
|
||||
case .cannotLocateTunnelFileDescriptor:
|
||||
wg_log(.error, staticMessage: "Starting tunnel failed: could not determine file descriptor")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
|
||||
completionHandler(PacketTunnelProviderError.couldNotDetermineFileDescriptor)
|
||||
case .dnsResolution(let dnsErrors):
|
||||
let hostnamesWithDnsResolutionFailure = dnsErrors.map { $0.address }
|
||||
.joined(separator: ", ")
|
||||
wg_log(.error, message:
|
||||
"DNS resolution failed for the following hostnames: \(hostnamesWithDnsResolutionFailure)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.dnsResolutionFailure)
|
||||
completionHandler(PacketTunnelProviderError.dnsResolutionFailure)
|
||||
case .setNetworkSettings(let error):
|
||||
wg_log(.error, message:
|
||||
"Starting tunnel failed with setTunnelNetworkSettings returning \(error.localizedDescription)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||
completionHandler(PacketTunnelProviderError.couldNotSetNetworkSettings)
|
||||
case .startWireGuardBackend(let errorCode):
|
||||
wg_log(.error, message: "Starting tunnel failed with wgTurnOn returning \(errorCode)")
|
||||
errorNotifier.notify(PacketTunnelProviderError.couldNotStartBackend)
|
||||
completionHandler(PacketTunnelProviderError.couldNotStartBackend)
|
||||
case .invalidState:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
log(.error, message: "Can't parse WG config: \(error.localizedDescription)")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private func startOpenVPN(completionHandler: @escaping (Error?) -> Void) {
|
||||
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
||||
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
||||
let ovpnConfiguration: Data = providerConfiguration[Constants.ovpnConfigKey] as? Data else {
|
||||
|
||||
let openVPNConfigData = providerConfiguration[Constants.ovpnConfigKey] as? Data else {
|
||||
wg_log(.error, message: "Can't start startOpenVPN()")
|
||||
return
|
||||
}
|
||||
|
||||
setupAndlaunchOpenVPN(withConfig: ovpnConfiguration, completionHandler: completionHandler)
|
||||
do {
|
||||
log(.info, message: "providerConfiguration: \(String(decoding: openVPNConfigData, as: UTF8.self).replacingOccurrences(of: "\n", with: " "))")
|
||||
|
||||
let openVPNConfig = try JSONDecoder().decode(OpenVPNConfig.self, from: openVPNConfigData)
|
||||
log(.info, message: "openVPNConfig: \(openVPNConfig.str.replacingOccurrences(of: "\n", with: " "))")
|
||||
let ovpnConfiguration = Data(openVPNConfig.config.utf8)
|
||||
setupAndlaunchOpenVPN(withConfig: ovpnConfiguration, completionHandler: completionHandler)
|
||||
} catch {
|
||||
log(.error, message: "Can't parse OpenVPN config: \(error.localizedDescription)")
|
||||
|
||||
if let underlyingError = (error as NSError).userInfo[NSUnderlyingErrorKey] as? NSError {
|
||||
log(.error, message: "Can't parse OpenVPN config: \(underlyingError.localizedDescription)")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private func stopWireguard(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||
|
||||
@@ -1,9 +1,41 @@
|
||||
import Foundation
|
||||
|
||||
struct WGConfigData: Decodable {
|
||||
struct WGConfig: Decodable {
|
||||
let h1, h2, h3, h4: String?
|
||||
let jc, jmax, jmin: String?
|
||||
let s1, s2: String?
|
||||
let dns1: String
|
||||
let dns2: String
|
||||
let mtu: String
|
||||
let hostName: String
|
||||
let port: Int
|
||||
let clientIP: String
|
||||
let clientPrivateKey: String
|
||||
let serverPublicKey: String
|
||||
let presharedKey: String
|
||||
var allowedIPs: [String]
|
||||
var persistentKeepAlive: String
|
||||
let splitTunnelType: Int
|
||||
let splitTunnelSites: [String]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case h1 = "H1", h2 = "H2", h3 = "H3", h4 = "H4"
|
||||
case jc = "Jc", jmax = "Jmax", jmin = "Jmin"
|
||||
case s1 = "S1", s2 = "S2"
|
||||
case dns1
|
||||
case dns2
|
||||
case mtu
|
||||
case hostName
|
||||
case port
|
||||
case clientIP = "client_ip"
|
||||
case clientPrivateKey = "client_priv_key"
|
||||
case serverPublicKey = "server_pub_key"
|
||||
case presharedKey = "psk_key"
|
||||
case allowedIPs = "allowed_ips"
|
||||
case persistentKeepAlive = "persistent_keep_alive"
|
||||
case splitTunnelType
|
||||
case splitTunnelSites
|
||||
}
|
||||
|
||||
var settings: String {
|
||||
jc == nil ? "" :
|
||||
@@ -21,113 +53,48 @@ struct WGConfigData: Decodable {
|
||||
"""
|
||||
}
|
||||
|
||||
let clientIP: String
|
||||
let clientPrivateKey: String
|
||||
let clientPublicKey: String
|
||||
let serverPublicKey: String
|
||||
let presharedKey: String
|
||||
let hostName: String
|
||||
let port: Int
|
||||
|
||||
var allowedIPs: [String]
|
||||
var persistentKeepAlive: String
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case h1 = "H1", h2 = "H2", h3 = "H3", h4 = "H4"
|
||||
case jc = "Jc", jmax = "Jmax", jmin = "Jmin"
|
||||
case s1 = "S1", s2 = "S2"
|
||||
|
||||
case clientIP = "client_ip" // "10.8.1.16"
|
||||
case clientPrivateKey = "client_priv_key"
|
||||
case clientPublicKey = "client_pub_key"
|
||||
case serverPublicKey = "server_pub_key"
|
||||
case presharedKey = "psk_key"
|
||||
|
||||
case allowedIPs = "allowed_ips"
|
||||
case persistentKeepAlive = "persistent_keep_alive"
|
||||
case hostName
|
||||
case port
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.h1 = try container.decodeIfPresent(String.self, forKey: .h1)
|
||||
self.h2 = try container.decodeIfPresent(String.self, forKey: .h2)
|
||||
self.h3 = try container.decodeIfPresent(String.self, forKey: .h3)
|
||||
self.h4 = try container.decodeIfPresent(String.self, forKey: .h4)
|
||||
self.jc = try container.decodeIfPresent(String.self, forKey: .jc)
|
||||
self.jmax = try container.decodeIfPresent(String.self, forKey: .jmax)
|
||||
self.jmin = try container.decodeIfPresent(String.self, forKey: .jmin)
|
||||
self.s1 = try container.decodeIfPresent(String.self, forKey: .s1)
|
||||
self.s2 = try container.decodeIfPresent(String.self, forKey: .s2)
|
||||
self.clientIP = try container.decode(String.self, forKey: .clientIP)
|
||||
self.clientPrivateKey = try container.decode(String.self, forKey: .clientPrivateKey)
|
||||
self.clientPublicKey = try container.decode(String.self, forKey: .clientPublicKey)
|
||||
self.serverPublicKey = try container.decode(String.self, forKey: .serverPublicKey)
|
||||
self.presharedKey = try container.decode(String.self, forKey: .presharedKey)
|
||||
self.allowedIPs = try container.decodeIfPresent([String].self, forKey: .allowedIPs) ?? ["0.0.0.0/0", "::/0"]
|
||||
self.persistentKeepAlive = try container.decodeIfPresent(String.self, forKey: .persistentKeepAlive) ?? "25"
|
||||
self.hostName = try container.decode(String.self, forKey: .hostName)
|
||||
self.port = try container.decode(Int.self, forKey: .port)
|
||||
}
|
||||
}
|
||||
|
||||
struct WGConfig: Decodable {
|
||||
let data: WGConfigData
|
||||
let configVersion: Int
|
||||
let description: String
|
||||
let dns1: String
|
||||
let dns2: String
|
||||
let hostName: String
|
||||
let `protocol`: String
|
||||
let splitTunnelSites: [String]
|
||||
let splitTunnelType: Int
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case awgConfigData = "awg_config_data", wgConfigData = "wireguard_config_data"
|
||||
case configData
|
||||
case configVersion = "config_version"
|
||||
case description
|
||||
case dns1
|
||||
case dns2
|
||||
case hostName
|
||||
case `protocol`
|
||||
case splitTunnelSites
|
||||
case splitTunnelType
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if container.contains(.awgConfigData) {
|
||||
self.data = try container.decode(WGConfigData.self, forKey: .awgConfigData)
|
||||
} else {
|
||||
self.data = try container.decode(WGConfigData.self, forKey: .wgConfigData)
|
||||
}
|
||||
|
||||
self.configVersion = try container.decode(Int.self, forKey: .configVersion)
|
||||
self.description = try container.decode(String.self, forKey: .description)
|
||||
self.dns1 = try container.decode(String.self, forKey: .dns1)
|
||||
self.dns2 = try container.decode(String.self, forKey: .dns2)
|
||||
self.hostName = try container.decode(String.self, forKey: .hostName)
|
||||
self.protocol = try container.decode(String.self, forKey: .protocol)
|
||||
self.splitTunnelSites = try container.decode([String].self, forKey: .splitTunnelSites)
|
||||
self.splitTunnelType = try container.decode(Int.self, forKey: .splitTunnelType)
|
||||
}
|
||||
|
||||
var wg: String {
|
||||
var str: String {
|
||||
"""
|
||||
[Interface]
|
||||
Address = \(data.clientIP)/32
|
||||
Address = \(clientIP)/32
|
||||
DNS = \(dns1), \(dns2)
|
||||
PrivateKey = \(data.clientPrivateKey)
|
||||
\(data.settings)
|
||||
MTU = \(mtu)
|
||||
PrivateKey = \(clientPrivateKey)
|
||||
\(settings)
|
||||
[Peer]
|
||||
PublicKey = \(data.serverPublicKey)
|
||||
PresharedKey = \(data.presharedKey)
|
||||
AllowedIPs = \(data.allowedIPs.joined(separator: ", "))
|
||||
Endpoint = \(data.hostName):\(data.port)
|
||||
PersistentKeepalive = \(data.persistentKeepAlive)
|
||||
PublicKey = \(serverPublicKey)
|
||||
PresharedKey = \(presharedKey)
|
||||
AllowedIPs = \(allowedIPs.joined(separator: ", "))
|
||||
Endpoint = \(hostName):\(port)
|
||||
PersistentKeepalive = \(persistentKeepAlive)
|
||||
"""
|
||||
}
|
||||
|
||||
var redux: String {
|
||||
"""
|
||||
[Interface]
|
||||
Address = \(clientIP)/32
|
||||
DNS = \(dns1), \(dns2)
|
||||
MTU = \(mtu)
|
||||
PrivateKey = ***
|
||||
\(settings)
|
||||
[Peer]
|
||||
PublicKey = ***
|
||||
PresharedKey = ***
|
||||
AllowedIPs = \(allowedIPs.joined(separator: ", "))
|
||||
Endpoint = \(hostName):\(port)
|
||||
PersistentKeepalive = \(persistentKeepAlive)
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
struct OpenVPNConfig: Decodable {
|
||||
let config: String
|
||||
let mtu: String
|
||||
let splitTunnelType: Int
|
||||
let splitTunnelSites: [String]
|
||||
|
||||
var str: String {
|
||||
"splitTunnelType: \(splitTunnelType) splitTunnelSites: \(splitTunnelSites) mtu: \(mtu) config: \(config)"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +357,16 @@ bool IosController::setupOpenVPN()
|
||||
QJsonObject ovpn = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::OpenVpn)].toObject();
|
||||
QString ovpnConfig = ovpn[config_key::config].toString();
|
||||
|
||||
return startOpenVPN(ovpnConfig);
|
||||
QJsonObject openVPNConfig {};
|
||||
openVPNConfig.insert(config_key::config, ovpnConfig);
|
||||
openVPNConfig.insert(config_key::mtu, m_rawConfig[config_key::mtu]);
|
||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||
openVPNConfig.insert(config_key::splitTunnelSites, m_rawConfig[config_key::splitTunnelSites]);
|
||||
|
||||
QJsonDocument openVPNConfigDoc(openVPNConfig);
|
||||
QString openVPNConfigStr(openVPNConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startOpenVPN(openVPNConfigStr);
|
||||
}
|
||||
|
||||
bool IosController::setupCloak()
|
||||
@@ -394,27 +403,100 @@ bool IosController::setupCloak()
|
||||
ovpnConfig.append(cloakBase64);
|
||||
ovpnConfig.append("\n</cloak>\n");
|
||||
|
||||
return startOpenVPN(ovpnConfig);
|
||||
QJsonObject openVPNConfig {};
|
||||
openVPNConfig.insert(config_key::config, ovpnConfig);
|
||||
openVPNConfig.insert(config_key::mtu, m_rawConfig[config_key::mtu]);
|
||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||
openVPNConfig.insert(config_key::splitTunnelSites, m_rawConfig[config_key::splitTunnelSites]);
|
||||
|
||||
QJsonDocument openVPNConfigDoc(openVPNConfig);
|
||||
QString openVPNConfigStr(openVPNConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startOpenVPN(openVPNConfigStr);
|
||||
}
|
||||
|
||||
bool IosController::setupWireGuard()
|
||||
{
|
||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::WireGuard)].toObject();
|
||||
|
||||
QJsonDocument doc(m_rawConfig);
|
||||
QString wgConfig(doc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startWireGuard(wgConfig);
|
||||
QJsonObject wgConfig {};
|
||||
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
||||
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
||||
wgConfig.insert(config_key::mtu, config[config_key::mtu]);
|
||||
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
||||
wgConfig.insert(config_key::port, config[config_key::port]);
|
||||
wgConfig.insert(config_key::client_ip, config[config_key::client_ip]);
|
||||
wgConfig.insert(config_key::client_priv_key, config[config_key::client_priv_key]);
|
||||
wgConfig.insert(config_key::server_pub_key, config[config_key::server_pub_key]);
|
||||
wgConfig.insert(config_key::psk_key, config[config_key::psk_key]);
|
||||
wgConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||
wgConfig.insert(config_key::splitTunnelSites, m_rawConfig[config_key::splitTunnelSites]);
|
||||
|
||||
if (config.contains(config_key::allowed_ips)) {
|
||||
wgConfig.insert(config_key::allowed_ips, config[config_key::allowed_ips]);
|
||||
} else {
|
||||
QJsonArray allowed_ips { "0.0.0.0/0", "::/0" };
|
||||
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
||||
}
|
||||
|
||||
if (config.contains(config_key::persistent_keep_alive)) {
|
||||
wgConfig.insert(config_key::persistent_keep_alive, config[config_key::persistent_keep_alive]);
|
||||
} else {
|
||||
wgConfig.insert(config_key::persistent_keep_alive, "25");
|
||||
}
|
||||
|
||||
QJsonDocument wgConfigDoc(wgConfig);
|
||||
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startWireGuard(wgConfigDocStr);
|
||||
}
|
||||
|
||||
bool IosController::setupAwg()
|
||||
{
|
||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::Awg)].toObject();
|
||||
|
||||
QJsonDocument doc(m_rawConfig);
|
||||
QString wgConfig(doc.toJson(QJsonDocument::Compact));
|
||||
QJsonObject wgConfig {};
|
||||
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
||||
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
||||
wgConfig.insert(config_key::mtu, config[config_key::mtu]);
|
||||
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
||||
wgConfig.insert(config_key::port, config[config_key::port]);
|
||||
wgConfig.insert(config_key::client_ip, config[config_key::client_ip]);
|
||||
wgConfig.insert(config_key::client_priv_key, config[config_key::client_priv_key]);
|
||||
wgConfig.insert(config_key::server_pub_key, config[config_key::server_pub_key]);
|
||||
wgConfig.insert(config_key::psk_key, config[config_key::psk_key]);
|
||||
wgConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||
wgConfig.insert(config_key::splitTunnelSites, m_rawConfig[config_key::splitTunnelSites]);
|
||||
|
||||
return startWireGuard(wgConfig);
|
||||
if (config.contains(config_key::allowed_ips)) {
|
||||
wgConfig.insert(config_key::allowed_ips, config[config_key::allowed_ips]);
|
||||
} else {
|
||||
QJsonArray allowed_ips { "0.0.0.0/0", "::/0" };
|
||||
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
||||
}
|
||||
|
||||
if (config.contains(config_key::persistent_keep_alive)) {
|
||||
wgConfig.insert(config_key::persistent_keep_alive, config[config_key::persistent_keep_alive]);
|
||||
} else {
|
||||
wgConfig.insert(config_key::persistent_keep_alive, "25");
|
||||
}
|
||||
|
||||
wgConfig.insert(config_key::initPacketMagicHeader, config[config_key::initPacketMagicHeader]);
|
||||
wgConfig.insert(config_key::responsePacketMagicHeader, config[config_key::responsePacketMagicHeader]);
|
||||
wgConfig.insert(config_key::underloadPacketMagicHeader, config[config_key::underloadPacketMagicHeader]);
|
||||
wgConfig.insert(config_key::transportPacketMagicHeader, config[config_key::transportPacketMagicHeader]);
|
||||
|
||||
wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]);
|
||||
wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]);
|
||||
|
||||
wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]);
|
||||
wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]);
|
||||
wgConfig.insert(config_key::junkPacketMaxSize, config[config_key::junkPacketMaxSize]);
|
||||
|
||||
QJsonDocument wgConfigDoc(wgConfig);
|
||||
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startWireGuard(wgConfigDocStr);
|
||||
}
|
||||
|
||||
bool IosController::startOpenVPN(const QString &config)
|
||||
@@ -499,7 +581,7 @@ void IosController::startTunnel()
|
||||
NSDictionary* message = @{actionKey: actionValue, tunnelIdKey: tunnelIdValue,
|
||||
SplitTunnelTypeKey: SplitTunnelTypeValue, SplitTunnelSitesKey: SplitTunnelSitesValue};
|
||||
|
||||
sendVpnExtensionMessage(message);
|
||||
// sendVpnExtensionMessage(message);
|
||||
|
||||
|
||||
BOOL started = [m_currentTunnel.connection startVPNTunnelWithOptions:nil andReturnError:&startError];
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace amnezia
|
||||
constexpr char psk_key[] = "psk_key";
|
||||
constexpr char mtu[] = "mtu";
|
||||
constexpr char allowed_ips[] = "allowed_ips";
|
||||
constexpr char persistent_keep_alive[] = "persistent_keep_alive";
|
||||
|
||||
constexpr char client_ip[] = "client_ip"; // internal ip address
|
||||
|
||||
|
||||
@@ -305,6 +305,11 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex, const ServerC
|
||||
// TODO: try to get hostName, port, description for 3rd party configs
|
||||
// vpnConfiguration[config_key::port] = ...;
|
||||
|
||||
#if defined Q_OS_IOS
|
||||
QJsonObject awg = server[config_key::containers].toArray().first().toObject()[config_key::awg].toObject();
|
||||
QString mtu = awg[config_key::mtu].toString(protocols::awg::defaultMtu);
|
||||
vpnConfiguration[config_key::mtu] = mtu;
|
||||
#endif
|
||||
return vpnConfiguration;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user