fix: fixed xray config parsing in xrayprotocol (#2557)

This commit is contained in:
vkamn
2026-05-02 12:25:07 +08:00
committed by GitHub
parent b05ee0a654
commit 396ce23228
+38 -22
View File
@@ -1,16 +1,16 @@
#include "xrayProtocol.h" #include "xrayProtocol.h"
#include "core/protocols/protocolUtils.h"
#include "core/utils/constants/configKeys.h" #include "core/utils/constants/configKeys.h"
#include "core/utils/ipcClient.h" #include "core/utils/ipcClient.h"
#include "core/utils/networkUtilities.h" #include "core/utils/networkUtilities.h"
#include "core/protocols/protocolUtils.h"
#include "core/utils/serialization/serialization.h" #include "core/utils/serialization/serialization.h"
#include "ipc.h" #include "ipc.h"
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QNetworkInterface> #include <QNetworkInterface>
#include <QJsonDocument>
#include <QtCore/qlogging.h> #include <QtCore/qlogging.h>
#include <QtCore/qobjectdefs.h> #include <QtCore/qobjectdefs.h>
#include <QtCore/qprocess.h> #include <QtCore/qprocess.h>
@@ -43,7 +43,17 @@ XrayProtocol::XrayProtocol(const QJsonObject &configuration, QObject *parent) :
if (xrayConfiguration.isEmpty()) { if (xrayConfiguration.isEmpty()) {
xrayConfiguration = configuration.value(ProtocolUtils::key_proto_config_data(Proto::SSXray)).toObject(); xrayConfiguration = configuration.value(ProtocolUtils::key_proto_config_data(Proto::SSXray)).toObject();
} }
m_xrayConfig = xrayConfiguration;
if (xrayConfiguration.isEmpty()) {
qWarning() << "Xray config wrapper is empty";
m_xrayConfig = {};
}
m_xrayConfig = QJsonDocument::fromJson(xrayConfiguration.value(amnezia::configKey::config).toString().toUtf8()).object();
if (m_xrayConfig.isEmpty()) {
qWarning() << "Xray config string is not a valid JSON object";
m_xrayConfig = {};
}
} }
XrayProtocol::~XrayProtocol() XrayProtocol::~XrayProtocol()
@@ -75,16 +85,16 @@ ErrorCode XrayProtocol::start()
return ErrorCode::XrayExecutableCrashed; return ErrorCode::XrayExecutableCrashed;
} }
return IpcClient::withInterface([&](QSharedPointer<IpcInterfaceReplica> iface) { return IpcClient::withInterface(
[&](QSharedPointer<IpcInterfaceReplica> iface) {
auto xrayStart = iface->xrayStart(xrayConfigStr); auto xrayStart = iface->xrayStart(xrayConfigStr);
if (!xrayStart.waitForFinished() || !xrayStart.returnValue()) { if (!xrayStart.waitForFinished() || !xrayStart.returnValue()) {
qCritical() << "Failed to start xray"; qCritical() << "Failed to start xray";
return ErrorCode::XrayExecutableCrashed; return ErrorCode::XrayExecutableCrashed;
} }
return startTun2Socks(); return startTun2Socks();
}, [] () { },
return ErrorCode::AmneziaServiceConnectionFailed; []() { return ErrorCode::AmneziaServiceConnectionFailed; });
});
} }
void XrayProtocol::stop() void XrayProtocol::stop()
@@ -143,13 +153,14 @@ ErrorCode XrayProtocol::startTun2Socks()
return ErrorCode::AmneziaServiceConnectionFailed; return ErrorCode::AmneziaServiceConnectionFailed;
} }
const QString proxyUrl = QString("socks5://%1:%2@127.0.0.1:%3") const QString proxyUrl = QString("socks5://%1:%2@127.0.0.1:%3").arg(m_socksUser, m_socksPassword, QString::number(m_socksPort));
.arg(m_socksUser, m_socksPassword, QString::number(m_socksPort));
m_tun2socksProcess->setProgram(PermittedProcess::Tun2Socks); m_tun2socksProcess->setProgram(PermittedProcess::Tun2Socks);
m_tun2socksProcess->setArguments({"-device", QString("tun://%1").arg(tunName), "-proxy", proxyUrl}); m_tun2socksProcess->setArguments({ "-device", QString("tun://%1").arg(tunName), "-proxy", proxyUrl });
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() { connect(
m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this,
[this]() {
auto readAllStandardOutput = m_tun2socksProcess->readAllStandardOutput(); auto readAllStandardOutput = m_tun2socksProcess->readAllStandardOutput();
if (!readAllStandardOutput.waitForFinished()) { if (!readAllStandardOutput.waitForFinished()) {
qWarning() << "Failed to read output from tun2socks"; qWarning() << "Failed to read output from tun2socks";
@@ -171,9 +182,12 @@ ErrorCode XrayProtocol::startTun2Socks()
setConnectionState(Vpn::ConnectionState::Connected); setConnectionState(Vpn::ConnectionState::Connected);
} }
} }
}, Qt::QueuedConnection); },
Qt::QueuedConnection);
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::finished, this, [this](int exitCode, QProcess::ExitStatus exitStatus) { connect(
m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::finished, this,
[this](int exitCode, QProcess::ExitStatus exitStatus) {
if (exitStatus == QProcess::ExitStatus::CrashExit) { if (exitStatus == QProcess::ExitStatus::CrashExit) {
qCritical() << "Tun2socks process crashed!"; qCritical() << "Tun2socks process crashed!";
} else { } else {
@@ -181,14 +195,17 @@ ErrorCode XrayProtocol::startTun2Socks()
} }
stop(); stop();
setLastError(ErrorCode::Tun2SockExecutableCrashed); setLastError(ErrorCode::Tun2SockExecutableCrashed);
}, Qt::QueuedConnection); },
Qt::QueuedConnection);
m_tun2socksProcess->start(); m_tun2socksProcess->start();
return ErrorCode::NoError; return ErrorCode::NoError;
} }
ErrorCode XrayProtocol::setupRouting() { ErrorCode XrayProtocol::setupRouting()
return IpcClient::withInterface([this](QSharedPointer<IpcInterfaceReplica> iface) -> ErrorCode { {
return IpcClient::withInterface(
[this](QSharedPointer<IpcInterfaceReplica> iface) -> ErrorCode {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
const int inetAdapterIndex = NetworkUtilities::AdapterIndexTo(QHostAddress(m_remoteAddress)); const int inetAdapterIndex = NetworkUtilities::AdapterIndexTo(QHostAddress(m_remoteAddress));
#endif #endif
@@ -207,8 +224,8 @@ ErrorCode XrayProtocol::setupRouting() {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
int vpnAdapterIndex = -1; int vpnAdapterIndex = -1;
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces(); QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
for (auto& netInterface : netInterfaces) { for (auto &netInterface : netInterfaces) {
for (auto& address : netInterface.addressEntries()) { for (auto &address : netInterface.addressEntries()) {
if (m_vpnLocalAddress == address.ip().toString()) if (m_vpnLocalAddress == address.ip().toString())
vpnAdapterIndex = netInterface.index(); vpnAdapterIndex = netInterface.index();
} }
@@ -232,7 +249,8 @@ ErrorCode XrayProtocol::setupRouting() {
} }
if (m_routeMode == amnezia::RouteMode::VpnAllSites) { if (m_routeMode == amnezia::RouteMode::VpnAllSites) {
static const QStringList subnets = { "1.0.0.0/8", "2.0.0.0/7", "4.0.0.0/6", "8.0.0.0/5", "16.0.0.0/4", "32.0.0.0/3", "64.0.0.0/2", "128.0.0.0/1" }; static const QStringList subnets = { "1.0.0.0/8", "2.0.0.0/7", "4.0.0.0/6", "8.0.0.0/5",
"16.0.0.0/4", "32.0.0.0/3", "64.0.0.0/2", "128.0.0.0/1" };
auto routeAddList = iface->routeAddList(m_vpnGateway, subnets); auto routeAddList = iface->routeAddList(m_vpnGateway, subnets);
if (!routeAddList.waitForFinished() || routeAddList.returnValue() != subnets.count()) { if (!routeAddList.waitForFinished() || routeAddList.returnValue() != subnets.count()) {
@@ -265,7 +283,5 @@ ErrorCode XrayProtocol::setupRouting() {
#endif #endif
return ErrorCode::NoError; return ErrorCode::NoError;
}, },
[] () { []() { return ErrorCode::AmneziaServiceConnectionFailed; });
return ErrorCode::AmneziaServiceConnectionFailed;
});
} }