mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-05-08 14:33:23 +00:00
fix: dns rewrites and flush
This commit is contained in:
@@ -7,9 +7,11 @@
|
||||
#include <net/if.h>
|
||||
|
||||
#include <QDBusVariant>
|
||||
#include <QNetworkInterface>
|
||||
#include <QTimer>
|
||||
#include <QtDBus/QtDBus>
|
||||
|
||||
#include "core/networkUtilities.h"
|
||||
#include "leakdetector.h"
|
||||
#include "logger.h"
|
||||
|
||||
@@ -64,6 +66,15 @@ DnsUtilsLinux::~DnsUtilsLinux() {
|
||||
MZ_COUNT_DTOR(DnsUtilsLinux);
|
||||
|
||||
if (m_resolver) {
|
||||
for (auto iterator = m_linkDefaultRoutes.constBegin();
|
||||
iterator != m_linkDefaultRoutes.constEnd(); ++iterator) {
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << QVariant::fromValue(iterator.key());
|
||||
argumentList << QVariant::fromValue(iterator.value());
|
||||
m_resolver->asyncCallWithArgumentList(QStringLiteral("SetLinkDefaultRoute"),
|
||||
argumentList);
|
||||
}
|
||||
|
||||
for (auto iterator = m_linkDomains.constBegin();
|
||||
iterator != m_linkDomains.constEnd(); ++iterator) {
|
||||
QList<QVariant> argumentList;
|
||||
@@ -82,6 +93,12 @@ DnsUtilsLinux::~DnsUtilsLinux() {
|
||||
|
||||
bool DnsUtilsLinux::updateResolvers(const QString& ifname,
|
||||
const QList<QHostAddress>& resolvers) {
|
||||
for (auto iterator = m_linkDefaultRoutes.constBegin();
|
||||
iterator != m_linkDefaultRoutes.constEnd(); ++iterator) {
|
||||
setLinkDefaultRoute(iterator.key(), iterator.value());
|
||||
}
|
||||
m_linkDefaultRoutes.clear();
|
||||
|
||||
m_ifindex = if_nametoindex(qPrintable(ifname));
|
||||
if (m_ifindex <= 0) {
|
||||
logger.error() << "Unable to resolve ifindex for" << ifname;
|
||||
@@ -96,9 +113,9 @@ bool DnsUtilsLinux::updateResolvers(const QString& ifname,
|
||||
return true;
|
||||
}
|
||||
|
||||
updateLinkDefaultRoutes();
|
||||
setLinkDNS(m_ifindex, resolvers);
|
||||
setLinkDefaultRoute(m_ifindex, true);
|
||||
setLinkDomains(m_ifindex, {DnsLinkDomain(".", true)});
|
||||
updateLinkDomains();
|
||||
return true;
|
||||
}
|
||||
@@ -107,6 +124,12 @@ 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());
|
||||
}
|
||||
m_linkDefaultRoutes.clear();
|
||||
|
||||
for (auto iterator = m_linkDomains.constBegin();
|
||||
iterator != m_linkDomains.constEnd(); ++iterator) {
|
||||
setLinkDomains(iterator.key(), iterator.value());
|
||||
@@ -132,7 +155,7 @@ bool DnsUtilsLinux::restoreResolvers() {
|
||||
void DnsUtilsLinux::dnsCallCompleted(QDBusPendingCallWatcher* call) {
|
||||
QDBusPendingReply<> reply = *call;
|
||||
if (reply.isError()) {
|
||||
logger.debug() << "DBus call failed (may be transient after systemd-resolved restart)";
|
||||
logger.error() << "Error received from the DBus service";
|
||||
}
|
||||
delete call;
|
||||
}
|
||||
@@ -200,6 +223,23 @@ 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
|
||||
|
||||
@@ -31,6 +31,7 @@ class DnsUtilsLinux final : public DnsUtils {
|
||||
void setLinkDNS(int ifindex, const QList<QHostAddress>& resolvers);
|
||||
void setLinkDomains(int ifindex, const QList<DnsLinkDomain>& domains);
|
||||
void setLinkDefaultRoute(int ifindex, bool enable);
|
||||
void updateLinkDefaultRoutes();
|
||||
void updateLinkDomains();
|
||||
|
||||
private slots:
|
||||
@@ -43,6 +44,7 @@ class DnsUtilsLinux final : public DnsUtils {
|
||||
int m_ifindex = 0;
|
||||
int m_domainRetries = 0;
|
||||
QMap<int, DnsLinkDomainList> m_linkDomains;
|
||||
QMap<int, bool> m_linkDefaultRoutes;
|
||||
QScopedPointer<QDBusInterface> m_resolver;
|
||||
QString m_pendingIfname;
|
||||
QList<QHostAddress> m_pendingResolvers;
|
||||
|
||||
@@ -167,22 +167,27 @@ bool RouterLinux::flushDns()
|
||||
|
||||
//check what the dns manager use
|
||||
if (isServiceActive("nscd.service")) {
|
||||
qDebug() << "Restarting nscd.service";
|
||||
p.start("systemctl", { "restart", "nscd" });
|
||||
qDebug() << "Flushing nscd cache";
|
||||
p.start("nscd", { "--invalidate=hosts" });
|
||||
} else if (isServiceActive("systemd-resolved.service")) {
|
||||
qDebug() << "Restarting systemd-resolved.service";
|
||||
p.start("systemctl", { "restart", "systemd-resolved" });
|
||||
qDebug() << "Flushing systemd-resolved DNS cache";
|
||||
p.start("resolvectl", { "flush-caches" });
|
||||
} else {
|
||||
qDebug() << "No suitable DNS manager found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
p.waitForFinished();
|
||||
QByteArray output(p.readAll());
|
||||
QByteArray output = p.readAll();
|
||||
if ((p.exitStatus() != QProcess::NormalExit) || (p.exitCode() != 0)) {
|
||||
qDebug().noquote() << "Failed to flush DNS: " + output;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (output.isEmpty())
|
||||
qDebug().noquote() << "Flush dns completed";
|
||||
else
|
||||
qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output;
|
||||
qDebug().noquote() << "OUTPUT dns flush: " + output;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user