fix: improve reeconnection

This commit is contained in:
NickVs2015
2026-03-31 14:08:04 +03:00
parent bd554fb730
commit 214b18f65f
5 changed files with 23 additions and 17 deletions

View File

@@ -27,7 +27,7 @@
#include "protocols/protocols_defs.h"
// How many times do we try to reconnect.
constexpr int MAX_CONNECTION_RETRY = 10;
constexpr int MAX_CONNECTION_RETRY = 70;
// How long do we wait between one try and the next one.
constexpr int CONNECTION_RETRY_TIMER_MSEC = 500;

View File

@@ -378,7 +378,7 @@ void LinuxFirewall::uninstall()
bool LinuxFirewall::isInstalled()
{
return execute(QStringLiteral("iptables -C %1 -j %2 2> /dev/null").arg(kOutputChain, kRootChain)) == 0;
return execute(QStringLiteral("iptables -C %1 -j %2 2> /dev/null").arg(kOutputChain, kRootChain), true) == 0;
}
void LinuxFirewall::enableAnchor(LinuxFirewall::IPVersion ip, const QString &anchor, const QString& tableName)

View File

@@ -164,8 +164,13 @@ bool LinuxRouteMonitor::rtmSendRoute(int action, int flags, int type,
}
if (rtm->rtm_type == RTN_THROW) {
QString gateway = NetworkUtilities::getGatewayAndIface().first;
if (gateway.isEmpty()) {
logger.warning() << "No default gateway available, skipping exclusion route";
return false;
}
struct in_addr ip4;
inet_pton(AF_INET, NetworkUtilities::getGatewayAndIface().first.toUtf8(), &ip4);
inet_pton(AF_INET, gateway.toUtf8(), &ip4);
nlmsg_append_attr(nlmsg, sizeof(buf), RTA_GATEWAY, &ip4, sizeof(ip4));
nlmsg_append_attr32(nlmsg, sizeof(buf), RTA_PRIORITY, 0);
rtm->rtm_type = RTN_UNICAST;

View File

@@ -65,18 +65,10 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
return false;
}
// Kill any orphaned wireguard-go process from a previous crash that may
// still hold the amn0 TUN device, then delete the stale interface.
QProcess::execute("pkill", {"-f", QString("wireguard-go.*%1").arg(WG_INTERFACE)});
QProcess::execute("ip", {"link", "delete", WG_INTERFACE});
QDir wgRuntimeDir(WG_RUNTIME_DIR);
if (!wgRuntimeDir.exists()) {
wgRuntimeDir.mkpath(".");
}
// Remove stale runtime files from a previous session.
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".sock"));
QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
QString wgNameFile = wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".sock");
@@ -245,8 +237,10 @@ bool WireguardUtilsLinux::updatePeer(const InterfaceConfig& config) {
// Exclude the server address, except for multihop exit servers.
if ((config.m_hopType != InterfaceConfig::MultiHopExit) &&
(m_rtmonitor != nullptr)) {
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
IPAddress v4(config.m_serverIpv4AddrIn);
if (!v4.address().isNull()) m_rtmonitor->addExclusionRoute(v4);
IPAddress v6(config.m_serverIpv6AddrIn);
if (!v6.address().isNull()) m_rtmonitor->addExclusionRoute(v6);
}
int err = uapiErrno(uapiCommand(message));
@@ -260,11 +254,13 @@ bool WireguardUtilsLinux::deletePeer(const InterfaceConfig& config) {
QByteArray publicKey =
QByteArray::fromBase64(qPrintable(config.m_serverPublicKey));
// Clear exclustion routes for this peer.
// Clear exclusion routes for this peer.
if ((config.m_hopType != InterfaceConfig::MultiHopExit) &&
(m_rtmonitor != nullptr)) {
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
IPAddress v4(config.m_serverIpv4AddrIn);
if (!v4.address().isNull()) m_rtmonitor->deleteExclusionRoute(v4);
IPAddress v6(config.m_serverIpv6AddrIn);
if (!v6.address().isNull()) m_rtmonitor->deleteExclusionRoute(v6);
}
QString message;

View File

@@ -213,7 +213,12 @@ void LinuxNetworkWatcherWorker::NMStateChanged(quint32 state)
if (state == NM_STATE_ASLEEP) {
emit wakeup();
} else if (state >= NM_STATE_CONNECTED_SITE && m_previousNMState < NM_STATE_CONNECTED_SITE) {
emit networkChanged();
// Delay the reconnect so the kernel routing table (and default gateway)
// are fully restored before the VPN exclusion route is recalculated.
// Without this delay, getGatewayAndIface() may return an empty gateway
// immediately after network recovery, causing the server exclusion route
// to be installed with gateway 0.0.0.0 and breaking WG handshakes.
QTimer::singleShot(3000, this, [this]() { emit networkChanged(); });
}
m_previousNMState = state;