fix: add support system with nscd service

This commit is contained in:
NickVs2015
2026-04-10 23:08:32 +03:00
parent 37d2b8716d
commit 9166e17a23
3 changed files with 58 additions and 49 deletions
+48 -24
View File
@@ -1,6 +1,3 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "dnsutilslinux.h"
@@ -26,7 +23,6 @@ DnsUtilsLinux::~DnsUtilsLinux() {
logger.debug() << "DnsUtilsLinux destroyed.";
}
void DnsUtilsLinux::writeResolvConf(const QList<QHostAddress>& resolvers) {
if (resolvers.isEmpty()) return;
@@ -38,16 +34,28 @@ void DnsUtilsLinux::writeResolvConf(const QList<QHostAddress>& resolvers) {
m_resolvConfOriginal = fi.symLinkTarget();
logger.debug() << "Saved resolv.conf symlink target:"
<< m_resolvConfOriginal;
if (!m_stateFilePath.isEmpty()) {
QFile sf(m_stateFilePath);
if (sf.open(QIODevice::WriteOnly | QIODevice::Text))
sf.write(m_resolvConfOriginal.toUtf8());
}
} else {
m_resolvConfOriginal = QStringLiteral("__file__");
logger.debug()
<< "resolv.conf is a regular file; will restore stub on disconnect";
}
if (!m_stateFilePath.isEmpty()) {
QFile sf(m_stateFilePath);
if (sf.open(QIODevice::WriteOnly | QIODevice::Text))
sf.write(m_resolvConfOriginal.toUtf8());
QFile orig(kPath);
if (orig.open(QIODevice::ReadOnly | QIODevice::Text)) {
QByteArray content = orig.readAll();
orig.close();
m_resolvConfOriginal = QStringLiteral("__file__");
logger.debug() << "resolv.conf is a regular file; saved content for restore";
if (!m_stateFilePath.isEmpty()) {
QFile sf(m_stateFilePath);
if (sf.open(QIODevice::WriteOnly | QIODevice::Text)) {
sf.write("__file__:");
sf.write(content);
}
}
} else {
m_resolvConfOriginal = QStringLiteral("__file__");
}
}
}
@@ -81,16 +89,25 @@ void DnsUtilsLinux::restoreResolvConf() {
QFile::remove(m_stateFilePath);
static const char* kPath = "/etc/resolv.conf";
static const char* kStub = "/run/systemd/resolve/stub-resolv.conf";
QFile::remove(kPath);
const QString target = (original == QStringLiteral("__file__"))
? QLatin1String(kStub)
: original;
QFile::link(target, kPath);
logger.debug() << "Restored resolv.conf symlink to" << target;
if (original == QStringLiteral("__file__")) {
if (!m_resolvConfSavedContent.isEmpty()) {
QFile f(kPath);
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
f.write(m_resolvConfSavedContent.toUtf8());
logger.debug() << "Restored resolv.conf from saved content";
}
m_resolvConfSavedContent.clear();
} else if (QFile::exists(QStringLiteral("/run/systemd/resolve/stub-resolv.conf"))) {
QFile::link(QStringLiteral("/run/systemd/resolve/stub-resolv.conf"), kPath);
logger.debug() << "Restored resolv.conf symlink to stub-resolv.conf";
}
} else {
QFile::link(original, kPath);
logger.debug() << "Restored resolv.conf symlink to" << original;
}
}
bool DnsUtilsLinux::updateResolvers(const QString& ifname,
@@ -114,6 +131,7 @@ bool DnsUtilsLinux::restoreResolvers() {
if (!m_stateFilePath.isEmpty()) {
candidates << m_stateFilePath;
} else {
QDir runDir(QStringLiteral("/run"));
for (const QString& name : runDir.entryList(
{QStringLiteral("amnezia-dns-*")}, QDir::Files)) {
@@ -122,10 +140,16 @@ bool DnsUtilsLinux::restoreResolvers() {
}
for (const QString& path : candidates) {
QFile sf(path);
if (sf.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_resolvConfOriginal = QString::fromUtf8(sf.readAll()).trimmed();
m_stateFilePath = path;
if (sf.open(QIODevice::ReadOnly)) {
QByteArray data = sf.readAll();
sf.close();
m_stateFilePath = path;
if (data.startsWith("__file__:")) {
m_resolvConfOriginal = QStringLiteral("__file__");
m_resolvConfSavedContent = QString::fromUtf8(data.mid(9));
} else {
m_resolvConfOriginal = QString::fromUtf8(data).trimmed();
}
logger.debug() << "Recovered DNS original from" << path << ":"
<< m_resolvConfOriginal;
break;
@@ -136,7 +160,7 @@ bool DnsUtilsLinux::restoreResolvers() {
const bool hadDnsState = !m_resolvConfOriginal.isEmpty();
restoreResolvConf();
if (hadDnsState) {
if (hadDnsState && QFile::exists(QStringLiteral("/run/systemd/resolve"))) {
QProcess::startDetached("systemctl", {"restart", "systemd-resolved"});
}
@@ -1,6 +1,3 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DNSUTILSLINUX_H
#define DNSUTILSLINUX_H
@@ -27,8 +24,10 @@ class DnsUtilsLinux final : public DnsUtils {
void restoreResolvConf();
private:
QString m_resolvConfOriginal;
QString m_resolvConfSavedContent;
QString m_stateFilePath;
};
#endif // DNSUTILSLINUX_H
#endif
+7 -21
View File
@@ -41,15 +41,14 @@ bool RouterLinux::routeAdd(const QString &ipWithSubnet, const QString &gw, const
struct rtentry route;
memset(&route, 0, sizeof( route ));
// set gateway
((struct sockaddr_in *)&route.rt_gateway)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_gateway)->sin_addr.s_addr = inet_addr(gw.toStdString().c_str());
((struct sockaddr_in *)&route.rt_gateway)->sin_port = 0;
// set host rejecting
((struct sockaddr_in *)&route.rt_dst)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_dst)->sin_addr.s_addr = inet_addr(ip.toStdString().c_str());
((struct sockaddr_in *)&route.rt_dst)->sin_port = 0;
// set mask
((struct sockaddr_in *)&route.rt_genmask)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_genmask)->sin_addr.s_addr = inet_addr(mask.toStdString().c_str());
((struct sockaddr_in *)&route.rt_genmask)->sin_port = 0;
@@ -116,22 +115,20 @@ bool RouterLinux::routeDelete(const QString &ipWithSubnet, const QString &gw, co
struct rtentry route;
memset(&route, 0, sizeof( route ));
// set gateway
((struct sockaddr_in *)&route.rt_gateway)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_gateway)->sin_addr.s_addr = inet_addr(gw.toStdString().c_str());
((struct sockaddr_in *)&route.rt_gateway)->sin_port = 0;
// set host rejecting
((struct sockaddr_in *)&route.rt_dst)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_dst)->sin_addr.s_addr = inet_addr(ip.toStdString().c_str());
((struct sockaddr_in *)&route.rt_dst)->sin_port = 0;
// set mask
((struct sockaddr_in *)&route.rt_genmask)->sin_family = AF_INET;
((struct sockaddr_in *)&route.rt_genmask)->sin_addr.s_addr = inet_addr(mask.toStdString().c_str());
((struct sockaddr_in *)&route.rt_genmask)->sin_port = 0;
route.rt_flags = RTF_UP | RTF_GATEWAY;
route.rt_metric = 0;
//route.rt_dev = "ens33";
if (ioctl(sock, SIOCDELRT, &route) < 0)
{
@@ -164,21 +161,10 @@ bool RouterLinux::isServiceActive(const QString &serviceName) {
bool RouterLinux::flushDns()
{
//check what the dns manager use
if (isServiceActive("nscd.service")) {
qDebug() << "Restarting nscd.service";
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
p.start("systemctl", { "restart", "nscd" });
if (!p.waitForFinished(3000)) {
qDebug() << "nscd restart timed out, killing process";
p.kill();
p.waitForFinished(500);
}
QByteArray output(p.readAll());
if (!output.isEmpty())
qDebug().noquote() << "OUTPUT systemctl restart nscd: " + output;
qDebug().noquote() << "Flush dns completed";
qDebug() << "Flushing nscd cache";
QProcess::startDetached("nscd", { "--invalidate=hosts" });
return true;
} else if (isServiceActive("systemd-resolved.service")) {
qDebug() << "Flushing systemd-resolved cache";