mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
GoodByeDPI support initial
This commit is contained in:
+1
-1
Submodule client/3rd-prebuilt updated: c38a587fcd...a7ec16db48
@@ -261,10 +261,12 @@ if(WIN32)
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(HEADERS ${HEADERS}
|
set(HEADERS ${HEADERS}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/goodbyedpi.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
set(SOURCES ${SOURCES}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/goodbyedpi.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerCon
|
|||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::None: return {};
|
case DockerContainer::None: return {};
|
||||||
|
|
||||||
|
case DockerContainer::GoodbyeDPI: return { Proto::GoodyeDPI };
|
||||||
|
|
||||||
case DockerContainer::OpenVpn: return { Proto::OpenVpn };
|
case DockerContainer::OpenVpn: return { Proto::OpenVpn };
|
||||||
|
|
||||||
case DockerContainer::ShadowSocks: return { Proto::OpenVpn, Proto::ShadowSocks };
|
case DockerContainer::ShadowSocks: return { Proto::OpenVpn, Proto::ShadowSocks };
|
||||||
@@ -97,6 +99,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
|||||||
{ DockerContainer::Xray, "XRay" },
|
{ DockerContainer::Xray, "XRay" },
|
||||||
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
||||||
{ DockerContainer::SSXray, "Shadowsocks"},
|
{ DockerContainer::SSXray, "Shadowsocks"},
|
||||||
|
{ DockerContainer::GoodbyeDPI, "GoodbyeDPI"},
|
||||||
|
|
||||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||||
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
||||||
@@ -136,7 +139,9 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
|||||||
{ DockerContainer::Sftp,
|
{ DockerContainer::Sftp,
|
||||||
QObject::tr("Create a file vault on your server to securely store and transfer files.") },
|
QObject::tr("Create a file vault on your server to securely store and transfer files.") },
|
||||||
{ DockerContainer::Socks5Proxy,
|
{ DockerContainer::Socks5Proxy,
|
||||||
QObject::tr("") } };
|
QObject::tr("") } ,
|
||||||
|
{ DockerContainer::GoodbyeDPI,
|
||||||
|
QObject::tr("GoodbueDPI --//DESRIPTION//--") }};
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||||
@@ -245,7 +250,9 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
|||||||
"You will be able to access it using\n FileZilla or other SFTP clients, "
|
"You will be able to access it using\n FileZilla or other SFTP clients, "
|
||||||
"as well as mount the disk on your device to access\n it directly from your device.\n\n"
|
"as well as mount the disk on your device to access\n it directly from your device.\n\n"
|
||||||
"For more detailed information, you can\n find it in the support section under \"Create SFTP file storage.\" ") },
|
"For more detailed information, you can\n find it in the support section under \"Create SFTP file storage.\" ") },
|
||||||
{ DockerContainer::Socks5Proxy, QObject::tr("SOCKS5 proxy server") }
|
{ DockerContainer::Socks5Proxy, QObject::tr("SOCKS5 proxy server") },
|
||||||
|
{ DockerContainer::GoodbyeDPI, QObject::tr("GoodbyeDPI --//DETAILED DESRIPTION//--") }
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,6 +278,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
|
|||||||
case DockerContainer::Dns: return Proto::Dns;
|
case DockerContainer::Dns: return Proto::Dns;
|
||||||
case DockerContainer::Sftp: return Proto::Sftp;
|
case DockerContainer::Sftp: return Proto::Sftp;
|
||||||
case DockerContainer::Socks5Proxy: return Proto::Socks5Proxy;
|
case DockerContainer::Socks5Proxy: return Proto::Socks5Proxy;
|
||||||
|
case DockerContainer::GoodbyeDPI: return Proto::GoodyeDPI;
|
||||||
default: return Proto::Any;
|
default: return Proto::Any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -377,6 +385,7 @@ bool ContainerProps::isShareable(DockerContainer container)
|
|||||||
case DockerContainer::Dns: return false;
|
case DockerContainer::Dns: return false;
|
||||||
case DockerContainer::Sftp: return false;
|
case DockerContainer::Sftp: return false;
|
||||||
case DockerContainer::Socks5Proxy: return false;
|
case DockerContainer::Socks5Proxy: return false;
|
||||||
|
case DockerContainer::GoodbyeDPI: return false;
|
||||||
default: return true;
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,6 +411,7 @@ int ContainerProps::installPageOrder(DockerContainer container)
|
|||||||
case DockerContainer::Xray: return 3;
|
case DockerContainer::Xray: return 3;
|
||||||
case DockerContainer::Ipsec: return 7;
|
case DockerContainer::Ipsec: return 7;
|
||||||
case DockerContainer::SSXray: return 8;
|
case DockerContainer::SSXray: return 8;
|
||||||
|
case DockerContainer::GoodbyeDPI: return 9;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace amnezia
|
|||||||
Ipsec,
|
Ipsec,
|
||||||
Xray,
|
Xray,
|
||||||
SSXray,
|
SSXray,
|
||||||
|
GoodbyeDPI,
|
||||||
|
|
||||||
// non-vpn
|
// non-vpn
|
||||||
TorWebSite,
|
TorWebSite,
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ ErrorCode VpnConfigurationsController::createProtocolConfigForContainer(const Se
|
|||||||
{
|
{
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||||
|
container == DockerContainer::GoodbyeDPI) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +62,8 @@ ErrorCode VpnConfigurationsController::createProtocolConfigString(const bool isA
|
|||||||
{
|
{
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||||
|
container == DockerContainer::GoodbyeDPI) {
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +84,8 @@ QJsonObject VpnConfigurationsController::createVpnConfiguration(const QPair<QStr
|
|||||||
{
|
{
|
||||||
QJsonObject vpnConfiguration {};
|
QJsonObject vpnConfiguration {};
|
||||||
|
|
||||||
if (ContainerProps::containerService(container) == ServiceType::Other) {
|
if (ContainerProps::containerService(container) == ServiceType::Other ||
|
||||||
|
container == DockerContainer::GoodbyeDPI) {
|
||||||
return vpnConfiguration;
|
return vpnConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ namespace amnezia
|
|||||||
ExecutableMissing = 604,
|
ExecutableMissing = 604,
|
||||||
XrayExecutableMissing = 605,
|
XrayExecutableMissing = 605,
|
||||||
Tun2SockExecutableMissing = 606,
|
Tun2SockExecutableMissing = 606,
|
||||||
|
GoodByeDPIExecutableMissing = 607,
|
||||||
|
|
||||||
// VPN errors
|
// VPN errors
|
||||||
OpenVpnAdaptersInUseError = 700,
|
OpenVpnAdaptersInUseError = 700,
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
#include "goodbyedpi.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
GoodbyeDPIProtocol::GoodbyeDPIProtocol(const QJsonObject &configuration, QObject* parent) :
|
||||||
|
VpnProtocol(configuration, parent)
|
||||||
|
{
|
||||||
|
qDebug() << "GoodbyeDPIProtocol::GoodbyeDPIProtocol()";
|
||||||
|
}
|
||||||
|
|
||||||
|
GoodbyeDPIProtocol::~GoodbyeDPIProtocol()
|
||||||
|
{
|
||||||
|
qDebug() << "GoodbyeDPIProtocol::~GoodbyeDPIProtocol()";
|
||||||
|
GoodbyeDPIProtocol::stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GoodbyeDPIProtocol::stop()
|
||||||
|
{
|
||||||
|
if (m_goodbyeDPIProcess) {
|
||||||
|
m_goodbyeDPIProcess->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode GoodbyeDPIProtocol::start()
|
||||||
|
{
|
||||||
|
qDebug() << "GoodbyeDPIProtocol::start()";
|
||||||
|
|
||||||
|
if (!QFileInfo::exists(Utils::goodbyedpiPath())) {
|
||||||
|
setLastError(ErrorCode::GoodByeDPIExecutableMissing);
|
||||||
|
return lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_goodbyeDPIProcess = IpcClient::CreatePrivilegedProcess();
|
||||||
|
|
||||||
|
if (!m_goodbyeDPIProcess) {
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_goodbyeDPIProcess->waitForSource(1000);
|
||||||
|
if (!m_goodbyeDPIProcess->isInitialized()) {
|
||||||
|
qWarning() << "IpcProcess replica is not connected!";
|
||||||
|
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||||
|
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_goodbyeDPIProcess->setProgram(PermittedProcess::GoodbyeDPI);
|
||||||
|
|
||||||
|
QStringList arguments({"-9", "--blacklist", "goodbyedpi/russia-blacklist.txt", "--blacklist", "goodbyedpi/russia-youtube.txt"});
|
||||||
|
|
||||||
|
m_goodbyeDPIProcess->setArguments(arguments);
|
||||||
|
qDebug() << arguments.join(" ");
|
||||||
|
|
||||||
|
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::errorOccurred,
|
||||||
|
[&](QProcess::ProcessError error) { qDebug() << "PrivilegedProcess errorOccurred" << error; });
|
||||||
|
|
||||||
|
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::stateChanged,
|
||||||
|
[&](QProcess::ProcessState newState) {
|
||||||
|
qDebug() << "PrivilegedProcess stateChanged" << newState;
|
||||||
|
if (newState == QProcess::Running)
|
||||||
|
{
|
||||||
|
setConnectionState(Vpn::ConnectionState::Connected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(m_goodbyeDPIProcess.data(), &PrivilegedProcess::finished, this,
|
||||||
|
[&]() {
|
||||||
|
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
m_goodbyeDPIProcess->start();
|
||||||
|
return ErrorCode::NoError;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef GOODBYEDPI_H
|
||||||
|
#define GOODBYEDPI_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QString>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "vpnprotocol.h"
|
||||||
|
#include "core/ipcclient.h"
|
||||||
|
|
||||||
|
class GoodbyeDPIProtocol : public VpnProtocol
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GoodbyeDPIProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
|
virtual ~GoodbyeDPIProtocol() override;
|
||||||
|
|
||||||
|
ErrorCode start() override;
|
||||||
|
void stop() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedPointer<PrivilegedProcess> m_goodbyeDPIProcess;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GOODBYEDPI_H
|
||||||
@@ -75,6 +75,7 @@ QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
|||||||
{ Proto::SSXray, "Shadowsocks"},
|
{ Proto::SSXray, "Shadowsocks"},
|
||||||
|
|
||||||
|
|
||||||
|
{ Proto::GoodyeDPI, "GoodbyeDPI"},
|
||||||
{ Proto::TorWebSite, "Website in Tor network" },
|
{ Proto::TorWebSite, "Website in Tor network" },
|
||||||
{ Proto::Dns, "DNS Service" },
|
{ Proto::Dns, "DNS Service" },
|
||||||
{ Proto::Sftp, QObject::tr("SFTP service") },
|
{ Proto::Sftp, QObject::tr("SFTP service") },
|
||||||
@@ -99,6 +100,7 @@ amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
|||||||
case Proto::Awg: return ServiceType::Vpn;
|
case Proto::Awg: return ServiceType::Vpn;
|
||||||
case Proto::Ikev2: return ServiceType::Vpn;
|
case Proto::Ikev2: return ServiceType::Vpn;
|
||||||
case Proto::Xray: return ServiceType::Vpn;
|
case Proto::Xray: return ServiceType::Vpn;
|
||||||
|
case Proto::GoodyeDPI: return ServiceType::Vpn;
|
||||||
|
|
||||||
case Proto::TorWebSite: return ServiceType::Other;
|
case Proto::TorWebSite: return ServiceType::Other;
|
||||||
case Proto::Dns: return ServiceType::Other;
|
case Proto::Dns: return ServiceType::Other;
|
||||||
|
|||||||
@@ -254,7 +254,8 @@ namespace amnezia
|
|||||||
TorWebSite,
|
TorWebSite,
|
||||||
Dns,
|
Dns,
|
||||||
Sftp,
|
Sftp,
|
||||||
Socks5Proxy
|
Socks5Proxy,
|
||||||
|
GoodyeDPI
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(Proto)
|
Q_ENUM_NS(Proto)
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
#include "ikev2_vpn_protocol_windows.h"
|
#include "ikev2_vpn_protocol_windows.h"
|
||||||
|
#include "goodbyedpi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
||||||
@@ -108,6 +109,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
|||||||
switch (container) {
|
switch (container) {
|
||||||
#if defined(Q_OS_WINDOWS)
|
#if defined(Q_OS_WINDOWS)
|
||||||
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
|
||||||
|
case DockerContainer::GoodbyeDPI: return new GoodbyeDPIProtocol(configuration);
|
||||||
#endif
|
#endif
|
||||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||||
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
|
||||||
|
|||||||
@@ -37,7 +37,13 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
|
|||||||
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
|
case EasySetupHeaderRole: return ContainerProps::easySetupHeader(container);
|
||||||
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
|
case EasySetupDescriptionRole: return ContainerProps::easySetupDescription(container);
|
||||||
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
|
case EasySetupOrderRole: return ContainerProps::easySetupOrder(container);
|
||||||
case IsInstalledRole: return m_containers.contains(container);
|
case IsInstalledRole: {
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
if (container == DockerContainer::GoodbyeDPI)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return m_containers.contains(container);
|
||||||
|
}
|
||||||
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
|
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
|
||||||
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
|
case IsSupportedRole: return ContainerProps::isSupportedByCurrentPlatform(container);
|
||||||
case IsShareableRole: return ContainerProps::isShareable(container);
|
case IsShareableRole: return ContainerProps::isShareable(container);
|
||||||
|
|||||||
@@ -214,6 +214,15 @@ QString Utils::certUtilPath()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Utils::goodbyedpiPath()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
return Utils::executable("goodbyedpi/goodbyedpi", true);
|
||||||
|
#else
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
QString Utils::tun2socksPath()
|
QString Utils::tun2socksPath()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public:
|
|||||||
static QString wireguardExecPath();
|
static QString wireguardExecPath();
|
||||||
static QString certUtilPath();
|
static QString certUtilPath();
|
||||||
static QString tun2socksPath();
|
static QString tun2socksPath();
|
||||||
|
static QString goodbyedpiPath();
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ enum PermittedProcess {
|
|||||||
OpenVPN,
|
OpenVPN,
|
||||||
Wireguard,
|
Wireguard,
|
||||||
Tun2Socks,
|
Tun2Socks,
|
||||||
CertUtil
|
CertUtil,
|
||||||
|
GoodbyeDPI
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QString permittedProcessPath(PermittedProcess pid)
|
inline QString permittedProcessPath(PermittedProcess pid)
|
||||||
@@ -27,6 +28,8 @@ inline QString permittedProcessPath(PermittedProcess pid)
|
|||||||
return Utils::certUtilPath();
|
return Utils::certUtilPath();
|
||||||
} else if (pid == PermittedProcess::Tun2Socks) {
|
} else if (pid == PermittedProcess::Tun2Socks) {
|
||||||
return Utils::tun2socksPath();
|
return Utils::tun2socksPath();
|
||||||
|
} else if (pid == PermittedProcess::GoodbyeDPI){
|
||||||
|
return Utils::goodbyedpiPath();
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user