mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-20 02:00:55 +07:00
fix: add support system with nscd service
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
Reference in New Issue
Block a user