Compare commits

..

1 Commits

Author SHA1 Message Date
lunardunno
4edc9eacbb Unblock IPsec Connection for Linux 2025-08-15 09:53:59 +04:00
19 changed files with 96 additions and 137 deletions

View File

@@ -53,16 +53,14 @@ AmneziaApplication::~AmneziaApplication()
{
if (m_vpnConnection) {
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::QueuedConnection);
QThread::msleep(2000);
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectSlots", Qt::QueuedConnection);
QMetaObject::invokeMethod(m_vpnConnection.get(), "deleteLater", Qt::QueuedConnection);
}
m_vpnConnectionThread.requestInterruption();
m_vpnConnectionThread.quit();
if (!m_vpnConnectionThread.wait(3000)) {
if (!m_vpnConnectionThread.wait(5000)) {
m_vpnConnectionThread.terminate();
m_vpnConnectionThread.wait(500);
m_vpnConnectionThread.wait();
}
if (m_engine) {

View File

@@ -308,10 +308,7 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
}
#elif defined(Q_OS_LINUX)
switch (c) {
case DockerContainer::Ipsec: return false;
default: return true;
}
return true;
#else
return false;

View File

@@ -85,9 +85,8 @@ bool IpcClient::init(IpcClient *instance)
}
qDebug() << "IpcClient::init succeed";
instance->m_isSocketConnected = (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid());
return Instance()->isSocketConnected();
return (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid());
}
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()

View File

@@ -56,8 +56,7 @@ void OpenVpnProtocol::stop()
}
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch();
disableKillSwitchResp.waitForFinished(1000);
IpcClient::Interface()->disableKillSwitch();
#endif
setConnectionState(Vpn::ConnectionState::Disconnected);

View File

@@ -167,10 +167,8 @@ ErrorCode XrayProtocol::startTun2Sock()
void XrayProtocol::stop()
{
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch();
disableKillSwitchResp.waitForFinished(1000);
QRemoteObjectPendingReply<bool> StartRoutingIpv6Resp = IpcClient::Interface()->StartRoutingIpv6();
StartRoutingIpv6Resp.waitForFinished(1000);
IpcClient::Interface()->disableKillSwitch();
IpcClient::Interface()->StartRoutingIpv6();
#endif
qDebug() << "XrayProtocol::stop()";
m_xrayProcess.disconnect();
@@ -178,7 +176,6 @@ void XrayProtocol::stop()
m_xrayProcess.waitForFinished(3000);
if (m_t2sProcess) {
m_t2sProcess->stop();
QThread::msleep(200);
}
setConnectionState(Vpn::ConnectionState::Disconnected);

View File

@@ -32,8 +32,8 @@
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
{
#if defined(Q_OS_IOS) || defined(MACOS_NE)
m_checkTimer.setInterval(1000);
#if defined(Q_OS_IOS) || defined(MACOS_NE)
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
@@ -42,6 +42,9 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent
VpnConnection::~VpnConnection()
{
#if defined AMNEZIA_DESKTOP
disconnectFromVpn();
#endif
}
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
@@ -52,7 +55,19 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
void VpnConnection::onKillSwitchModeChanged(bool enabled)
{
#ifdef AMNEZIA_DESKTOP
if (InterfaceReady()) {
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return;
}
}
if (IpcClient::Interface()) {
qDebug() << "Set KillSwitch Strict mode enabled " << enabled;
IpcClient::Interface()->refreshKillSwitch(enabled);
}
@@ -65,7 +80,7 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
#ifdef AMNEZIA_DESKTOP
auto container = m_settings->defaultContainer(m_settings->defaultServerIndex());
if (InterfaceReady()) {
if (IpcClient::Interface()) {
if (state == Vpn::ConnectionState::Connected) {
IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns();
@@ -197,41 +212,14 @@ void VpnConnection::deleteRoutes(const QStringList &ips)
#endif
}
bool VpnConnection::InterfaceReady()
{
#ifdef AMNEZIA_DESKTOP
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return false;
}
}
return IpcClient::Interface() != nullptr;
#endif
return true;
}
void VpnConnection::flushDns()
{
#ifdef AMNEZIA_DESKTOP
if (InterfaceReady())
if (IpcClient::Interface())
IpcClient::Interface()->flushDns();
#endif
}
void VpnConnection::disconnectSlots()
{
if (m_vpnProtocol) {
m_vpnProtocol->disconnect();
}
}
ErrorCode VpnConnection::lastError() const
{
#ifdef Q_OS_ANDROID
@@ -252,12 +240,21 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
.arg(serverIndex)
.arg(ContainerProps::containerToString(container))
<< m_settings->routeMode();
if (!InterfaceReady()) {
emit connectionStateChanged(Vpn::ConnectionState::Error);
return;
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
emit connectionStateChanged(Vpn::ConnectionState::Error);
return;
}
}
#endif
m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName);
emit connectionStateChanged(Vpn::ConnectionState::Connecting);
@@ -443,18 +440,13 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
void VpnConnection::disconnectFromVpn()
{
#ifdef AMNEZIA_DESKTOP
if (InterfaceReady()) {
QString proto = m_settings->defaultContainerName(m_settings->defaultServerIndex());
if (IpcClient::Interface()) {
IpcClient::Interface()->flushDns();
m_vpnProtocol.data()->stop();
qDebug() << "Interface is ready!";
QRemoteObjectPendingReply<bool> flushDnsResp = IpcClient::Interface()->flushDns();
flushDnsResp.waitForFinished(1000);
qDebug() << "Flushed DNS";
// delete cached routes
QRemoteObjectPendingReply<bool> clearSavedRoutesResp = IpcClient::Interface()->clearSavedRoutes();
clearSavedRoutesResp.waitForFinished(1000);
QRemoteObjectPendingReply<bool> response = IpcClient::Interface()->clearSavedRoutes();
response.waitForFinished(1000);
}
#endif
@@ -483,13 +475,12 @@ void VpnConnection::disconnectFromVpn()
return;
}
#if !defined(Q_OS_ANDROID) && !defined(AMNEZIA_DESKTOP)
#ifndef Q_OS_ANDROID
if (m_vpnProtocol) {
m_vpnProtocol->deleteLater();
}
#endif
m_vpnProtocol = nullptr;
#endif
}
Vpn::ConnectionState VpnConnection::connectionState()

View File

@@ -56,7 +56,6 @@ public slots:
void deleteRoutes(const QStringList &ips);
void flushDns();
void onKillSwitchModeChanged(bool enabled);
void disconnectSlots();
signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
@@ -96,7 +95,6 @@ private:
void appendSplitTunnelingConfig();
void appendKillSwitchConfig();
bool InterfaceReady();
};
#endif // VPNCONNECTION_H

View File

@@ -12,7 +12,7 @@ class IpcInterface
SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
SLOT( bool clearSavedRoutes() );
SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) );
SLOT( bool flushDns() );
SLOT( void flushDns() );
SLOT( void resetIpStack() );
SLOT( bool checkAndInstallDriver() );
@@ -25,8 +25,8 @@ class IpcInterface
SLOT( bool createTun(const QString &dev, const QString &subnet) );
SLOT( bool deleteTun(const QString &dev) );
SLOT( bool StartRoutingIpv6() );
SLOT( bool StopRoutingIpv6() );
SLOT( void StartRoutingIpv6() );
SLOT( void StopRoutingIpv6() );
SLOT( bool disableKillSwitch() );
SLOT( bool disableAllTraffic() );

View File

@@ -83,7 +83,7 @@ bool IpcServer::routeDeleteList(const QString &gw, const QStringList &ips)
return Router::routeDeleteList(gw, ips);
}
bool IpcServer::flushDns()
void IpcServer::flushDns()
{
#ifdef MZ_DEBUG
qDebug() << "IpcServer::flushDns";
@@ -157,13 +157,13 @@ bool IpcServer::updateResolvers(const QString &ifname, const QList<QHostAddress>
return Router::updateResolvers(ifname, resolvers);
}
bool IpcServer::StartRoutingIpv6()
void IpcServer::StartRoutingIpv6()
{
return Router::StartRoutingIpv6();
Router::StartRoutingIpv6();
}
bool IpcServer::StopRoutingIpv6()
void IpcServer::StopRoutingIpv6()
{
return Router::StopRoutingIpv6();
Router::StopRoutingIpv6();
}
void IpcServer::setLogsEnabled(bool enabled)

View File

@@ -23,7 +23,7 @@ public:
virtual int routeAddList(const QString &gw, const QStringList &ips) override;
virtual bool clearSavedRoutes() override;
virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override;
virtual bool flushDns() override;
virtual void flushDns() override;
virtual void resetIpStack() override;
virtual bool checkAndInstallDriver() override;
virtual QStringList getTapList() override;
@@ -32,8 +32,8 @@ public:
virtual void setLogsEnabled(bool enabled) override;
virtual bool createTun(const QString &dev, const QString &subnet) override;
virtual bool deleteTun(const QString &dev) override;
virtual bool StartRoutingIpv6() override;
virtual bool StopRoutingIpv6() override;
virtual void StartRoutingIpv6() override;
virtual void StopRoutingIpv6() override;
virtual bool disableAllTraffic() override;
virtual bool addKillSwitchAllowedRange(QStringList ranges) override;
virtual bool resetKillSwitchAllowedRange(QStringList ranges) override;

View File

@@ -98,17 +98,6 @@ bool KillSwitch::disableKillSwitch() {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
} else {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("000.allowLoopback"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("300.allowLAN"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("310.blockDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
LinuxFirewall::uninstall();
}
#endif

View File

@@ -42,14 +42,14 @@ int Router::routeDeleteList(const QString &gw, const QStringList &ips)
#endif
}
bool Router::flushDns()
void Router::flushDns()
{
#ifdef Q_OS_WIN
return RouterWin::Instance().flushDns();
RouterWin::Instance().flushDns();
#elif defined (Q_OS_MAC)
return RouterMac::Instance().flushDns();
RouterMac::Instance().flushDns();
#elif defined Q_OS_LINUX
return RouterLinux::Instance().flushDns();
RouterLinux::Instance().flushDns();
#endif
}
@@ -100,25 +100,25 @@ bool Router::updateResolvers(const QString& ifname, const QList<QHostAddress>& r
}
bool Router::StopRoutingIpv6()
void Router::StopRoutingIpv6()
{
#ifdef Q_OS_WIN
return RouterWin::Instance().StopRoutingIpv6();
RouterWin::Instance().StopRoutingIpv6();
#elif defined (Q_OS_MAC)
return true;// todo fixme
// todo fixme
#elif defined Q_OS_LINUX
return RouterLinux::Instance().StopRoutingIpv6();
RouterLinux::Instance().StopRoutingIpv6();
#endif
}
bool Router::StartRoutingIpv6()
void Router::StartRoutingIpv6()
{
#ifdef Q_OS_WIN
return RouterWin::Instance().StartRoutingIpv6();
RouterWin::Instance().StartRoutingIpv6();
#elif defined (Q_OS_MAC)
return true;// todo fixme
// todo fixme
#elif defined Q_OS_LINUX
return RouterLinux::Instance().StartRoutingIpv6();
RouterLinux::Instance().StartRoutingIpv6();
#endif
}

View File

@@ -19,12 +19,12 @@ public:
static int routeAddList(const QString &gw, const QStringList &ips);
static bool clearSavedRoutes();
static int routeDeleteList(const QString &gw, const QStringList &ips);
static bool flushDns();
static void flushDns();
static void resetIpStack();
static bool createTun(const QString &dev, const QString &subnet);
static bool deleteTun(const QString &dev);
static bool StartRoutingIpv6();
static bool StopRoutingIpv6();
static void StartRoutingIpv6();
static void StopRoutingIpv6();
static bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
};

View File

@@ -160,7 +160,7 @@ bool RouterLinux::isServiceActive(const QString &serviceName) {
return process.exitCode() == 0;
}
bool RouterLinux::flushDns()
void RouterLinux::flushDns()
{
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
@@ -174,7 +174,7 @@ bool RouterLinux::flushDns()
p.start("systemctl", { "restart", "systemd-resolved" });
} else {
qDebug() << "No suitable DNS manager found.";
return false;
return;
}
p.waitForFinished();
@@ -183,8 +183,6 @@ bool RouterLinux::flushDns()
qDebug().noquote() << "Flush dns completed";
else
qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output;
return true;
}
bool RouterLinux::createTun(const QString &dev, const QString &subnet) {
@@ -281,7 +279,7 @@ bool RouterLinux::updateResolvers(const QString& ifname, const QList<QHostAddres
return m_dnsUtil->updateResolvers(ifname, resolvers);
}
bool RouterLinux::StartRoutingIpv6()
void RouterLinux::StartRoutingIpv6()
{
QProcess process;
QStringList commands;
@@ -291,12 +289,12 @@ bool RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not start activate ipv6\n";
return false;
return;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not activate ipv6\n";
return false;
return;
}
commands.clear();
@@ -305,20 +303,19 @@ bool RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not start activate ipv6\n";
return false;
return;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not activate ipv6\n";
return false;
return;
}
commands.clear();
qDebug().noquote() << "StartRoutingIpv6 OK";
return true;
}
bool RouterLinux::StopRoutingIpv6()
void RouterLinux::StopRoutingIpv6()
{
QProcess process;
QStringList commands;
@@ -328,12 +325,12 @@ bool RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not start disable ipv6\n";
return false;
return;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not disable ipv6\n";
return false;
return;
}
commands.clear();
@@ -342,15 +339,14 @@ bool RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000))
{
qDebug().noquote() << "Could not start disable ipv6\n";
return false;
return;
}
else if (!process.waitForFinished(2000))
{
qDebug().noquote() << "Could not disable ipv6\n";
return false;
return;
}
commands.clear();
qDebug().noquote() << "StopRoutingIpv6 OK";
return true;
}

View File

@@ -30,11 +30,11 @@ public:
bool routeDelete(const QString &ip, const QString &gw, const int &sock);
bool routeDeleteList(const QString &gw, const QStringList &ips);
QString getgatewayandiface();
bool flushDns();
void flushDns();
bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev);
bool StartRoutingIpv6();
bool StopRoutingIpv6();
void StartRoutingIpv6();
void StopRoutingIpv6();
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
public slots:

View File

@@ -166,7 +166,7 @@ bool RouterMac::deleteTun(const QString &dev)
return true;
}
bool RouterMac::flushDns()
void RouterMac::flushDns()
{
// sudo killall -HUP mDNSResponder
QProcess p;
@@ -174,7 +174,5 @@ bool RouterMac::flushDns()
p.start("killall", QStringList() << "-HUP" << "mDNSResponder");
p.waitForFinished();
qDebug().noquote() << "OUTPUT killall -HUP mDNSResponder: " + p.readAll();
return true;
}

View File

@@ -29,7 +29,7 @@ public:
bool clearSavedRoutes();
bool routeDelete(const QString &ip, const QString &gw);
bool routeDeleteList(const QString &gw, const QStringList &ips);
bool flushDns();
void flushDns();
bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);

View File

@@ -273,7 +273,7 @@ int RouterWin::routeDeleteList(const QString &gw, const QStringList &ips)
return success_count;
}
bool RouterWin::flushDns()
void RouterWin::flushDns()
{
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
@@ -281,7 +281,6 @@ bool RouterWin::flushDns()
p.start(command);
p.waitForFinished();
return true;
//qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll();
}
@@ -445,7 +444,7 @@ bool RouterWin::updateResolvers(const QString& ifname, const QList<QHostAddress>
}
bool RouterWin::StopRoutingIpv6()
void RouterWin::StopRoutingIpv6()
{
{
QProcess p;
@@ -465,10 +464,9 @@ bool RouterWin::StopRoutingIpv6()
p.start(command);
p.waitForFinished();
}
return true;
}
bool RouterWin::StartRoutingIpv6()
void RouterWin::StartRoutingIpv6()
{
{
QProcess p;
@@ -488,6 +486,5 @@ bool RouterWin::StartRoutingIpv6()
p.start(command);
p.waitForFinished();
}
return true;
}

View File

@@ -39,11 +39,11 @@ public:
int routeAddList(const QString &gw, const QStringList &ips);
bool clearSavedRoutes();
int routeDeleteList(const QString &gw, const QStringList &ips);
bool flushDns();
void flushDns();
void resetIpStack();
bool StartRoutingIpv6();
bool StopRoutingIpv6();
void StartRoutingIpv6();
void StopRoutingIpv6();
void suspendWcmSvc(bool suspend);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);