mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +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"
|
#include "dnsutilslinux.h"
|
||||||
|
|
||||||
@@ -26,7 +23,6 @@ DnsUtilsLinux::~DnsUtilsLinux() {
|
|||||||
logger.debug() << "DnsUtilsLinux destroyed.";
|
logger.debug() << "DnsUtilsLinux destroyed.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DnsUtilsLinux::writeResolvConf(const QList<QHostAddress>& resolvers) {
|
void DnsUtilsLinux::writeResolvConf(const QList<QHostAddress>& resolvers) {
|
||||||
if (resolvers.isEmpty()) return;
|
if (resolvers.isEmpty()) return;
|
||||||
|
|
||||||
@@ -38,17 +34,29 @@ void DnsUtilsLinux::writeResolvConf(const QList<QHostAddress>& resolvers) {
|
|||||||
m_resolvConfOriginal = fi.symLinkTarget();
|
m_resolvConfOriginal = fi.symLinkTarget();
|
||||||
logger.debug() << "Saved resolv.conf symlink target:"
|
logger.debug() << "Saved resolv.conf symlink target:"
|
||||||
<< m_resolvConfOriginal;
|
<< m_resolvConfOriginal;
|
||||||
} else {
|
|
||||||
m_resolvConfOriginal = QStringLiteral("__file__");
|
|
||||||
logger.debug()
|
|
||||||
<< "resolv.conf is a regular file; will restore stub on disconnect";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_stateFilePath.isEmpty()) {
|
if (!m_stateFilePath.isEmpty()) {
|
||||||
QFile sf(m_stateFilePath);
|
QFile sf(m_stateFilePath);
|
||||||
if (sf.open(QIODevice::WriteOnly | QIODevice::Text))
|
if (sf.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||||
sf.write(m_resolvConfOriginal.toUtf8());
|
sf.write(m_resolvConfOriginal.toUtf8());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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__");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile::remove(kPath);
|
QFile::remove(kPath);
|
||||||
@@ -81,16 +89,25 @@ void DnsUtilsLinux::restoreResolvConf() {
|
|||||||
QFile::remove(m_stateFilePath);
|
QFile::remove(m_stateFilePath);
|
||||||
|
|
||||||
static const char* kPath = "/etc/resolv.conf";
|
static const char* kPath = "/etc/resolv.conf";
|
||||||
static const char* kStub = "/run/systemd/resolve/stub-resolv.conf";
|
|
||||||
|
|
||||||
QFile::remove(kPath);
|
QFile::remove(kPath);
|
||||||
|
|
||||||
const QString target = (original == QStringLiteral("__file__"))
|
if (original == QStringLiteral("__file__")) {
|
||||||
? QLatin1String(kStub)
|
if (!m_resolvConfSavedContent.isEmpty()) {
|
||||||
: original;
|
QFile f(kPath);
|
||||||
|
if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
QFile::link(target, kPath);
|
f.write(m_resolvConfSavedContent.toUtf8());
|
||||||
logger.debug() << "Restored resolv.conf symlink to" << target;
|
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,
|
bool DnsUtilsLinux::updateResolvers(const QString& ifname,
|
||||||
@@ -114,6 +131,7 @@ bool DnsUtilsLinux::restoreResolvers() {
|
|||||||
if (!m_stateFilePath.isEmpty()) {
|
if (!m_stateFilePath.isEmpty()) {
|
||||||
candidates << m_stateFilePath;
|
candidates << m_stateFilePath;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
QDir runDir(QStringLiteral("/run"));
|
QDir runDir(QStringLiteral("/run"));
|
||||||
for (const QString& name : runDir.entryList(
|
for (const QString& name : runDir.entryList(
|
||||||
{QStringLiteral("amnezia-dns-*")}, QDir::Files)) {
|
{QStringLiteral("amnezia-dns-*")}, QDir::Files)) {
|
||||||
@@ -122,10 +140,16 @@ bool DnsUtilsLinux::restoreResolvers() {
|
|||||||
}
|
}
|
||||||
for (const QString& path : candidates) {
|
for (const QString& path : candidates) {
|
||||||
QFile sf(path);
|
QFile sf(path);
|
||||||
if (sf.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (sf.open(QIODevice::ReadOnly)) {
|
||||||
m_resolvConfOriginal = QString::fromUtf8(sf.readAll()).trimmed();
|
QByteArray data = sf.readAll();
|
||||||
m_stateFilePath = path;
|
|
||||||
sf.close();
|
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 << ":"
|
logger.debug() << "Recovered DNS original from" << path << ":"
|
||||||
<< m_resolvConfOriginal;
|
<< m_resolvConfOriginal;
|
||||||
break;
|
break;
|
||||||
@@ -136,7 +160,7 @@ bool DnsUtilsLinux::restoreResolvers() {
|
|||||||
const bool hadDnsState = !m_resolvConfOriginal.isEmpty();
|
const bool hadDnsState = !m_resolvConfOriginal.isEmpty();
|
||||||
restoreResolvConf();
|
restoreResolvConf();
|
||||||
|
|
||||||
if (hadDnsState) {
|
if (hadDnsState && QFile::exists(QStringLiteral("/run/systemd/resolve"))) {
|
||||||
QProcess::startDetached("systemctl", {"restart", "systemd-resolved"});
|
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
|
#ifndef DNSUTILSLINUX_H
|
||||||
#define DNSUTILSLINUX_H
|
#define DNSUTILSLINUX_H
|
||||||
@@ -27,8 +24,10 @@ class DnsUtilsLinux final : public DnsUtils {
|
|||||||
void restoreResolvConf();
|
void restoreResolvConf();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QString m_resolvConfOriginal;
|
QString m_resolvConfOriginal;
|
||||||
|
QString m_resolvConfSavedContent;
|
||||||
QString m_stateFilePath;
|
QString m_stateFilePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DNSUTILSLINUX_H
|
#endif
|
||||||
|
|||||||
@@ -41,15 +41,14 @@ bool RouterLinux::routeAdd(const QString &ipWithSubnet, const QString &gw, const
|
|||||||
struct rtentry route;
|
struct rtentry route;
|
||||||
memset(&route, 0, sizeof( 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_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_addr.s_addr = inet_addr(gw.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_gateway)->sin_port = 0;
|
((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_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_addr.s_addr = inet_addr(ip.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_dst)->sin_port = 0;
|
((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_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_addr.s_addr = inet_addr(mask.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_genmask)->sin_port = 0;
|
((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;
|
struct rtentry route;
|
||||||
memset(&route, 0, sizeof( 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_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_addr.s_addr = inet_addr(gw.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_gateway)->sin_port = 0;
|
((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_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_addr.s_addr = inet_addr(ip.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_dst)->sin_port = 0;
|
((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_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_addr.s_addr = inet_addr(mask.toStdString().c_str());
|
||||||
((struct sockaddr_in *)&route.rt_genmask)->sin_port = 0;
|
((struct sockaddr_in *)&route.rt_genmask)->sin_port = 0;
|
||||||
|
|
||||||
route.rt_flags = RTF_UP | RTF_GATEWAY;
|
route.rt_flags = RTF_UP | RTF_GATEWAY;
|
||||||
route.rt_metric = 0;
|
route.rt_metric = 0;
|
||||||
//route.rt_dev = "ens33";
|
|
||||||
|
|
||||||
if (ioctl(sock, SIOCDELRT, &route) < 0)
|
if (ioctl(sock, SIOCDELRT, &route) < 0)
|
||||||
{
|
{
|
||||||
@@ -164,21 +161,10 @@ bool RouterLinux::isServiceActive(const QString &serviceName) {
|
|||||||
|
|
||||||
bool RouterLinux::flushDns()
|
bool RouterLinux::flushDns()
|
||||||
{
|
{
|
||||||
//check what the dns manager use
|
|
||||||
if (isServiceActive("nscd.service")) {
|
if (isServiceActive("nscd.service")) {
|
||||||
qDebug() << "Restarting nscd.service";
|
qDebug() << "Flushing nscd cache";
|
||||||
QProcess p;
|
QProcess::startDetached("nscd", { "--invalidate=hosts" });
|
||||||
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";
|
|
||||||
return true;
|
return true;
|
||||||
} else if (isServiceActive("systemd-resolved.service")) {
|
} else if (isServiceActive("systemd-resolved.service")) {
|
||||||
qDebug() << "Flushing systemd-resolved cache";
|
qDebug() << "Flushing systemd-resolved cache";
|
||||||
|
|||||||
Reference in New Issue
Block a user