fixed default var

This commit is contained in:
dranik
2026-05-22 15:17:39 +03:00
parent ba2382924d
commit dec410016e
5 changed files with 202 additions and 58 deletions
+17 -1
View File
@@ -201,6 +201,14 @@ ErrorCode XrayConfigurator::applyServerSettingsToRemote(const ServerCredentials
} }
const XrayServerConfig &srv = xrayCfg->serverConfig; const XrayServerConfig &srv = xrayCfg->serverConfig;
if (srv.isThirdPartyConfig) {
logger.info() << "Xray applyServerSettings: skipped (third-party/native profile)";
if (outClientId && xrayCfg->hasClientConfig()) {
*outClientId = xrayCfg->clientConfig->id;
}
return ErrorCode::NoError;
}
logger.info() << "Xray applyServerSettings: start" logger.info() << "Xray applyServerSettings: start"
<< "container=" << static_cast<int>(container) << "host=" << credentials.hostName << "container=" << static_cast<int>(container) << "host=" << credentials.hostName
<< "transport=" << srv.transport << "security=" << srv.security << "port=" << srv.port << "transport=" << srv.transport << "security=" << srv.security << "port=" << srv.port
@@ -369,7 +377,8 @@ XrayProtocolConfig XrayConfigurator::buildClientProtocolConfig(const ServerCrede
QJsonObject vnextEntry; QJsonObject vnextEntry;
vnextEntry[amnezia::protocols::xray::address] = credentials.hostName; vnextEntry[amnezia::protocols::xray::address] = credentials.hostName;
vnextEntry[amnezia::protocols::xray::port] = srv.port.isEmpty() ? amnezia::protocols::xray::defaultPort : srv.port.toInt(); vnextEntry[amnezia::protocols::xray::port] =
srv.port.isEmpty() ? QString(amnezia::protocols::xray::defaultPort).toInt() : srv.port.toInt();
vnextEntry[amnezia::protocols::xray::users] = QJsonArray { userObj }; vnextEntry[amnezia::protocols::xray::users] = QJsonArray { userObj };
QJsonObject outboundSettings; QJsonObject outboundSettings;
@@ -586,6 +595,13 @@ ProtocolConfig XrayConfigurator::createConfig(const ServerCredentials &credentia
const DnsSettings &dnsSettings, const DnsSettings &dnsSettings,
ErrorCode &errorCode) ErrorCode &errorCode)
{ {
if (const auto *xrayCfg = containerConfig.protocolConfig.as<XrayProtocolConfig>()) {
if (xrayCfg->serverConfig.isThirdPartyConfig && xrayCfg->hasClientConfig()) {
logger.info() << "Xray createConfig: returning existing third-party client config without server SSH";
return *xrayCfg;
}
}
const XrayServerConfig *serverConfig = nullptr; const XrayServerConfig *serverConfig = nullptr;
if (const auto *xrayCfg = containerConfig.protocolConfig.as<XrayProtocolConfig>()) { if (const auto *xrayCfg = containerConfig.protocolConfig.as<XrayProtocolConfig>()) {
serverConfig = &xrayCfg->serverConfig; serverConfig = &xrayCfg->serverConfig;
@@ -202,7 +202,10 @@ ErrorCode InstallController::updateContainer(const QString &serverId, DockerCont
} }
} }
if (errorCode == ErrorCode::NoError && xrayServerSettingsChanged) { const bool skipXrayInboundSync =
newConfig.getXrayProtocolConfig() && newConfig.getXrayProtocolConfig()->serverConfig.isThirdPartyConfig;
if (errorCode == ErrorCode::NoError && xrayServerSettingsChanged && !skipXrayInboundSync) {
DnsSettings dnsSettings = { m_appSettingsRepository->primaryDns(), m_appSettingsRepository->secondaryDns() }; DnsSettings dnsSettings = { m_appSettingsRepository->primaryDns(), m_appSettingsRepository->secondaryDns() };
XrayConfigurator xrayConfigurator(&sshSession); XrayConfigurator xrayConfigurator(&sshSession);
qDebug() << "InstallController::updateContainer applying Xray server inbound sync, reinstall=" qDebug() << "InstallController::updateContainer applying Xray server inbound sync, reinstall="
@@ -108,35 +108,114 @@ QJsonObject XrayXhttpConfig::toJson() const
return obj; return obj;
} }
namespace
{
XrayXhttpConfig clearedXhttpConfig()
{
XrayXhttpConfig c;
c.mode = QString();
c.host = QString();
c.path = QString();
c.headersTemplate = QString();
c.uplinkMethod = QString();
c.disableGrpc = false;
c.disableSse = false;
c.sessionPlacement = QString();
c.sessionKey = QString();
c.seqPlacement = QString();
c.seqKey = QString();
c.uplinkDataPlacement = QString();
c.uplinkDataKey = QString();
c.uplinkChunkSize = QString();
c.scMaxBufferedPosts = QString();
c.scMaxEachPostBytesMin = QString();
c.scMaxEachPostBytesMax = QString();
c.scMinPostsIntervalMsMin = QString();
c.scMinPostsIntervalMsMax = QString();
c.scStreamUpServerSecsMin = QString();
c.scStreamUpServerSecsMax = QString();
return c;
}
} // namespace
XrayXhttpConfig XrayXhttpConfig::fromJson(const QJsonObject &json) XrayXhttpConfig XrayXhttpConfig::fromJson(const QJsonObject &json)
{ {
XrayXhttpConfig c; if (json.isEmpty()) {
c.mode = json.value(configKey::xhttpMode).toString(protocols::xray::defaultXhttpMode); return clearedXhttpConfig();
c.host = json.value(configKey::xhttpHost).toString(protocols::xray::defaultSite); }
c.path = json.value(configKey::xhttpPath).toString();
c.headersTemplate = json.value(configKey::xhttpHeadersTemplate).toString(protocols::xray::defaultXhttpHeadersTemplate);
c.uplinkMethod = json.value(configKey::xhttpUplinkMethod).toString(protocols::xray::defaultXhttpUplinkMethod);
c.disableGrpc = json.value(configKey::xhttpDisableGrpc).toBool(true);
c.disableSse = json.value(configKey::xhttpDisableSse).toBool(true);
c.sessionPlacement = json.value(configKey::xhttpSessionPlacement).toString(protocols::xray::defaultXhttpSessionPlacement); XrayXhttpConfig c = clearedXhttpConfig();
c.sessionKey = json.value(configKey::xhttpSessionKey).toString();
c.seqPlacement = json.value(configKey::xhttpSeqPlacement).toString(protocols::xray::defaultXhttpSessionPlacement);
c.seqKey = json.value(configKey::xhttpSeqKey).toString();
c.uplinkDataPlacement = json.value(configKey::xhttpUplinkDataPlacement).toString(protocols::xray::defaultXhttpUplinkDataPlacement);
c.uplinkDataKey = json.value(configKey::xhttpUplinkDataKey).toString();
c.uplinkChunkSize = json.value(configKey::xhttpUplinkChunkSize).toString("0"); if (json.contains(configKey::xhttpMode)) {
c.scMaxBufferedPosts = json.value(configKey::xhttpScMaxBufferedPosts).toString(); c.mode = json.value(configKey::xhttpMode).toString();
c.scMaxEachPostBytesMin = json.value(configKey::xhttpScMaxEachPostBytesMin).toString("1"); }
c.scMaxEachPostBytesMax = json.value(configKey::xhttpScMaxEachPostBytesMax).toString("100"); if (json.contains(configKey::xhttpHost)) {
c.scMinPostsIntervalMsMin = json.value(configKey::xhttpScMinPostsIntervalMsMin).toString("100"); c.host = json.value(configKey::xhttpHost).toString();
c.scMinPostsIntervalMsMax = json.value(configKey::xhttpScMinPostsIntervalMsMax).toString("800"); }
c.scStreamUpServerSecsMin = json.value(configKey::xhttpScStreamUpServerSecsMin).toString("1"); if (json.contains(configKey::xhttpPath)) {
c.scStreamUpServerSecsMax = json.value(configKey::xhttpScStreamUpServerSecsMax).toString("100"); c.path = json.value(configKey::xhttpPath).toString();
}
if (json.contains(configKey::xhttpHeadersTemplate)) {
c.headersTemplate = json.value(configKey::xhttpHeadersTemplate).toString();
}
if (json.contains(configKey::xhttpUplinkMethod)) {
c.uplinkMethod = json.value(configKey::xhttpUplinkMethod).toString();
}
if (json.contains(configKey::xhttpDisableGrpc)) {
c.disableGrpc = json.value(configKey::xhttpDisableGrpc).toBool();
}
if (json.contains(configKey::xhttpDisableSse)) {
c.disableSse = json.value(configKey::xhttpDisableSse).toBool();
}
if (json.contains(configKey::xhttpSessionPlacement)) {
c.sessionPlacement = json.value(configKey::xhttpSessionPlacement).toString();
}
if (json.contains(configKey::xhttpSessionKey)) {
c.sessionKey = json.value(configKey::xhttpSessionKey).toString();
}
if (json.contains(configKey::xhttpSeqPlacement)) {
c.seqPlacement = json.value(configKey::xhttpSeqPlacement).toString();
}
if (json.contains(configKey::xhttpSeqKey)) {
c.seqKey = json.value(configKey::xhttpSeqKey).toString();
}
if (json.contains(configKey::xhttpUplinkDataPlacement)) {
c.uplinkDataPlacement = json.value(configKey::xhttpUplinkDataPlacement).toString();
}
if (json.contains(configKey::xhttpUplinkDataKey)) {
c.uplinkDataKey = json.value(configKey::xhttpUplinkDataKey).toString();
}
if (json.contains(configKey::xhttpUplinkChunkSize)) {
c.uplinkChunkSize = json.value(configKey::xhttpUplinkChunkSize).toString();
}
if (json.contains(configKey::xhttpScMaxBufferedPosts)) {
c.scMaxBufferedPosts = json.value(configKey::xhttpScMaxBufferedPosts).toString();
}
if (json.contains(configKey::xhttpScMaxEachPostBytesMin)) {
c.scMaxEachPostBytesMin = json.value(configKey::xhttpScMaxEachPostBytesMin).toString();
}
if (json.contains(configKey::xhttpScMaxEachPostBytesMax)) {
c.scMaxEachPostBytesMax = json.value(configKey::xhttpScMaxEachPostBytesMax).toString();
}
if (json.contains(configKey::xhttpScMinPostsIntervalMsMin)) {
c.scMinPostsIntervalMsMin = json.value(configKey::xhttpScMinPostsIntervalMsMin).toString();
}
if (json.contains(configKey::xhttpScMinPostsIntervalMsMax)) {
c.scMinPostsIntervalMsMax = json.value(configKey::xhttpScMinPostsIntervalMsMax).toString();
}
if (json.contains(configKey::xhttpScStreamUpServerSecsMin)) {
c.scStreamUpServerSecsMin = json.value(configKey::xhttpScStreamUpServerSecsMin).toString();
}
if (json.contains(configKey::xhttpScStreamUpServerSecsMax)) {
c.scStreamUpServerSecsMax = json.value(configKey::xhttpScStreamUpServerSecsMax).toString();
}
c.xPadding = XrayXPaddingConfig::fromJson(json.value("xPadding").toObject()); if (json.contains(QLatin1String("xPadding"))) {
c.xmux = XrayXmuxConfig::fromJson(json.value("xmux").toObject()); c.xPadding = XrayXPaddingConfig::fromJson(json.value(QLatin1String("xPadding")).toObject());
}
if (json.contains(QLatin1String("xmux"))) {
c.xmux = XrayXmuxConfig::fromJson(json.value(QLatin1String("xmux")).toObject());
}
return c; return c;
} }
@@ -156,12 +235,27 @@ QJsonObject XrayMkcpConfig::toJson() const
XrayMkcpConfig XrayMkcpConfig::fromJson(const QJsonObject &json) XrayMkcpConfig XrayMkcpConfig::fromJson(const QJsonObject &json)
{ {
XrayMkcpConfig c; XrayMkcpConfig c;
c.tti = json.value(configKey::mkcpTti).toString(); if (json.isEmpty()) {
c.uplinkCapacity = json.value(configKey::mkcpUplinkCapacity).toString(); return c;
c.downlinkCapacity = json.value(configKey::mkcpDownlinkCapacity).toString(); }
c.readBufferSize = json.value(configKey::mkcpReadBufferSize).toString(); if (json.contains(configKey::mkcpTti)) {
c.writeBufferSize = json.value(configKey::mkcpWriteBufferSize).toString(); c.tti = json.value(configKey::mkcpTti).toString();
c.congestion = json.value(configKey::mkcpCongestion).toBool(true); }
if (json.contains(configKey::mkcpUplinkCapacity)) {
c.uplinkCapacity = json.value(configKey::mkcpUplinkCapacity).toString();
}
if (json.contains(configKey::mkcpDownlinkCapacity)) {
c.downlinkCapacity = json.value(configKey::mkcpDownlinkCapacity).toString();
}
if (json.contains(configKey::mkcpReadBufferSize)) {
c.readBufferSize = json.value(configKey::mkcpReadBufferSize).toString();
}
if (json.contains(configKey::mkcpWriteBufferSize)) {
c.writeBufferSize = json.value(configKey::mkcpWriteBufferSize).toString();
}
if (json.contains(configKey::mkcpCongestion)) {
c.congestion = json.value(configKey::mkcpCongestion).toBool();
}
return c; return c;
} }
@@ -208,8 +302,14 @@ QJsonObject XrayServerConfig::toJson() const
if (!transport.isEmpty()) { if (!transport.isEmpty()) {
obj[configKey::xrayTransport] = transport; obj[configKey::xrayTransport] = transport;
} }
obj["xhttp"] = xhttp.toJson(); const QJsonObject xhttpObj = xhttp.toJson();
obj["mkcp"] = mkcp.toJson(); if (!xhttpObj.isEmpty()) {
obj[QStringLiteral("xhttp")] = xhttpObj;
}
const QJsonObject mkcpObj = mkcp.toJson();
if (!mkcpObj.isEmpty()) {
obj[QStringLiteral("mkcp")] = mkcpObj;
}
return obj; return obj;
} }
@@ -225,20 +325,39 @@ XrayServerConfig XrayServerConfig::fromJson(const QJsonObject &json)
c.site = json.value(configKey::site).toString(); c.site = json.value(configKey::site).toString();
c.isThirdPartyConfig = json.value(configKey::isThirdPartyConfig).toBool(false); c.isThirdPartyConfig = json.value(configKey::isThirdPartyConfig).toBool(false);
// New: Security if (json.contains(configKey::xraySecurity)) {
c.security = json.value(configKey::xraySecurity).toString(protocols::xray::defaultSecurity); c.security = json.value(configKey::xraySecurity).toString();
c.flow = json.value(configKey::xrayFlow).toString(protocols::xray::defaultFlow); }
c.fingerprint = json.value(configKey::xrayFingerprint).toString(protocols::xray::defaultFingerprint); if (json.contains(configKey::xrayFlow)) {
if (c.fingerprint.contains(QLatin1String("Mozilla/5.0"), Qt::CaseInsensitive)) { c.flow = json.value(configKey::xrayFlow).toString();
c.fingerprint = QString::fromLatin1(protocols::xray::defaultFingerprint); }
if (json.contains(configKey::xrayFingerprint)) {
c.fingerprint = json.value(configKey::xrayFingerprint).toString();
if (c.fingerprint.contains(QLatin1String("Mozilla/5.0"), Qt::CaseInsensitive)) {
c.fingerprint = QString::fromLatin1(protocols::xray::defaultFingerprint);
}
}
if (json.contains(configKey::xraySni)) {
c.sni = json.value(configKey::xraySni).toString();
}
if (json.contains(configKey::xrayAlpn)) {
c.alpn = json.value(configKey::xrayAlpn).toString();
}
if (json.contains(configKey::xrayTransport)) {
c.transport = json.value(configKey::xrayTransport).toString();
}
if (json.contains(QLatin1String("xhttp"))) {
const QJsonObject xhttpJson = json.value(QLatin1String("xhttp")).toObject();
if (!xhttpJson.isEmpty()) {
c.xhttp = XrayXhttpConfig::fromJson(xhttpJson);
}
}
if (json.contains(QLatin1String("mkcp"))) {
const QJsonObject mkcpJson = json.value(QLatin1String("mkcp")).toObject();
if (!mkcpJson.isEmpty()) {
c.mkcp = XrayMkcpConfig::fromJson(mkcpJson);
}
} }
c.sni = json.value(configKey::xraySni).toString(protocols::xray::defaultSni);
c.alpn = json.value(configKey::xrayAlpn).toString(protocols::xray::defaultAlpn);
// New: Transport
c.transport = json.value(configKey::xrayTransport).toString(protocols::xray::defaultTransport);
c.xhttp = XrayXhttpConfig::fromJson(json.value("xhttp").toObject());
c.mkcp = XrayMkcpConfig::fromJson(json.value("mkcp").toObject());
return c; return c;
} }
@@ -354,7 +473,9 @@ XrayProtocolConfig XrayProtocolConfig::fromJson(const QJsonObject &json)
} }
} }
c.needsClientHydration = !json.contains(configKey::xrayTransport) && c.hasClientConfig(); c.needsClientHydration =
c.hasClientConfig()
&& (!json.contains(configKey::xrayTransport) || c.serverConfig.isThirdPartyConfig);
if (c.needsClientHydration) { if (c.needsClientHydration) {
c.hydrateServerConfigFromClientNative(); c.hydrateServerConfigFromClientNative();
} }
@@ -409,7 +530,9 @@ bool XrayProtocolConfig::hydrateServerConfigFromClientNative()
srv.transport = QStringLiteral("raw"); srv.transport = QStringLiteral("raw");
} }
srv.security = streamSettings.value(protocols::xray::security).toString(protocols::xray::defaultSecurity); if (streamSettings.contains(protocols::xray::security)) {
srv.security = streamSettings.value(protocols::xray::security).toString();
}
if (srv.security == QLatin1String("reality")) { if (srv.security == QLatin1String("reality")) {
const QJsonObject rs = streamSettings.value(protocols::xray::realitySettings).toObject(); const QJsonObject rs = streamSettings.value(protocols::xray::realitySettings).toObject();
@@ -75,6 +75,7 @@ struct XrayXhttpConfig {
XrayXmuxConfig xmux; XrayXmuxConfig xmux;
QJsonObject toJson() const; QJsonObject toJson() const;
/// Reads only keys present in JSON (no Amnezia UI defaults). Use XrayConfigModel::applyDefaultsToServerConfig for UI.
static XrayXhttpConfig fromJson(const QJsonObject &json); static XrayXhttpConfig fromJson(const QJsonObject &json);
}; };
@@ -99,15 +100,14 @@ struct XrayServerConfig {
QString site; QString site;
bool isThirdPartyConfig = false; bool isThirdPartyConfig = false;
// New: Security // Extended VLESS fields: empty in persisted JSON means "not set" (UI defaults applied in XrayConfigModel).
QString security = protocols::xray::defaultSecurity; QString security;
QString flow = protocols::xray::defaultFlow; QString flow;
QString fingerprint = protocols::xray::defaultFingerprint; QString fingerprint;
QString sni = protocols::xray::defaultSni; QString sni;
QString alpn = protocols::xray::defaultAlpn; QString alpn;
// New: Transport QString transport;
QString transport = protocols::xray::defaultTransport;
XrayXhttpConfig xhttp; XrayXhttpConfig xhttp;
XrayMkcpConfig mkcp; XrayMkcpConfig mkcp;
@@ -271,7 +271,9 @@ void XrayConfigModel::updateModel(amnezia::DockerContainer container, const amne
m_protocolConfig.hydrateServerConfigFromClientNative(); m_protocolConfig.hydrateServerConfigFromClientNative();
} }
applyDefaultsToServerConfig(m_protocolConfig.serverConfig); if (!m_protocolConfig.serverConfig.isThirdPartyConfig) {
applyDefaultsToServerConfig(m_protocolConfig.serverConfig);
}
m_originalProtocolConfig = m_protocolConfig; m_originalProtocolConfig = m_protocolConfig;