From 5134d479f7f265a8245271b8ba26dd10568420cc Mon Sep 17 00:00:00 2001 From: cd-amn Date: Wed, 6 May 2026 18:43:56 +0400 Subject: [PATCH] fix: apply WG interface params on hot-swap --- .../linux/daemon/wireguardutilslinux.cpp | 71 ++++++++----------- .../macos/daemon/wireguardutilsmacos.cpp | 70 ++++++++---------- .../windows/daemon/wireguardutilswindows.cpp | 29 ++++++++ 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/client/platforms/linux/daemon/wireguardutilslinux.cpp b/client/platforms/linux/daemon/wireguardutilslinux.cpp index 1b7cddc8e..ab5334910 100644 --- a/client/platforms/linux/daemon/wireguardutilslinux.cpp +++ b/client/platforms/linux/daemon/wireguardutilslinux.cpp @@ -25,6 +25,34 @@ constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg"; namespace { Logger logger("WireguardUtilsLinux"); Logger logwireguard("WireguardGo"); + +bool appendAwgInterfaceParams(const InterfaceConfig& config, QTextStream& out) { + bool hasParams = false; + const auto appendField = [&](const char* key, const QString& value) { + if (!value.isEmpty()) { + out << key << "=" << value << "\n"; + hasParams = true; + } + }; + + appendField("jc", config.m_junkPacketCount); + appendField("jmin", config.m_junkPacketMinSize); + appendField("jmax", config.m_junkPacketMaxSize); + appendField("s1", config.m_initPacketJunkSize); + appendField("s2", config.m_responsePacketJunkSize); + appendField("s3", config.m_cookieReplyPacketJunkSize); + appendField("s4", config.m_transportPacketJunkSize); + appendField("h1", config.m_initPacketMagicHeader); + appendField("h2", config.m_responsePacketMagicHeader); + appendField("h3", config.m_underloadPacketMagicHeader); + appendField("h4", config.m_transportPacketMagicHeader); + + for (const QString& key : config.m_specialJunk.keys()) { + out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; + hasParams = true; + } + return hasParams; +} }; // namespace WireguardUtilsLinux::WireguardUtilsLinux(QObject* parent) @@ -59,7 +87,6 @@ void WireguardUtilsLinux::tunnelErrorOccurred(QProcess::ProcessError error) { } bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) { - Q_UNUSED(config); if (m_tunnel.state() != QProcess::NotRunning) { logger.warning() << "Unable to start: tunnel process already running"; return false; @@ -104,45 +131,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) { QTextStream out(&message); out << "private_key=" << QString(privateKey.toHex()) << "\n"; out << "replace_peers=true\n"; - - - if (!config.m_junkPacketCount.isEmpty()) { - out << "jc=" << config.m_junkPacketCount << "\n"; - } - if (!config.m_junkPacketMinSize.isEmpty()) { - out << "jmin=" << config.m_junkPacketMinSize << "\n"; - } - if (!config.m_junkPacketMaxSize.isEmpty()) { - out << "jmax=" << config.m_junkPacketMaxSize << "\n"; - } - if (!config.m_initPacketJunkSize.isEmpty()) { - out << "s1=" << config.m_initPacketJunkSize << "\n"; - } - if (!config.m_responsePacketJunkSize.isEmpty()) { - out << "s2=" << config.m_responsePacketJunkSize << "\n"; - } - if (!config.m_cookieReplyPacketJunkSize.isEmpty()) { - out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n"; - } - if (!config.m_transportPacketJunkSize.isEmpty()) { - out << "s4=" << config.m_transportPacketJunkSize << "\n"; - } - if (!config.m_initPacketMagicHeader.isEmpty()) { - out << "h1=" << config.m_initPacketMagicHeader << "\n"; - } - if (!config.m_responsePacketMagicHeader.isEmpty()) { - out << "h2=" << config.m_responsePacketMagicHeader << "\n"; - } - if (!config.m_underloadPacketMagicHeader.isEmpty()) { - out << "h3=" << config.m_underloadPacketMagicHeader << "\n"; - } - if (!config.m_transportPacketMagicHeader.isEmpty()) { - out << "h4=" << config.m_transportPacketMagicHeader << "\n"; - } - - for (const QString& key : config.m_specialJunk.keys()) { - out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; - } + appendAwgInterfaceParams(config, out); int err = uapiErrno(uapiCommand(message)); if (err != 0) { @@ -201,7 +190,6 @@ bool WireguardUtilsLinux::deleteInterface() { return true; } -// dummy implementations for now bool WireguardUtilsLinux::updatePeer(const InterfaceConfig& config) { QByteArray publicKey = QByteArray::fromBase64(qPrintable(config.m_serverPublicKey)); @@ -214,6 +202,7 @@ bool WireguardUtilsLinux::updatePeer(const InterfaceConfig& config) { QString message; QTextStream out(&message); out << "set=1\n"; + appendAwgInterfaceParams(config, out); out << "public_key=" << QString(publicKey.toHex()) << "\n"; if (!config.m_serverPskKey.isNull()) { out << "preshared_key=" << QString(pskKey.toHex()) << "\n"; diff --git a/client/platforms/macos/daemon/wireguardutilsmacos.cpp b/client/platforms/macos/daemon/wireguardutilsmacos.cpp index 55a5526be..40f9f2772 100644 --- a/client/platforms/macos/daemon/wireguardutilsmacos.cpp +++ b/client/platforms/macos/daemon/wireguardutilsmacos.cpp @@ -24,6 +24,34 @@ constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg"; namespace { Logger logger("WireguardUtilsMacos"); Logger logwireguard("WireguardGo"); + +bool appendAwgInterfaceParams(const InterfaceConfig& config, QTextStream& out) { + bool hasParams = false; + const auto appendField = [&](const char* key, const QString& value) { + if (!value.isEmpty()) { + out << key << "=" << value << "\n"; + hasParams = true; + } + }; + + appendField("jc", config.m_junkPacketCount); + appendField("jmin", config.m_junkPacketMinSize); + appendField("jmax", config.m_junkPacketMaxSize); + appendField("s1", config.m_initPacketJunkSize); + appendField("s2", config.m_responsePacketJunkSize); + appendField("s3", config.m_cookieReplyPacketJunkSize); + appendField("s4", config.m_transportPacketJunkSize); + appendField("h1", config.m_initPacketMagicHeader); + appendField("h2", config.m_responsePacketMagicHeader); + appendField("h3", config.m_underloadPacketMagicHeader); + appendField("h4", config.m_transportPacketMagicHeader); + + for (const QString& key : config.m_specialJunk.keys()) { + out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; + hasParams = true; + } + return hasParams; +} }; // namespace WireguardUtilsMacos::WireguardUtilsMacos(QObject* parent) @@ -58,7 +86,6 @@ void WireguardUtilsMacos::tunnelErrorOccurred(QProcess::ProcessError error) { } bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) { - Q_UNUSED(config); if (m_tunnel.state() != QProcess::NotRunning) { logger.warning() << "Unable to start: tunnel process already running"; return false; @@ -103,44 +130,7 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) { QTextStream out(&message); out << "private_key=" << QString(privateKey.toHex()) << "\n"; out << "replace_peers=true\n"; - - if (!config.m_junkPacketCount.isEmpty()) { - out << "jc=" << config.m_junkPacketCount << "\n"; - } - if (!config.m_junkPacketMinSize.isEmpty()) { - out << "jmin=" << config.m_junkPacketMinSize << "\n"; - } - if (!config.m_junkPacketMaxSize.isEmpty()) { - out << "jmax=" << config.m_junkPacketMaxSize << "\n"; - } - if (!config.m_initPacketJunkSize.isEmpty()) { - out << "s1=" << config.m_initPacketJunkSize << "\n"; - } - if (!config.m_responsePacketJunkSize.isEmpty()) { - out << "s2=" << config.m_responsePacketJunkSize << "\n"; - } - if (!config.m_cookieReplyPacketJunkSize.isEmpty()) { - out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n"; - } - if (!config.m_transportPacketJunkSize.isEmpty()) { - out << "s4=" << config.m_transportPacketJunkSize << "\n"; - } - if (!config.m_initPacketMagicHeader.isEmpty()) { - out << "h1=" << config.m_initPacketMagicHeader << "\n"; - } - if (!config.m_responsePacketMagicHeader.isEmpty()) { - out << "h2=" << config.m_responsePacketMagicHeader << "\n"; - } - if (!config.m_underloadPacketMagicHeader.isEmpty()) { - out << "h3=" << config.m_underloadPacketMagicHeader << "\n"; - } - if (!config.m_transportPacketMagicHeader.isEmpty()) { - out << "h4=" << config.m_transportPacketMagicHeader << "\n"; - } - - for (const QString& key : config.m_specialJunk.keys()) { - out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; - } + appendAwgInterfaceParams(config, out); int err = uapiErrno(uapiCommand(message)); if (err != 0) { @@ -200,7 +190,6 @@ bool WireguardUtilsMacos::deleteInterface() { return true; } -// dummy implementations for now bool WireguardUtilsMacos::updatePeer(const InterfaceConfig& config) { QByteArray publicKey = QByteArray::fromBase64(qPrintable(config.m_serverPublicKey)); @@ -214,6 +203,7 @@ bool WireguardUtilsMacos::updatePeer(const InterfaceConfig& config) { QString message; QTextStream out(&message); out << "set=1\n"; + appendAwgInterfaceParams(config, out); out << "public_key=" << QString(publicKey.toHex()) << "\n"; if (!config.m_serverPskKey.isNull()) { out << "preshared_key=" << QString(pskKey.toHex()) << "\n"; diff --git a/client/platforms/windows/daemon/wireguardutilswindows.cpp b/client/platforms/windows/daemon/wireguardutilswindows.cpp index a5c9c84d1..49fd43fe5 100644 --- a/client/platforms/windows/daemon/wireguardutilswindows.cpp +++ b/client/platforms/windows/daemon/wireguardutilswindows.cpp @@ -20,6 +20,34 @@ namespace { Logger logger("WireguardUtilsWindows"); + +bool appendAwgInterfaceParams(const InterfaceConfig& config, QTextStream& out) { + bool hasParams = false; + const auto appendField = [&](const char* key, const QString& value) { + if (!value.isEmpty()) { + out << key << "=" << value << "\n"; + hasParams = true; + } + }; + + appendField("jc", config.m_junkPacketCount); + appendField("jmin", config.m_junkPacketMinSize); + appendField("jmax", config.m_junkPacketMaxSize); + appendField("s1", config.m_initPacketJunkSize); + appendField("s2", config.m_responsePacketJunkSize); + appendField("s3", config.m_cookieReplyPacketJunkSize); + appendField("s4", config.m_transportPacketJunkSize); + appendField("h1", config.m_initPacketMagicHeader); + appendField("h2", config.m_responsePacketMagicHeader); + appendField("h3", config.m_underloadPacketMagicHeader); + appendField("h4", config.m_transportPacketMagicHeader); + + for (const QString& key : config.m_specialJunk.keys()) { + out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n"; + hasParams = true; + } + return hasParams; +} }; // namespace std::unique_ptr WireguardUtilsWindows::create( @@ -165,6 +193,7 @@ bool WireguardUtilsWindows::updatePeer(const InterfaceConfig& config) { QString message; QTextStream out(&message); out << "set=1\n"; + appendAwgInterfaceParams(config, out); out << "public_key=" << QString(publicKey.toHex()) << "\n"; if (!config.m_serverPskKey.isNull()) { out << "preshared_key=" << QString(pskKey.toHex()) << "\n";