Files
DefaultVPN/client/protocols/shadowsocksvpnprotocol.cpp

133 lines
4.1 KiB
C++
Raw Permalink Normal View History

2021-01-10 20:37:57 +03:00
#include "shadowsocksvpnprotocol.h"
2022-12-28 13:41:45 +03:00
#include "logger.h"
#include "utilities.h"
2021-09-09 20:15:44 +03:00
#include "containers/containers_defs.h"
2021-01-15 23:36:35 +03:00
2021-03-13 14:16:24 +03:00
#include <QCryptographicHash>
2021-01-15 23:36:35 +03:00
#include <QJsonDocument>
#include <QJsonObject>
ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration, QObject *parent):
OpenVpnProtocol(configuration, parent)
2021-01-15 23:36:35 +03:00
{
readShadowSocksConfiguration(configuration);
2021-01-15 23:36:35 +03:00
}
2021-02-21 09:44:53 -08:00
ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol()
{
qDebug() << "ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol";
2021-02-21 09:44:53 -08:00
ShadowSocksVpnProtocol::stop();
QThread::msleep(200);
2021-09-15 08:03:28 -07:00
#ifndef Q_OS_IOS
m_ssProcess.close();
2021-09-15 08:03:28 -07:00
#endif
2021-02-21 09:44:53 -08:00
}
2021-01-15 23:36:35 +03:00
ErrorCode ShadowSocksVpnProtocol::start()
{
2022-08-09 18:44:05 +04:00
if (!QFileInfo::exists(shadowSocksExecPath())) {
setLastError(ErrorCode::ShadowSocksExecutableMissing);
return lastError();
}
2021-09-15 08:03:28 -07:00
#ifndef Q_OS_IOS
if (Utils::processIsRunning(Utils::executable("ss-local", false))) {
Utils::killProcessByName(Utils::executable("ss-local", false));
}
#ifdef QT_DEBUG
m_shadowSocksCfgFile.setAutoRemove(false);
#endif
m_shadowSocksCfgFile.open();
m_shadowSocksCfgFile.write(QJsonDocument(m_shadowSocksConfig).toJson());
m_shadowSocksCfgFile.close();
2021-08-04 10:08:00 -07:00
#ifdef Q_OS_LINUX
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName();
#else
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName()
<< "--no-delay";
2021-08-04 10:08:00 -07:00
#endif
qDebug().noquote() << "ShadowSocksVpnProtocol::start()"
<< shadowSocksExecPath() << args.join(" ");
2021-01-15 23:36:35 +03:00
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
2021-01-15 23:36:35 +03:00
m_ssProcess.setProgram(shadowSocksExecPath());
m_ssProcess.setArguments(args);
connect(&m_ssProcess, &QProcess::readyReadStandardOutput, this, [this](){
qDebug().noquote() << "ss-local:" << m_ssProcess.readAllStandardOutput();
});
connect(&m_ssProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus){
qDebug().noquote() << "ShadowSocksVpnProtocol finished, exitCode, exiStatus" << exitCode << exitStatus;
setConnectionState(Vpn::ConnectionState::Disconnected);
if (exitStatus != QProcess::NormalExit){
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
stop();
}
if (exitCode !=0 ){
emit protocolError(amnezia::ErrorCode::InternalError);
stop();
}
});
2021-01-15 23:36:35 +03:00
m_ssProcess.start();
m_ssProcess.waitForStarted();
if (m_ssProcess.state() == QProcess::ProcessState::Running) {
setConnectionState(Vpn::ConnectionState::Connecting);
2021-01-15 23:36:35 +03:00
return OpenVpnProtocol::start();
}
2021-02-21 09:44:53 -08:00
else return ErrorCode::ShadowSocksExecutableMissing;
2021-09-15 08:03:28 -07:00
#else
return ErrorCode::NotImplementedError;
#endif
2021-01-15 23:36:35 +03:00
}
void ShadowSocksVpnProtocol::stop()
2021-01-10 20:37:57 +03:00
{
OpenVpnProtocol::stop();
2021-01-15 23:36:35 +03:00
qDebug() << "ShadowSocksVpnProtocol::stop()";
2021-09-15 08:03:28 -07:00
#ifndef Q_OS_IOS
m_ssProcess.terminate();
2021-09-15 08:03:28 -07:00
#endif
#ifdef Q_OS_WIN
Utils::signalCtrl(m_ssProcess.processId(), CTRL_C_EVENT);
#endif
2021-01-15 23:36:35 +03:00
}
2021-01-10 20:37:57 +03:00
QString ShadowSocksVpnProtocol::shadowSocksExecPath()
2021-01-15 23:36:35 +03:00
{
#ifdef Q_OS_WIN
return Utils::executable(QString("ss/ss-local"), true);
#else
return Utils::executable(QString("/ss-local"), true);
#endif
}
void ShadowSocksVpnProtocol::readShadowSocksConfiguration(const QJsonObject &configuration)
{
QJsonObject shadowSocksConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::ShadowSocks)).toObject();
bool isLocalPortConvertOk = false;
bool isServerPortConvertOk = false;
int localPort = shadowSocksConfig.value("local_port").toString().toInt(&isLocalPortConvertOk);
int serverPort = shadowSocksConfig.value("server_port").toString().toInt(&isServerPortConvertOk);
if (!isLocalPortConvertOk) {
qDebug() << "Error when converting local_port field in ShadowSocks config";
} else if (!isServerPortConvertOk) {
qDebug() << "Error when converting server_port field in ShadowSocks config";
}
shadowSocksConfig["local_port"] = localPort;
shadowSocksConfig["server_port"] = serverPort;
m_shadowSocksConfig = shadowSocksConfig;
2021-01-10 20:37:57 +03:00
}