parent
9f82b4c21f
commit
e646b85e56
29 changed files with 512 additions and 56 deletions
|
@ -64,7 +64,7 @@ class Awg : Wireguard() {
|
||||||
val configDataJson = config.getJSONObject("awg_config_data")
|
val configDataJson = config.getJSONObject("awg_config_data")
|
||||||
val configData = parseConfigData(configDataJson.getString("config"))
|
val configData = parseConfigData(configDataJson.getString("config"))
|
||||||
return AwgConfig.build {
|
return AwgConfig.build {
|
||||||
configWireguard(configData)
|
configWireguard(configData, configDataJson)
|
||||||
configSplitTunneling(config)
|
configSplitTunneling(config)
|
||||||
configData["Jc"]?.let { setJc(it.toInt()) }
|
configData["Jc"]?.let { setJc(it.toInt()) }
|
||||||
configData["Jmin"]?.let { setJmin(it.toInt()) }
|
configData["Jmin"]?.let { setJmin(it.toInt()) }
|
||||||
|
|
|
@ -92,12 +92,12 @@ open class Wireguard : Protocol() {
|
||||||
val configDataJson = config.getJSONObject("wireguard_config_data")
|
val configDataJson = config.getJSONObject("wireguard_config_data")
|
||||||
val configData = parseConfigData(configDataJson.getString("config"))
|
val configData = parseConfigData(configDataJson.getString("config"))
|
||||||
return WireguardConfig.build {
|
return WireguardConfig.build {
|
||||||
configWireguard(configData)
|
configWireguard(configData, configDataJson)
|
||||||
configSplitTunneling(config)
|
configSplitTunneling(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun WireguardConfig.Builder.configWireguard(configData: Map<String, String>) {
|
protected fun WireguardConfig.Builder.configWireguard(configData: Map<String, String>, configDataJson: JSONObject) {
|
||||||
configData["Address"]?.split(",")?.map { address ->
|
configData["Address"]?.split(",")?.map { address ->
|
||||||
InetNetwork.parse(address.trim())
|
InetNetwork.parse(address.trim())
|
||||||
}?.forEach(::addAddress)
|
}?.forEach(::addAddress)
|
||||||
|
@ -118,7 +118,14 @@ open class Wireguard : Protocol() {
|
||||||
if (routes.any { it !in defRoutes }) disableSplitTunneling()
|
if (routes.any { it !in defRoutes }) disableSplitTunneling()
|
||||||
addRoutes(routes)
|
addRoutes(routes)
|
||||||
|
|
||||||
configData["MTU"]?.let { setMtu(it.toInt()) }
|
configDataJson.optString("mtu").let { mtu ->
|
||||||
|
if (mtu.isNotEmpty()) {
|
||||||
|
setMtu(mtu.toInt())
|
||||||
|
} else {
|
||||||
|
configData["MTU"]?.let { setMtu(it.toInt()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
configData["Endpoint"]?.let { setEndpoint(InetEndpoint.parse(it)) }
|
configData["Endpoint"]?.let { setEndpoint(InetEndpoint.parse(it)) }
|
||||||
configData["PersistentKeepalive"]?.let { setPersistentKeepalive(it.toInt()) }
|
configData["PersistentKeepalive"]?.let { setPersistentKeepalive(it.toInt()) }
|
||||||
configData["PrivateKey"]?.let { setPrivateKeyHex(it.base64ToHex()) }
|
configData["PrivateKey"]?.let { setPrivateKeyHex(it.base64ToHex()) }
|
||||||
|
|
|
@ -41,6 +41,8 @@ QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials, Dock
|
||||||
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
||||||
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
||||||
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
jsonConfig[config_key::mtu] = containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().
|
||||||
|
value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
||||||
|
|
||||||
return QJsonDocument(jsonConfig).toJson();
|
return QJsonDocument(jsonConfig).toJson();
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,7 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
||||||
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
|
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
|
||||||
config.replace("$WIREGUARD_PSK", connData.pskKey);
|
config.replace("$WIREGUARD_PSK", connData.pskKey);
|
||||||
|
|
||||||
|
const QJsonObject &wireguarConfig = containerConfig.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
||||||
QJsonObject jConfig;
|
QJsonObject jConfig;
|
||||||
jConfig[config_key::config] = config;
|
jConfig[config_key::config] = config;
|
||||||
|
|
||||||
|
@ -205,6 +206,8 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
||||||
jConfig[config_key::psk_key] = connData.pskKey;
|
jConfig[config_key::psk_key] = connData.pskKey;
|
||||||
jConfig[config_key::server_pub_key] = connData.serverPubKey;
|
jConfig[config_key::server_pub_key] = connData.serverPubKey;
|
||||||
|
|
||||||
|
jConfig[config_key::mtu] = wireguarConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
|
||||||
|
|
||||||
clientId = connData.clientPubKey;
|
clientId = connData.clientPubKey;
|
||||||
|
|
||||||
return QJsonDocument(jConfig).toJson();
|
return QJsonDocument(jConfig).toJson();
|
||||||
|
|
|
@ -359,7 +359,33 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::Awg) {
|
if (container == DockerContainer::Awg) {
|
||||||
return true;
|
if ((oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
|
||||||
|
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
|
||||||
|
|| (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)
|
||||||
|
!= newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount))
|
||||||
|
|| (oldProtoConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize)
|
||||||
|
!= newProtoConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize))
|
||||||
|
|| (oldProtoConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize)
|
||||||
|
!= newProtoConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize))
|
||||||
|
|| (oldProtoConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize)
|
||||||
|
!= newProtoConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize))
|
||||||
|
|| (oldProtoConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize)
|
||||||
|
!= newProtoConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize))
|
||||||
|
|| (oldProtoConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader)
|
||||||
|
!= newProtoConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader))
|
||||||
|
|| (oldProtoConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader)
|
||||||
|
!= newProtoConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader))
|
||||||
|
|| (oldProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader)
|
||||||
|
!= newProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader))
|
||||||
|
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)
|
||||||
|
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::WireGuard){
|
||||||
|
if (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
||||||
|
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -251,6 +251,19 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||||
GETVALUE("serverPskKey", config.m_serverPskKey, String);
|
GETVALUE("serverPskKey", config.m_serverPskKey, String);
|
||||||
GETVALUE("serverPort", config.m_serverPort, Double);
|
GETVALUE("serverPort", config.m_serverPort, Double);
|
||||||
|
|
||||||
|
if (!obj.contains("deviceMTU") || obj.value("deviceMTU").toString().toInt() == 0)
|
||||||
|
{
|
||||||
|
config.m_deviceMTU = 1420;
|
||||||
|
} else {
|
||||||
|
config.m_deviceMTU = obj.value("deviceMTU").toString().toInt();
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
// For Windows min MTU value is 1280 (the smallest MTU legal with IPv6).
|
||||||
|
if (config.m_deviceMTU < 1280) {
|
||||||
|
config.m_deviceMTU = 1280;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
config.m_deviceIpv4Address = obj.value("deviceIpv4Address").toString();
|
config.m_deviceIpv4Address = obj.value("deviceIpv4Address").toString();
|
||||||
config.m_deviceIpv6Address = obj.value("deviceIpv6Address").toString();
|
config.m_deviceIpv6Address = obj.value("deviceIpv6Address").toString();
|
||||||
if (config.m_deviceIpv4Address.isNull() &&
|
if (config.m_deviceIpv4Address.isNull() &&
|
||||||
|
|
|
@ -23,6 +23,7 @@ QJsonObject InterfaceConfig::toJson() const {
|
||||||
json.insert("serverIpv4AddrIn", QJsonValue(m_serverIpv4AddrIn));
|
json.insert("serverIpv4AddrIn", QJsonValue(m_serverIpv4AddrIn));
|
||||||
json.insert("serverIpv6AddrIn", QJsonValue(m_serverIpv6AddrIn));
|
json.insert("serverIpv6AddrIn", QJsonValue(m_serverIpv6AddrIn));
|
||||||
json.insert("serverPort", QJsonValue((double)m_serverPort));
|
json.insert("serverPort", QJsonValue((double)m_serverPort));
|
||||||
|
json.insert("deviceMTU", QJsonValue(m_deviceMTU));
|
||||||
if ((m_hopType == InterfaceConfig::MultiHopExit) ||
|
if ((m_hopType == InterfaceConfig::MultiHopExit) ||
|
||||||
(m_hopType == InterfaceConfig::SingleHop)) {
|
(m_hopType == InterfaceConfig::SingleHop)) {
|
||||||
json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway));
|
json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway));
|
||||||
|
@ -85,8 +86,13 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||||
if (addresses.isEmpty()) {
|
if (addresses.isEmpty()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "Address = " << addresses.join(", ") << "\n";
|
out << "Address = " << addresses.join(", ") << "\n";
|
||||||
|
|
||||||
|
if (m_deviceMTU) {
|
||||||
|
out << "MTU = " << m_deviceMTU << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_dnsServer.isNull()) {
|
if (!m_dnsServer.isNull()) {
|
||||||
QStringList dnsServers(m_dnsServer);
|
QStringList dnsServers(m_dnsServer);
|
||||||
// If the DNS is not the Gateway, it's a user defined DNS
|
// If the DNS is not the Gateway, it's a user defined DNS
|
||||||
|
|
|
@ -33,6 +33,7 @@ class InterfaceConfig {
|
||||||
QString m_serverIpv6AddrIn;
|
QString m_serverIpv6AddrIn;
|
||||||
QString m_dnsServer;
|
QString m_dnsServer;
|
||||||
int m_serverPort = 0;
|
int m_serverPort = 0;
|
||||||
|
int m_deviceMTU = 1420;
|
||||||
QList<IPAddress> m_allowedIPAddressRanges;
|
QList<IPAddress> m_allowedIPAddressRanges;
|
||||||
QStringList m_excludedAddresses;
|
QStringList m_excludedAddresses;
|
||||||
QStringList m_vpnDisabledApps;
|
QStringList m_vpnDisabledApps;
|
||||||
|
|
|
@ -132,8 +132,9 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
|
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
|
||||||
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
|
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
|
||||||
// json.insert("serverIpv6AddrIn", QJsonValue(hop.m_server.ipv6AddrIn()));
|
// json.insert("serverIpv6AddrIn", QJsonValue(hop.m_server.ipv6AddrIn()));
|
||||||
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
|
json.insert("deviceMTU", wgConfig.value(amnezia::config_key::mtu));
|
||||||
|
|
||||||
|
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
|
||||||
json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName));
|
json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName));
|
||||||
// json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway()));
|
// json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway()));
|
||||||
json.insert("dnsServer", rawConfig.value(amnezia::config_key::dns1));
|
json.insert("dnsServer", rawConfig.value(amnezia::config_key::dns1));
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct Log {
|
||||||
init(_ str: String) {
|
init(_ str: String) {
|
||||||
self.records = str.split(whereSeparator: \.isNewline)
|
self.records = str.split(whereSeparator: \.isNewline)
|
||||||
.compactMap {
|
.compactMap {
|
||||||
Record(String($0))!
|
Record(String($0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ struct WGConfig: Decodable {
|
||||||
let initPacketJunkSize, responsePacketJunkSize: String?
|
let initPacketJunkSize, responsePacketJunkSize: String?
|
||||||
let dns1: String
|
let dns1: String
|
||||||
let dns2: String
|
let dns2: String
|
||||||
|
let mtu: String
|
||||||
let hostName: String
|
let hostName: String
|
||||||
let port: Int
|
let port: Int
|
||||||
let clientIP: String
|
let clientIP: String
|
||||||
|
@ -25,6 +26,7 @@ struct WGConfig: Decodable {
|
||||||
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2"
|
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2"
|
||||||
case dns1
|
case dns1
|
||||||
case dns2
|
case dns2
|
||||||
|
case mtu
|
||||||
case hostName
|
case hostName
|
||||||
case port
|
case port
|
||||||
case clientIP = "client_ip"
|
case clientIP = "client_ip"
|
||||||
|
@ -58,6 +60,7 @@ struct WGConfig: Decodable {
|
||||||
[Interface]
|
[Interface]
|
||||||
Address = \(clientIP)
|
Address = \(clientIP)
|
||||||
DNS = \(dns1), \(dns2)
|
DNS = \(dns1), \(dns2)
|
||||||
|
MTU = \(mtu)
|
||||||
PrivateKey = \(clientPrivateKey)
|
PrivateKey = \(clientPrivateKey)
|
||||||
\(settings)
|
\(settings)
|
||||||
[Peer]
|
[Peer]
|
||||||
|
@ -74,6 +77,7 @@ struct WGConfig: Decodable {
|
||||||
[Interface]
|
[Interface]
|
||||||
Address = \(clientIP)
|
Address = \(clientIP)
|
||||||
DNS = \(dns1), \(dns2)
|
DNS = \(dns1), \(dns2)
|
||||||
|
MTU = \(mtu)
|
||||||
PrivateKey = ***
|
PrivateKey = ***
|
||||||
\(settings)
|
\(settings)
|
||||||
[Peer]
|
[Peer]
|
||||||
|
@ -88,10 +92,11 @@ struct WGConfig: Decodable {
|
||||||
|
|
||||||
struct OpenVPNConfig: Decodable {
|
struct OpenVPNConfig: Decodable {
|
||||||
let config: String
|
let config: String
|
||||||
|
let mtu: String
|
||||||
let splitTunnelType: Int
|
let splitTunnelType: Int
|
||||||
let splitTunnelSites: [String]
|
let splitTunnelSites: [String]
|
||||||
|
|
||||||
var str: String {
|
var str: String {
|
||||||
"splitTunnelType: \(splitTunnelType) splitTunnelSites: \(splitTunnelSites) config: \(config)"
|
"splitTunnelType: \(splitTunnelType) splitTunnelSites: \(splitTunnelSites) mtu: \(mtu) config: \(config)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,6 +358,13 @@ bool IosController::setupOpenVPN()
|
||||||
|
|
||||||
QJsonObject openVPNConfig {};
|
QJsonObject openVPNConfig {};
|
||||||
openVPNConfig.insert(config_key::config, ovpnConfig);
|
openVPNConfig.insert(config_key::config, ovpnConfig);
|
||||||
|
|
||||||
|
if (ovpn.contains(config_key::mtu)) {
|
||||||
|
openVPNConfig.insert(config_key::mtu, ovpn[config_key::mtu]);
|
||||||
|
} else {
|
||||||
|
openVPNConfig.insert(config_key::mtu, protocols::openvpn::defaultMtu);
|
||||||
|
}
|
||||||
|
|
||||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
||||||
|
|
||||||
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
||||||
|
@ -410,7 +417,12 @@ bool IosController::setupCloak()
|
||||||
|
|
||||||
QJsonObject openVPNConfig {};
|
QJsonObject openVPNConfig {};
|
||||||
openVPNConfig.insert(config_key::config, ovpnConfig);
|
openVPNConfig.insert(config_key::config, ovpnConfig);
|
||||||
openVPNConfig.insert(config_key::splitTunnelType, m_rawConfig[config_key::splitTunnelType]);
|
|
||||||
|
if (ovpn.contains(config_key::mtu)) {
|
||||||
|
openVPNConfig.insert(config_key::mtu, ovpn[config_key::mtu]);
|
||||||
|
} else {
|
||||||
|
openVPNConfig.insert(config_key::mtu, protocols::openvpn::defaultMtu);
|
||||||
|
}
|
||||||
|
|
||||||
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
QJsonArray splitTunnelSites = m_rawConfig[config_key::splitTunnelSites].toArray();
|
||||||
|
|
||||||
|
@ -433,6 +445,13 @@ bool IosController::setupWireGuard()
|
||||||
QJsonObject wgConfig {};
|
QJsonObject wgConfig {};
|
||||||
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
||||||
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
||||||
|
|
||||||
|
if (config.contains(config_key::mtu)) {
|
||||||
|
wgConfig.insert(config_key::mtu, config[config_key::mtu]);
|
||||||
|
} else {
|
||||||
|
wgConfig.insert(config_key::mtu, protocols::wireguard::defaultMtu);
|
||||||
|
}
|
||||||
|
|
||||||
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
||||||
wgConfig.insert(config_key::port, config[config_key::port]);
|
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_ip, config[config_key::client_ip]);
|
||||||
|
@ -456,7 +475,11 @@ bool IosController::setupWireGuard()
|
||||||
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
||||||
}
|
}
|
||||||
|
|
||||||
wgConfig.insert("persistent_keep_alive", "25");
|
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);
|
QJsonDocument wgConfigDoc(wgConfig);
|
||||||
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
||||||
|
@ -471,6 +494,13 @@ bool IosController::setupAwg()
|
||||||
QJsonObject wgConfig {};
|
QJsonObject wgConfig {};
|
||||||
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
wgConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
||||||
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
wgConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
||||||
|
|
||||||
|
if (config.contains(config_key::mtu)) {
|
||||||
|
wgConfig.insert(config_key::mtu, config[config_key::mtu]);
|
||||||
|
} else {
|
||||||
|
wgConfig.insert(config_key::mtu, protocols::awg::defaultMtu);
|
||||||
|
}
|
||||||
|
|
||||||
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
wgConfig.insert(config_key::hostName, config[config_key::hostName]);
|
||||||
wgConfig.insert(config_key::port, config[config_key::port]);
|
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_ip, config[config_key::client_ip]);
|
||||||
|
@ -494,7 +524,12 @@ bool IosController::setupAwg()
|
||||||
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
wgConfig.insert(config_key::allowed_ips, allowed_ips);
|
||||||
}
|
}
|
||||||
|
|
||||||
wgConfig.insert("persistent_keep_alive", "25");
|
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::initPacketMagicHeader, config[config_key::initPacketMagicHeader]);
|
||||||
wgConfig.insert(config_key::responsePacketMagicHeader, config[config_key::responsePacketMagicHeader]);
|
wgConfig.insert(config_key::responsePacketMagicHeader, config[config_key::responsePacketMagicHeader]);
|
||||||
wgConfig.insert(config_key::underloadPacketMagicHeader, config[config_key::underloadPacketMagicHeader]);
|
wgConfig.insert(config_key::underloadPacketMagicHeader, config[config_key::underloadPacketMagicHeader]);
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
#include "leakdetector.h"
|
#include "leakdetector.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
constexpr uint32_t ETH_MTU = 1500;
|
|
||||||
constexpr uint32_t WG_MTU_OVERHEAD = 80;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Logger logger("IPUtilsLinux");
|
Logger logger("IPUtilsLinux");
|
||||||
}
|
}
|
||||||
|
@ -38,8 +35,6 @@ bool IPUtilsLinux::addInterfaceIPs(const InterfaceConfig& config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
||||||
Q_UNUSED(config);
|
|
||||||
|
|
||||||
// Create socket file descriptor to perform the ioctl operations on
|
// Create socket file descriptor to perform the ioctl operations on
|
||||||
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||||
if (sockfd < 0) {
|
if (sockfd < 0) {
|
||||||
|
@ -56,10 +51,10 @@ bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
||||||
// FIXME: We need to know how many layers deep this particular
|
// FIXME: We need to know how many layers deep this particular
|
||||||
// interface is into a tunnel to work effectively. Otherwise
|
// interface is into a tunnel to work effectively. Otherwise
|
||||||
// we will run into fragmentation issues.
|
// we will run into fragmentation issues.
|
||||||
ifr.ifr_mtu = ETH_MTU - WG_MTU_OVERHEAD;
|
ifr.ifr_mtu = config.m_deviceMTU;
|
||||||
int ret = ioctl(sockfd, SIOCSIFMTU, &ifr);
|
int ret = ioctl(sockfd, SIOCSIFMTU, &ifr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
logger.error() << "Failed to set MTU -- Return code: " << ret;
|
logger.error() << "Failed to set MTU -- " << config.m_deviceMTU << " -- Return code: " << ret;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,6 @@
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "macosdaemon.h"
|
#include "macosdaemon.h"
|
||||||
|
|
||||||
constexpr uint32_t ETH_MTU = 1500;
|
|
||||||
constexpr uint32_t WG_MTU_OVERHEAD = 80;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Logger logger("IPUtilsMacos");
|
Logger logger("IPUtilsMacos");
|
||||||
}
|
}
|
||||||
|
@ -56,10 +53,10 @@ bool IPUtilsMacos::setMTUAndUp(const InterfaceConfig& config) {
|
||||||
|
|
||||||
// MTU
|
// MTU
|
||||||
strncpy(ifr.ifr_name, qPrintable(ifname), IFNAMSIZ);
|
strncpy(ifr.ifr_name, qPrintable(ifname), IFNAMSIZ);
|
||||||
ifr.ifr_mtu = ETH_MTU - WG_MTU_OVERHEAD;
|
ifr.ifr_mtu = config.m_deviceMTU;
|
||||||
int ret = ioctl(sockfd, SIOCSIFMTU, &ifr);
|
int ret = ioctl(sockfd, SIOCSIFMTU, &ifr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
logger.error() << "Failed to set MTU:" << strerror(errno);
|
logger.error() << "Failed to set MTU -- " << config.m_deviceMTU << " -- Return code: " << ret;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,9 @@ namespace amnezia
|
||||||
constexpr char server_priv_key[] = "server_priv_key";
|
constexpr char server_priv_key[] = "server_priv_key";
|
||||||
constexpr char server_pub_key[] = "server_pub_key";
|
constexpr char server_pub_key[] = "server_pub_key";
|
||||||
constexpr char psk_key[] = "psk_key";
|
constexpr char psk_key[] = "psk_key";
|
||||||
|
constexpr char mtu[] = "mtu";
|
||||||
constexpr char allowed_ips[] = "allowed_ips";
|
constexpr char allowed_ips[] = "allowed_ips";
|
||||||
|
constexpr char persistent_keep_alive[] = "persistent_keep_alive";
|
||||||
|
|
||||||
constexpr char client_ip[] = "client_ip"; // internal ip address
|
constexpr char client_ip[] = "client_ip"; // internal ip address
|
||||||
|
|
||||||
|
@ -103,6 +105,7 @@ namespace amnezia
|
||||||
constexpr char defaultSubnetAddress[] = "10.8.0.0";
|
constexpr char defaultSubnetAddress[] = "10.8.0.0";
|
||||||
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
constexpr char defaultSubnetMask[] = "255.255.255.0";
|
||||||
constexpr char defaultSubnetCidr[] = "24";
|
constexpr char defaultSubnetCidr[] = "24";
|
||||||
|
constexpr char defaultMtu[] = "1500";
|
||||||
|
|
||||||
constexpr char serverConfigPath[] = "/opt/amnezia/openvpn/server.conf";
|
constexpr char serverConfigPath[] = "/opt/amnezia/openvpn/server.conf";
|
||||||
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
constexpr char caCertPath[] = "/opt/amnezia/openvpn/pki/ca.crt";
|
||||||
|
@ -149,6 +152,7 @@ namespace amnezia
|
||||||
constexpr char defaultSubnetCidr[] = "24";
|
constexpr char defaultSubnetCidr[] = "24";
|
||||||
|
|
||||||
constexpr char defaultPort[] = "51820";
|
constexpr char defaultPort[] = "51820";
|
||||||
|
constexpr char defaultMtu[] = "1420";
|
||||||
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
|
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
|
||||||
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
|
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
|
||||||
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
|
||||||
|
@ -164,6 +168,7 @@ namespace amnezia
|
||||||
namespace awg
|
namespace awg
|
||||||
{
|
{
|
||||||
constexpr char defaultPort[] = "55424";
|
constexpr char defaultPort[] = "55424";
|
||||||
|
constexpr char defaultMtu[] = "1420";
|
||||||
|
|
||||||
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf";
|
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf";
|
||||||
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
|
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
|
||||||
|
|
|
@ -224,6 +224,7 @@
|
||||||
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
|
||||||
<file>images/controls/close.svg</file>
|
<file>images/controls/close.svg</file>
|
||||||
<file>images/controls/search.svg</file>
|
<file>images/controls/search.svg</file>
|
||||||
|
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
|
||||||
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
|
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
|
||||||
<file>images/controls/split-tunneling.svg</file>
|
<file>images/controls/split-tunneling.svg</file>
|
||||||
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
<file>ui/qml/Controls2/DrawerType2.qml</file>
|
||||||
|
|
|
@ -286,6 +286,10 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!configMap.value("MTU").isEmpty()) {
|
||||||
|
lastConfig[config_key::mtu] = configMap.value("MTU");
|
||||||
|
}
|
||||||
|
|
||||||
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
|
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
|
||||||
|
|
||||||
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -273,12 +275,16 @@ void InstallController::updateContainer(QJsonObject config)
|
||||||
|
|
||||||
const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
const DockerContainer container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||||
QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container);
|
QJsonObject oldContainerConfig = m_containersModel->getContainerConfig(container);
|
||||||
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
ServerController serverController(m_settings);
|
if (isUpdateDockerContainerRequired(container, oldContainerConfig, config)) {
|
||||||
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
ServerController serverController(m_settings);
|
||||||
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
connect(&serverController, &ServerController::serverIsBusy, this, &InstallController::serverIsBusy);
|
||||||
|
connect(this, &InstallController::cancelInstallation, &serverController, &ServerController::cancelInstallation);
|
||||||
|
|
||||||
|
errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
||||||
|
}
|
||||||
|
|
||||||
auto errorCode = serverController.updateContainer(serverCredentials, container, oldContainerConfig, config);
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
m_serversModel->updateContainerConfig(container, config);
|
m_serversModel->updateContainerConfig(container, config);
|
||||||
m_protocolModel->updateModel(config);
|
m_protocolModel->updateModel(config);
|
||||||
|
@ -514,3 +520,29 @@ void InstallController::addEmptyServer()
|
||||||
|
|
||||||
emit installServerFinished(tr("Server added successfully"));
|
emit installServerFinished(tr("Server added successfully"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
|
||||||
|
{
|
||||||
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
|
const QJsonObject &oldProtoConfig = oldConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||||
|
const QJsonObject &newProtoConfig = newConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||||
|
|
||||||
|
if (container == DockerContainer::Awg) {
|
||||||
|
const AwgConfig oldConfig(oldProtoConfig);
|
||||||
|
const AwgConfig newConfig(newProtoConfig);
|
||||||
|
|
||||||
|
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (container == DockerContainer::WireGuard) {
|
||||||
|
const WgConfig oldConfig(oldProtoConfig);
|
||||||
|
const WgConfig newConfig(newProtoConfig);
|
||||||
|
|
||||||
|
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -76,6 +76,8 @@ private:
|
||||||
void installContainer(DockerContainer container, QJsonObject &config);
|
void installContainer(DockerContainer container, QJsonObject &config);
|
||||||
bool isServerAlreadyExists();
|
bool isServerAlreadyExists();
|
||||||
|
|
||||||
|
bool isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
|
||||||
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ProtocolsModel> m_protocolModel;
|
QSharedPointer<ProtocolsModel> m_protocolModel;
|
||||||
|
|
|
@ -22,6 +22,7 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||||
|
case Roles::MtuRole: m_protocolConfig.insert(config_key::mtu, value.toString()); break;
|
||||||
case Roles::JunkPacketCountRole: m_protocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
case Roles::JunkPacketCountRole: m_protocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
||||||
case Roles::JunkPacketMinSizeRole: m_protocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
case Roles::JunkPacketMinSizeRole: m_protocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
||||||
case Roles::JunkPacketMaxSizeRole: m_protocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
case Roles::JunkPacketMaxSizeRole: m_protocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
||||||
|
@ -57,6 +58,7 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
||||||
|
case Roles::MtuRole: return m_protocolConfig.value(config_key::mtu).toString();
|
||||||
case Roles::JunkPacketCountRole: return m_protocolConfig.value(config_key::junkPacketCount);
|
case Roles::JunkPacketCountRole: return m_protocolConfig.value(config_key::junkPacketCount);
|
||||||
case Roles::JunkPacketMinSizeRole: return m_protocolConfig.value(config_key::junkPacketMinSize);
|
case Roles::JunkPacketMinSizeRole: return m_protocolConfig.value(config_key::junkPacketMinSize);
|
||||||
case Roles::JunkPacketMaxSizeRole: return m_protocolConfig.value(config_key::junkPacketMaxSize);
|
case Roles::JunkPacketMaxSizeRole: return m_protocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
|
@ -80,25 +82,21 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
|
|
||||||
QJsonObject protocolConfig = config.value(config_key::awg).toObject();
|
QJsonObject protocolConfig = config.value(config_key::awg).toObject();
|
||||||
|
|
||||||
m_protocolConfig[config_key::port] =
|
m_protocolConfig[config_key::last_config] = protocolConfig.value(config_key::last_config);
|
||||||
protocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
m_protocolConfig[config_key::port] = protocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||||
|
m_protocolConfig[config_key::mtu] = protocolConfig.value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
||||||
m_protocolConfig[config_key::junkPacketCount] =
|
m_protocolConfig[config_key::junkPacketCount] =
|
||||||
protocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
protocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||||
m_protocolConfig[config_key::junkPacketMinSize] =
|
m_protocolConfig[config_key::junkPacketMinSize] =
|
||||||
protocolConfig.value(config_key::junkPacketMinSize)
|
protocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
||||||
.toString(protocols::awg::defaultJunkPacketMinSize);
|
|
||||||
m_protocolConfig[config_key::junkPacketMaxSize] =
|
m_protocolConfig[config_key::junkPacketMaxSize] =
|
||||||
protocolConfig.value(config_key::junkPacketMaxSize)
|
protocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
|
||||||
.toString(protocols::awg::defaultJunkPacketMaxSize);
|
|
||||||
m_protocolConfig[config_key::initPacketJunkSize] =
|
m_protocolConfig[config_key::initPacketJunkSize] =
|
||||||
protocolConfig.value(config_key::initPacketJunkSize)
|
protocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
||||||
.toString(protocols::awg::defaultInitPacketJunkSize);
|
|
||||||
m_protocolConfig[config_key::responsePacketJunkSize] =
|
m_protocolConfig[config_key::responsePacketJunkSize] =
|
||||||
protocolConfig.value(config_key::responsePacketJunkSize)
|
protocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||||
.toString(protocols::awg::defaultResponsePacketJunkSize);
|
|
||||||
m_protocolConfig[config_key::initPacketMagicHeader] =
|
m_protocolConfig[config_key::initPacketMagicHeader] =
|
||||||
protocolConfig.value(config_key::initPacketMagicHeader)
|
protocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||||
.toString(protocols::awg::defaultInitPacketMagicHeader);
|
|
||||||
m_protocolConfig[config_key::responsePacketMagicHeader] =
|
m_protocolConfig[config_key::responsePacketMagicHeader] =
|
||||||
protocolConfig.value(config_key::responsePacketMagicHeader)
|
protocolConfig.value(config_key::responsePacketMagicHeader)
|
||||||
.toString(protocols::awg::defaultResponsePacketMagicHeader);
|
.toString(protocols::awg::defaultResponsePacketMagicHeader);
|
||||||
|
@ -114,6 +112,19 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
|
|
||||||
QJsonObject AwgConfigModel::getConfig()
|
QJsonObject AwgConfigModel::getConfig()
|
||||||
{
|
{
|
||||||
|
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
|
||||||
|
const AwgConfig newConfig(m_protocolConfig);
|
||||||
|
|
||||||
|
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
|
m_protocolConfig.remove(config_key::last_config);
|
||||||
|
} else {
|
||||||
|
auto lastConfig = m_protocolConfig.value(config_key::last_config).toString();
|
||||||
|
QJsonObject jsonConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
|
||||||
|
jsonConfig[config_key::mtu] = newConfig.mtu;
|
||||||
|
|
||||||
|
m_protocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
m_fullConfig.insert(config_key::awg, m_protocolConfig);
|
m_fullConfig.insert(config_key::awg, m_protocolConfig);
|
||||||
return m_fullConfig;
|
return m_fullConfig;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +134,7 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
roles[PortRole] = "port";
|
roles[PortRole] = "port";
|
||||||
|
roles[MtuRole] = "mtu";
|
||||||
roles[JunkPacketCountRole] = "junkPacketCount";
|
roles[JunkPacketCountRole] = "junkPacketCount";
|
||||||
roles[JunkPacketMinSizeRole] = "junkPacketMinSize";
|
roles[JunkPacketMinSizeRole] = "junkPacketMinSize";
|
||||||
roles[JunkPacketMaxSizeRole] = "junkPacketMaxSize";
|
roles[JunkPacketMaxSizeRole] = "junkPacketMaxSize";
|
||||||
|
@ -135,3 +147,47 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AwgConfig::AwgConfig(const QJsonObject &jsonConfig)
|
||||||
|
{
|
||||||
|
port = jsonConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||||
|
mtu = jsonConfig.value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
||||||
|
junkPacketCount = jsonConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||||
|
junkPacketMinSize =
|
||||||
|
jsonConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
||||||
|
junkPacketMaxSize =
|
||||||
|
jsonConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
|
||||||
|
initPacketJunkSize =
|
||||||
|
jsonConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
||||||
|
responsePacketJunkSize =
|
||||||
|
jsonConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||||
|
initPacketMagicHeader =
|
||||||
|
jsonConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||||
|
responsePacketMagicHeader = jsonConfig.value(config_key::responsePacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultResponsePacketMagicHeader);
|
||||||
|
underloadPacketMagicHeader = jsonConfig.value(config_key::underloadPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultUnderloadPacketMagicHeader);
|
||||||
|
transportPacketMagicHeader = jsonConfig.value(config_key::transportPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultTransportPacketMagicHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
|
||||||
|
{
|
||||||
|
if (port != other.port || junkPacketCount != other.junkPacketCount || junkPacketMinSize != other.junkPacketMinSize
|
||||||
|
|| junkPacketMaxSize != other.junkPacketMaxSize || initPacketJunkSize != other.initPacketJunkSize
|
||||||
|
|| responsePacketJunkSize != other.responsePacketJunkSize || initPacketMagicHeader != other.initPacketMagicHeader
|
||||||
|
|| responsePacketMagicHeader != other.responsePacketMagicHeader
|
||||||
|
|| underloadPacketMagicHeader != other.underloadPacketMagicHeader
|
||||||
|
|| transportPacketMagicHeader != other.transportPacketMagicHeader) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwgConfig::hasEqualClientSettings(const AwgConfig &other) const
|
||||||
|
{
|
||||||
|
if (mtu != other.mtu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,27 @@
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
|
struct AwgConfig
|
||||||
|
{
|
||||||
|
AwgConfig(const QJsonObject &jsonConfig);
|
||||||
|
|
||||||
|
QString port;
|
||||||
|
QString mtu;
|
||||||
|
QString junkPacketCount;
|
||||||
|
QString junkPacketMinSize;
|
||||||
|
QString junkPacketMaxSize;
|
||||||
|
QString initPacketJunkSize;
|
||||||
|
QString responsePacketJunkSize;
|
||||||
|
QString initPacketMagicHeader;
|
||||||
|
QString responsePacketMagicHeader;
|
||||||
|
QString underloadPacketMagicHeader;
|
||||||
|
QString transportPacketMagicHeader;
|
||||||
|
|
||||||
|
bool hasEqualServerSettings(const AwgConfig &other) const;
|
||||||
|
bool hasEqualClientSettings(const AwgConfig &other) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class AwgConfigModel : public QAbstractListModel
|
class AwgConfigModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -13,6 +34,7 @@ class AwgConfigModel : public QAbstractListModel
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
PortRole = Qt::UserRole + 1,
|
PortRole = Qt::UserRole + 1,
|
||||||
|
MtuRole,
|
||||||
JunkPacketCountRole,
|
JunkPacketCountRole,
|
||||||
JunkPacketMinSizeRole,
|
JunkPacketMinSizeRole,
|
||||||
JunkPacketMaxSizeRole,
|
JunkPacketMaxSizeRole,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "wireguardConfigModel.h"
|
#include "wireguardConfigModel.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
#include "protocols/protocols_defs.h"
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
||||||
WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent)
|
WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
@ -19,8 +21,8 @@ bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &val
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||||
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
|
case Roles::MtuRole: m_protocolConfig.insert(config_key::mtu, value.toString()); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(index, index, QList { role });
|
emit dataChanged(index, index, QList { role });
|
||||||
|
@ -34,9 +36,8 @@ QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
|
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
||||||
case Roles::CipherRole:
|
case Roles::MtuRole: return m_protocolConfig.value(config_key::mtu).toString();
|
||||||
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -50,11 +51,31 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
|
||||||
m_fullConfig = config;
|
m_fullConfig = config;
|
||||||
QJsonObject protocolConfig = config.value(config_key::wireguard).toObject();
|
QJsonObject protocolConfig = config.value(config_key::wireguard).toObject();
|
||||||
|
|
||||||
|
m_protocolConfig[config_key::last_config] = protocolConfig.value(config_key::last_config);
|
||||||
|
m_protocolConfig[config_key::port] =
|
||||||
|
protocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||||
|
|
||||||
|
m_protocolConfig[config_key::mtu] =
|
||||||
|
protocolConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject WireGuardConfigModel::getConfig()
|
QJsonObject WireGuardConfigModel::getConfig()
|
||||||
{
|
{
|
||||||
|
const WgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
|
||||||
|
const WgConfig newConfig(m_protocolConfig);
|
||||||
|
|
||||||
|
if (!oldConfig.hasEqualServerSettings(newConfig)) {
|
||||||
|
m_protocolConfig.remove(config_key::last_config);
|
||||||
|
} else {
|
||||||
|
auto lastConfig = m_protocolConfig.value(config_key::last_config).toString();
|
||||||
|
QJsonObject jsonConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
|
||||||
|
jsonConfig[config_key::mtu] = newConfig.mtu;
|
||||||
|
|
||||||
|
m_protocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
m_fullConfig.insert(config_key::wireguard, m_protocolConfig);
|
m_fullConfig.insert(config_key::wireguard, m_protocolConfig);
|
||||||
return m_fullConfig;
|
return m_fullConfig;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +85,29 @@ QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
roles[PortRole] = "port";
|
roles[PortRole] = "port";
|
||||||
roles[CipherRole] = "cipher";
|
roles[MtuRole] = "mtu";
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WgConfig::WgConfig(const QJsonObject &jsonConfig)
|
||||||
|
{
|
||||||
|
port = jsonConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
||||||
|
mtu = jsonConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WgConfig::hasEqualServerSettings(const WgConfig &other) const
|
||||||
|
{
|
||||||
|
if (port != other.port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WgConfig::hasEqualClientSettings(const WgConfig &other) const
|
||||||
|
{
|
||||||
|
if (mtu != other.mtu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,18 @@
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
|
struct WgConfig
|
||||||
|
{
|
||||||
|
WgConfig(const QJsonObject &jsonConfig);
|
||||||
|
|
||||||
|
QString port;
|
||||||
|
QString mtu;
|
||||||
|
|
||||||
|
bool hasEqualServerSettings(const WgConfig &other) const;
|
||||||
|
bool hasEqualClientSettings(const WgConfig &other) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class WireGuardConfigModel : public QAbstractListModel
|
class WireGuardConfigModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -13,7 +25,7 @@ class WireGuardConfigModel : public QAbstractListModel
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
PortRole = Qt::UserRole + 1,
|
PortRole = Qt::UserRole + 1,
|
||||||
CipherRole
|
MtuRole
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit WireGuardConfigModel(QObject *parent = nullptr);
|
explicit WireGuardConfigModel(QObject *parent = nullptr);
|
||||||
|
|
|
@ -58,10 +58,8 @@ ListView {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case ContainerEnum.WireGuard: {
|
case ContainerEnum.WireGuard: {
|
||||||
ProtocolsModel.updateModel(config)
|
WireGuardConfigModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
PageController.goToPage(PageEnum.PageProtocolWireGuardSettings)
|
||||||
// WireGuardConfigModel.updateModel(config)
|
|
||||||
// goToPage(PageEnum.PageProtocolWireGuardSettings)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case ContainerEnum.Awg: {
|
case ContainerEnum.Awg: {
|
||||||
|
@ -72,8 +70,6 @@ ListView {
|
||||||
case ContainerEnum.Ipsec: {
|
case ContainerEnum.Ipsec: {
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||||
// Ikev2ConfigModel.updateModel(config)
|
|
||||||
// goToPage(PageEnum.PageProtocolIKev2Settings)
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case ContainerEnum.Sftp: {
|
case ContainerEnum.Sftp: {
|
||||||
|
|
|
@ -106,6 +106,26 @@ PageType {
|
||||||
KeyNavigation.tab: junkPacketCountTextField.textField
|
KeyNavigation.tab: junkPacketCountTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: mtuTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("MTU")
|
||||||
|
textFieldText: mtu
|
||||||
|
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText === "") {
|
||||||
|
textFieldText = "0"
|
||||||
|
}
|
||||||
|
if (textFieldText !== mtu) {
|
||||||
|
mtu = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketCountTextField
|
id: junkPacketCountTextField
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -337,7 +357,7 @@ PageType {
|
||||||
junkPacketCountTextField.errorText === "" &&
|
junkPacketCountTextField.errorText === "" &&
|
||||||
portTextField.errorText === ""
|
portTextField.errorText === ""
|
||||||
|
|
||||||
text: qsTr("Save and Restart Amnezia")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
@ -174,7 +174,7 @@ PageType {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save and Restart Amnezia")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
@ -404,7 +404,7 @@ PageType {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save and Restart Amnezia")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
@ -148,7 +148,7 @@ PageType {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save and Restart Amnezia")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
172
client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
Normal file
172
client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
import "../Components"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlickableType {
|
||||||
|
id: fl
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listview
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: listview.contentItem.height
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
model: WireGuardConfigModel
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
implicitWidth: listview.width
|
||||||
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
headerText: qsTr("WG settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: portTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 40
|
||||||
|
|
||||||
|
headerText: qsTr("Port")
|
||||||
|
textFieldText: port
|
||||||
|
textField.maximumLength: 5
|
||||||
|
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== port) {
|
||||||
|
port = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: mtuTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("MTU")
|
||||||
|
textFieldText: mtu
|
||||||
|
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText === "") {
|
||||||
|
textFieldText = "0"
|
||||||
|
}
|
||||||
|
if (textFieldText !== mtu) {
|
||||||
|
mtu = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.leftMargin: -8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
text: qsTr("Remove WG")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
questionDrawer.headerText = qsTr("Remove WG from server?")
|
||||||
|
questionDrawer.descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
|
||||||
|
questionDrawer.yesButtonText = qsTr("Continue")
|
||||||
|
questionDrawer.noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
questionDrawer.yesButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
|
InstallController.removeCurrentlyProcessedContainer()
|
||||||
|
}
|
||||||
|
questionDrawer.noButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
}
|
||||||
|
questionDrawer.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
|
enabled: mtuTextField.errorText === "" &&
|
||||||
|
portTextField.errorText === ""
|
||||||
|
|
||||||
|
text: qsTr("Save")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
forceActiveFocus()
|
||||||
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
|
InstallController.updateContainer(WireGuardConfigModel.getConfig())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionDrawer {
|
||||||
|
id: questionDrawer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue