From fd915a43252e6ba89935a607bb2e0a17c4394671 Mon Sep 17 00:00:00 2001 From: NickVs2015 Date: Wed, 29 Apr 2026 10:18:08 +0300 Subject: [PATCH] fix: replace m_linkDefaultRoutes map with single m_gatewayIfindex --- .../platforms/linux/daemon/dnsutilslinux.cpp | 62 +++++++------------ client/platforms/linux/daemon/dnsutilslinux.h | 3 +- 2 files changed, 25 insertions(+), 40 deletions(-) diff --git a/client/platforms/linux/daemon/dnsutilslinux.cpp b/client/platforms/linux/daemon/dnsutilslinux.cpp index 83a749d68..e1f9e724e 100644 --- a/client/platforms/linux/daemon/dnsutilslinux.cpp +++ b/client/platforms/linux/daemon/dnsutilslinux.cpp @@ -66,14 +66,8 @@ DnsUtilsLinux::~DnsUtilsLinux() { MZ_COUNT_DTOR(DnsUtilsLinux); if (m_resolver) { - for (auto iterator = m_linkDefaultRoutes.constBegin(); - iterator != m_linkDefaultRoutes.constEnd(); ++iterator) { - QList argumentList; - argumentList << QVariant::fromValue(iterator.key()); - argumentList << QVariant::fromValue(iterator.value()); - m_resolver->asyncCallWithArgumentList(QStringLiteral("SetLinkDefaultRoute"), - argumentList); - } + if (m_gatewayIfindex > 0) + setLinkDefaultRoute(m_gatewayIfindex, true); for (auto iterator = m_linkDomains.constBegin(); iterator != m_linkDomains.constEnd(); ++iterator) { @@ -93,11 +87,10 @@ DnsUtilsLinux::~DnsUtilsLinux() { bool DnsUtilsLinux::updateResolvers(const QString& ifname, const QList& resolvers) { - for (auto iterator = m_linkDefaultRoutes.constBegin(); - iterator != m_linkDefaultRoutes.constEnd(); ++iterator) { - setLinkDefaultRoute(iterator.key(), iterator.value()); + if (m_gatewayIfindex > 0) { + setLinkDefaultRoute(m_gatewayIfindex, true); + m_gatewayIfindex = 0; } - m_linkDefaultRoutes.clear(); m_ifindex = if_nametoindex(qPrintable(ifname)); if (m_ifindex <= 0) { @@ -113,7 +106,12 @@ bool DnsUtilsLinux::updateResolvers(const QString& ifname, return true; } - updateLinkDefaultRoutes(); + const int gwIdx = NetworkUtilities::getGatewayAndIface().second.index(); + if (gwIdx > 0 && gwIdx != m_ifindex && gwIdx != m_gatewayIfindex) { + m_gatewayIfindex = gwIdx; + setLinkDefaultRoute(gwIdx, false); + } + setLinkDNS(m_ifindex, resolvers); setLinkDefaultRoute(m_ifindex, true); updateLinkDomains(); @@ -124,11 +122,10 @@ bool DnsUtilsLinux::restoreResolvers() { m_pendingIfname.clear(); m_pendingResolvers.clear(); - for (auto iterator = m_linkDefaultRoutes.constBegin(); - iterator != m_linkDefaultRoutes.constEnd(); ++iterator) { - setLinkDefaultRoute(iterator.key(), iterator.value()); + if (m_gatewayIfindex > 0) { + setLinkDefaultRoute(m_gatewayIfindex, true); + m_gatewayIfindex = 0; } - m_linkDefaultRoutes.clear(); for (auto iterator = m_linkDomains.constBegin(); iterator != m_linkDomains.constEnd(); ++iterator) { @@ -155,7 +152,7 @@ bool DnsUtilsLinux::restoreResolvers() { void DnsUtilsLinux::dnsCallCompleted(QDBusPendingCallWatcher* call) { QDBusPendingReply<> reply = *call; if (reply.isError()) { - logger.error() << "Error received from the DBus service"; + logger.debug() << "DBus call failed (may be transient after systemd-resolved restart)"; } delete call; } @@ -223,23 +220,6 @@ void DnsUtilsLinux::setLinkDefaultRoute(int ifindex, bool enable) { SLOT(dnsCallCompleted(QDBusPendingCallWatcher*))); } -void DnsUtilsLinux::updateLinkDefaultRoutes() { - const QNetworkInterface defaultIface = NetworkUtilities::getGatewayAndIface().second; - const int ifindex = defaultIface.index(); - if (ifindex <= 0) { - logger.warning() << "Unable to determine default route interface"; - return; - } - if ((ifindex == m_ifindex) || m_linkDefaultRoutes.contains(ifindex)) { - return; - } - - // Gateway link normally has DefaultRoute=yes. Keep behavior simple: - // disable it while VPN DNS is active and restore to yes on teardown. - m_linkDefaultRoutes[ifindex] = true; - setLinkDefaultRoute(ifindex, false); -} - void DnsUtilsLinux::updateLinkDomains() { if (!m_resolver) return; /* Get the list of search domains, and remove any others that might conspire @@ -300,9 +280,15 @@ void DnsUtilsLinux::dnsDomainsReceived(QDBusPendingCallWatcher* call) { /* Add a root search domain for the new interface. */ if (m_ifindex > 0) { - QList newlist = {root}; - setLinkDomains(m_ifindex, newlist); - updateLinkDefaultRoutes(); + setLinkDomains(m_ifindex, {root}); + + /* Disable DefaultRoute on the physical gateway so systemd-resolved + * routes all DNS through the VPN interface. */ + const int gwIdx = NetworkUtilities::getGatewayAndIface().second.index(); + if (gwIdx > 0 && gwIdx != m_ifindex && gwIdx != m_gatewayIfindex) { + m_gatewayIfindex = gwIdx; + setLinkDefaultRoute(gwIdx, false); + } } } diff --git a/client/platforms/linux/daemon/dnsutilslinux.h b/client/platforms/linux/daemon/dnsutilslinux.h index f9f03b41e..cdc1492df 100644 --- a/client/platforms/linux/daemon/dnsutilslinux.h +++ b/client/platforms/linux/daemon/dnsutilslinux.h @@ -31,7 +31,6 @@ class DnsUtilsLinux final : public DnsUtils { void setLinkDNS(int ifindex, const QList& resolvers); void setLinkDomains(int ifindex, const QList& domains); void setLinkDefaultRoute(int ifindex, bool enable); - void updateLinkDefaultRoutes(); void updateLinkDomains(); private slots: @@ -42,9 +41,9 @@ class DnsUtilsLinux final : public DnsUtils { private: int m_ifindex = 0; + int m_gatewayIfindex = 0; int m_domainRetries = 0; QMap m_linkDomains; - QMap m_linkDefaultRoutes; QScopedPointer m_resolver; QString m_pendingIfname; QList m_pendingResolvers;