2021-01-10 20:37:57 +03:00
|
|
|
#include "shadowsocksvpnprotocol.h"
|
|
|
|
|
|
2021-01-15 23:36:35 +03:00
|
|
|
#include "debug.h"
|
|
|
|
|
#include "utils.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>
|
|
|
|
|
|
2021-02-18 15:00:41 +03:00
|
|
|
ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration, QObject *parent):
|
|
|
|
|
OpenVpnProtocol(configuration, parent)
|
2021-01-15 23:36:35 +03:00
|
|
|
{
|
2021-02-18 15:00:41 +03:00
|
|
|
readShadowSocksConfiguration(configuration);
|
2021-01-15 23:36:35 +03:00
|
|
|
}
|
|
|
|
|
|
2021-02-21 09:44:53 -08:00
|
|
|
ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol()
|
|
|
|
|
{
|
2021-03-18 18:45:08 +03:00
|
|
|
qDebug() << "ShadowSocksVpnProtocol::~ShadowSocksVpnProtocol";
|
2021-02-21 09:44:53 -08:00
|
|
|
ShadowSocksVpnProtocol::stop();
|
2021-03-18 18:45:08 +03:00
|
|
|
QThread::msleep(200);
|
2021-09-15 08:03:28 -07:00
|
|
|
#ifndef Q_OS_IOS
|
2021-03-18 18:45:08 +03:00
|
|
|
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
|
2021-03-18 18:45:08 +03:00
|
|
|
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
|
2021-03-18 18:45:08 +03:00
|
|
|
QStringList args = QStringList() << "-c" << m_shadowSocksCfgFile.fileName()
|
|
|
|
|
<< "--no-delay";
|
2021-08-04 10:08:00 -07:00
|
|
|
#endif
|
2021-03-18 18:45:08 +03:00
|
|
|
|
|
|
|
|
qDebug().noquote() << "ShadowSocksVpnProtocol::start()"
|
|
|
|
|
<< shadowSocksExecPath() << args.join(" ");
|
2021-01-15 23:36:35 +03:00
|
|
|
|
2021-02-18 15:00:41 +03:00
|
|
|
m_ssProcess.setProcessChannelMode(QProcess::MergedChannels);
|
2021-01-15 23:36:35 +03:00
|
|
|
|
2021-02-18 15:00:41 +03:00
|
|
|
m_ssProcess.setProgram(shadowSocksExecPath());
|
2021-03-18 18:45:08 +03:00
|
|
|
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;
|
2021-06-01 18:18:09 +03:00
|
|
|
setConnectionState(VpnProtocol::Disconnected);
|
2021-03-18 18:45:08 +03:00
|
|
|
if (exitStatus != QProcess::NormalExit){
|
|
|
|
|
emit protocolError(amnezia::ErrorCode::ShadowSocksExecutableCrashed);
|
|
|
|
|
stop();
|
|
|
|
|
}
|
|
|
|
|
if (exitCode !=0 ){
|
|
|
|
|
emit protocolError(amnezia::ErrorCode::InternalError);
|
|
|
|
|
stop();
|
|
|
|
|
}
|
2021-02-18 15:00:41 +03:00
|
|
|
});
|
2021-01-15 23:36:35 +03:00
|
|
|
|
2021-02-18 15:00:41 +03:00
|
|
|
m_ssProcess.start();
|
|
|
|
|
m_ssProcess.waitForStarted();
|
|
|
|
|
|
|
|
|
|
if (m_ssProcess.state() == QProcess::ProcessState::Running) {
|
2021-11-30 21:51:06 +03:00
|
|
|
setConnectionState(VpnConnectionState::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
|
|
|
{
|
2021-02-18 15:00:41 +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
|
2021-03-18 18:45:08 +03:00
|
|
|
m_ssProcess.terminate();
|
2021-09-15 08:03:28 -07:00
|
|
|
#endif
|
2021-03-18 18:45:08 +03:00
|
|
|
|
|
|
|
|
#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
|
|
|
|
2021-03-18 18:45:08 +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);
|
2021-08-04 10:08:00 -07:00
|
|
|
#elif defined Q_OS_LINUX
|
|
|
|
|
return Utils::usrExecutable(QString("ss-local"));
|
2021-01-15 23:36:35 +03:00
|
|
|
#else
|
|
|
|
|
return Utils::executable(QString("/ss-local"), true);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-18 15:00:41 +03:00
|
|
|
void ShadowSocksVpnProtocol::readShadowSocksConfiguration(const QJsonObject &configuration)
|
|
|
|
|
{
|
2021-11-30 21:51:06 +03:00
|
|
|
m_shadowSocksConfig = configuration.value(ProtocolProps::key_proto_config_data(Proto::ShadowSocks)).toObject();
|
2021-01-10 20:37:57 +03:00
|
|
|
}
|