Update configs only if the key is not empty

This commit is contained in:
Dmitry Vorobyov 2025-04-20 11:49:08 +02:00
parent c44ce0d77c
commit 693d0eb64a
8 changed files with 134 additions and 71 deletions

View file

@ -4,6 +4,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
AwgConfigModel::AwgConfigModel(QObject *parent) : QAbstractListModel(parent) AwgConfigModel::AwgConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -90,40 +92,45 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
QJsonObject serverProtocolConfig = config.value(config_key::awg).toObject(); QJsonObject serverProtocolConfig = config.value(config_key::awg).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Awg), Proto::Awg); const auto defaultTransportProto =
m_serverProtocolConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Awg), Proto::Awg);
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
m_serverProtocolConfig[config_key::junkPacketCount] =
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
m_serverProtocolConfig[config_key::junkPacketMinSize] =
serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
m_serverProtocolConfig[config_key::junkPacketMaxSize] =
serverProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
m_serverProtocolConfig[config_key::initPacketJunkSize] =
serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
m_serverProtocolConfig[config_key::responsePacketJunkSize] =
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
serverProtocolConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader);
m_serverProtocolConfig[config_key::underloadPacketMagicHeader] =
serverProtocolConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader);
m_serverProtocolConfig[config_key::transportPacketMagicHeader] =
serverProtocolConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader);
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString(); updateConfig(serverProtocolConfig, config_key::transport_proto, defaultTransportProto.toUtf8().constData());
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
const std::pair<const char *, const char *> serverDefaults[] = {
{ config_key::subnet_address, protocols::wireguard::defaultSubnetAddress },
{ config_key::port, protocols::wireguard::defaultPort },
{ config_key::junkPacketCount, protocols::awg::defaultJunkPacketCount },
{ config_key::junkPacketMinSize, protocols::awg::defaultJunkPacketMinSize },
{ config_key::junkPacketMaxSize, protocols::awg::defaultJunkPacketMaxSize },
{ config_key::initPacketJunkSize, protocols::awg::defaultInitPacketJunkSize },
{ config_key::responsePacketJunkSize, protocols::awg::defaultResponsePacketJunkSize },
{ config_key::initPacketMagicHeader, protocols::awg::defaultInitPacketMagicHeader },
{ config_key::responsePacketMagicHeader, protocols::awg::defaultResponsePacketMagicHeader },
{ config_key::underloadPacketMagicHeader, protocols::awg::defaultUnderloadPacketMagicHeader },
{ config_key::transportPacketMagicHeader, protocols::awg::defaultTransportPacketMagicHeader },
};
for (const auto &[key, defaultValue] : serverDefaults)
updateConfig(serverProtocolConfig, key, defaultValue);
const auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object(); QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
m_clientProtocolConfig[config_key::mtu] = clientProtocolConfig[config_key::mtu].toString(protocols::awg::defaultMtu);
m_clientProtocolConfig[config_key::junkPacketCount] = const std::pair<const char *, const char *> clientDefaults[] = {
clientProtocolConfig.value(config_key::junkPacketCount).toString(m_serverProtocolConfig[config_key::junkPacketCount].toString()); { config_key::mtu, protocols::awg::defaultMtu },
m_clientProtocolConfig[config_key::junkPacketMinSize] = { config_key::junkPacketCount,
clientProtocolConfig.value(config_key::junkPacketMinSize).toString(m_serverProtocolConfig[config_key::junkPacketMinSize].toString()); m_serverProtocolConfig[config_key::junkPacketCount].toString().toUtf8().constData() },
m_clientProtocolConfig[config_key::junkPacketMaxSize] = { config_key::junkPacketMinSize,
clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(m_serverProtocolConfig[config_key::junkPacketMaxSize].toString()); m_serverProtocolConfig[config_key::junkPacketMinSize].toString().toUtf8().constData() },
{ config_key::junkPacketMaxSize,
m_serverProtocolConfig[config_key::junkPacketMaxSize].toString().toUtf8().constData() },
};
for (const auto &[key, defaultValue] : clientDefaults)
updateConfig(clientProtocolConfig, key, defaultValue);
endResetModel(); endResetModel();
} }

View file

@ -2,6 +2,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
CloakConfigModel::CloakConfigModel(QObject *parent) : QAbstractListModel(parent) CloakConfigModel::CloakConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -51,11 +53,12 @@ void CloakConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config; m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::cloak).toObject(); QJsonObject protocolConfig = config.value(config_key::cloak).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Cloak), Proto::Cloak); auto defaultTransportProto =
m_protocolConfig.insert(config_key::transport_proto, protocolConfig.value(config_key::transport_proto).toString(defaultTransportProto)); ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Cloak), Proto::Cloak);
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::cloak::defaultCipher)); updateConfig(protocolConfig, config_key::transport_proto, defaultTransportProto.toUtf8().constData());
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::cloak::defaultPort)); updateConfig(protocolConfig, config_key::cipher, protocols::cloak::defaultCipher);
m_protocolConfig.insert(config_key::site, protocolConfig.value(config_key::site).toString(protocols::cloak::defaultRedirSite)); updateConfig(protocolConfig, config_key::port, protocols::cloak::defaultPort);
updateConfig(protocolConfig, config_key::site, protocols::cloak::defaultRedirSite);
endResetModel(); endResetModel();
} }

View file

@ -2,6 +2,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
Ikev2ConfigModel::Ikev2ConfigModel(QObject *parent) : QAbstractListModel(parent) Ikev2ConfigModel::Ikev2ConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -49,8 +51,8 @@ void Ikev2ConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config; m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::shadowsocks).toObject(); QJsonObject protocolConfig = config.value(config_key::shadowsocks).toObject();
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher)); updateConfig(protocolConfig, config_key::cipher, protocols::shadowsocks::defaultCipher);
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort)); updateConfig(protocolConfig, config_key::port, protocols::shadowsocks::defaultPort);
endResetModel(); endResetModel();
} }

View file

@ -2,6 +2,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
OpenVpnConfigModel::OpenVpnConfigModel(QObject *parent) : QAbstractListModel(parent) OpenVpnConfigModel::OpenVpnConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -73,9 +75,7 @@ void OpenVpnConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config; m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::openvpn).toObject(); QJsonObject protocolConfig = config.value(config_key::openvpn).toObject();
m_protocolConfig.insert( updateConfig(protocolConfig, config_key::subnet_address, amnezia::protocols::openvpn::defaultSubnetAddress);
config_key::subnet_address,
protocolConfig.value(amnezia::config_key::subnet_address).toString(amnezia::protocols::openvpn::defaultSubnetAddress));
QString transportProto; QString transportProto;
if (m_container == DockerContainer::OpenVpn) { if (m_container == DockerContainer::OpenVpn) {
@ -84,22 +84,31 @@ void OpenVpnConfigModel::updateModel(const QJsonObject &config)
transportProto = "tcp"; transportProto = "tcp";
} }
m_protocolConfig.insert(config_key::transport_proto, transportProto); const std::pair<const char *, std::variant<const char *, bool>> defaults[] = {
{ config_key::transport_proto, transportProto.toUtf8().constData() },
{ config_key::port, protocols::openvpn::defaultPort },
{ config_key::ncp_disable, protocols::openvpn::defaultNcpDisable },
{ config_key::cipher, protocols::openvpn::defaultCipher },
{ config_key::hash, protocols::openvpn::defaultHash },
{ config_key::block_outside_dns, protocols::openvpn::defaultBlockOutsideDns },
{ config_key::tls_auth, protocols::openvpn::defaultTlsAuth },
{ config_key::additional_client_config, protocols::openvpn::defaultAdditionalClientConfig },
};
m_protocolConfig.insert(config_key::ncp_disable, for (const auto &[key, def] : defaults) {
protocolConfig.value(config_key::ncp_disable).toBool(protocols::openvpn::defaultNcpDisable)); const auto configKey = key;
m_protocolConfig.insert(config_key::cipher, protocolConfig.value(config_key::cipher).toString(protocols::openvpn::defaultCipher)); const auto defaultValue = def;
m_protocolConfig.insert(config_key::hash, protocolConfig.value(config_key::hash).toString(protocols::openvpn::defaultHash)); std::visit([&](auto &&defaultValue_) { updateConfig(protocolConfig, configKey, defaultValue_); }, defaultValue);
m_protocolConfig.insert(config_key::block_outside_dns, }
protocolConfig.value(config_key::block_outside_dns).toBool(protocols::openvpn::defaultBlockOutsideDns));
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::openvpn::defaultPort)); updateConfig(protocolConfig, config_key::transport_proto, transportProto.toUtf8().constData());
m_protocolConfig.insert(config_key::tls_auth, protocolConfig.value(config_key::tls_auth).toBool(protocols::openvpn::defaultTlsAuth)); updateConfig(protocolConfig, config_key::ncp_disable, protocols::openvpn::defaultNcpDisable);
m_protocolConfig.insert( updateConfig(protocolConfig, config_key::cipher, protocols::openvpn::defaultCipher);
config_key::additional_client_config, updateConfig(protocolConfig, config_key::hash, protocols::openvpn::defaultHash);
protocolConfig.value(config_key::additional_client_config).toString(protocols::openvpn::defaultAdditionalClientConfig)); updateConfig(protocolConfig, config_key::block_outside_dns, protocols::openvpn::defaultBlockOutsideDns);
m_protocolConfig.insert( updateConfig(protocolConfig, config_key::port, protocols::openvpn::defaultPort);
config_key::additional_server_config, updateConfig(protocolConfig, config_key::tls_auth, protocols::openvpn::defaultTlsAuth);
protocolConfig.value(config_key::additional_server_config).toString(protocols::openvpn::defaultAdditionalServerConfig)); updateConfig(protocolConfig, config_key::additional_client_config, protocols::openvpn::defaultAdditionalClientConfig);
endResetModel(); endResetModel();
} }

View file

@ -0,0 +1,22 @@
#pragma once
#include <QJsonObject>
template<typename T>
inline void updateConfig(const QJsonObject &inConfig, QJsonObject &outConfig, const char *config_key, T default_value)
{
if (!inConfig.contains(config_key))
return;
const auto value = inConfig.value(config_key);
if constexpr (std::is_same_v<T, const char *>) {
outConfig[config_key] = value.toString(default_value);
} else if constexpr (std::is_same_v<T, bool>) {
outConfig[config_key] = value.toBool(default_value);
} else {
static_assert(std::is_same_v<T, void>, "updateConfig: unsupported default-value type");
}
}
#define updateConfig(NAME, key, default_value) updateConfig(NAME, m_##NAME, key, default_value);

View file

@ -4,6 +4,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent) WireGuardConfigModel::WireGuardConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -55,15 +57,23 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
auto defaultTransportProto = auto defaultTransportProto =
ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::WireGuard), Proto::WireGuard); ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::WireGuard), Proto::WireGuard);
m_serverProtocolConfig.insert(config_key::transport_proto, updateConfig(serverProtocolConfig, config_key::transport_proto, defaultTransportProto.toUtf8().constData());
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
const std::pair<const char *, const char *> serverDefaults[] = {
{ config_key::transport_proto, defaultTransportProto.toUtf8().constData() },
{ config_key::subnet_address, protocols::wireguard::defaultSubnetAddress },
{ config_key::port, protocols::wireguard::defaultPort },
};
for (const auto &[key, def] : serverDefaults)
updateConfig(serverProtocolConfig, key, def);
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config); m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString(); auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object(); QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
m_clientProtocolConfig[config_key::mtu] = clientProtocolConfig[config_key::mtu].toString(protocols::wireguard::defaultMtu); updateConfig(clientProtocolConfig, config_key::mtu, protocols::wireguard::defaultMtu);
endResetModel(); endResetModel();
} }

View file

@ -2,6 +2,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
XrayConfigModel::XrayConfigModel(QObject *parent) : QAbstractListModel(parent) XrayConfigModel::XrayConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -47,11 +49,20 @@ void XrayConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config; m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::xray).toObject(); QJsonObject protocolConfig = config.value(config_key::xray).toObject();
auto defaultTransportProto = ProtocolProps::transportProtoToString(ProtocolProps::defaultTransportProto(Proto::Xray), Proto::Xray); if (protocolConfig.contains(config_key::transport_proto)) {
m_protocolConfig.insert(config_key::transport_proto, auto transportProto = protocolConfig.value(config_key::transport_proto)
protocolConfig.value(config_key::transport_proto).toString(defaultTransportProto)); .toString(ProtocolProps::transportProtoToString(
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString(protocols::xray::defaultPort)); ProtocolProps::defaultTransportProto(Proto::Xray), Proto::Xray));
m_protocolConfig.insert(config_key::site, protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite)); m_protocolConfig[config_key::transport_proto] = transportProto;
}
const std::pair<const char *, const char *> defaults[] = {
{ config_key::port, protocols::xray::defaultPort },
{ config_key::site, protocols::xray::defaultSite },
};
for (const auto &[key, def] : defaults)
updateConfig(protocolConfig, key, def);
endResetModel(); endResetModel();
} }

View file

@ -2,6 +2,8 @@
#include "protocols/protocols_defs.h" #include "protocols/protocols_defs.h"
#include "ui/models/protocols/utils.h"
SftpConfigModel::SftpConfigModel(QObject *parent) : QAbstractListModel(parent) SftpConfigModel::SftpConfigModel(QObject *parent) : QAbstractListModel(parent)
{ {
} }
@ -36,11 +38,8 @@ void SftpConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config; m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::sftp).toObject(); QJsonObject protocolConfig = config.value(config_key::sftp).toObject();
m_protocolConfig.insert(config_key::userName, updateConfig(protocolConfig, config_key::userName, protocols::sftp::defaultUserName);
protocolConfig.value(config_key::userName).toString(protocols::sftp::defaultUserName));
m_protocolConfig.insert(config_key::password, protocolConfig.value(config_key::password).toString()); m_protocolConfig.insert(config_key::password, protocolConfig.value(config_key::password).toString());
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString()); m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString());
endResetModel(); endResetModel();