mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-16 17:46:08 +00:00
* fix: enable XTLS vision flow for VLESS+XHTTP+vlessenc in UI and share links (#5157) * fix: enable xtls-rprx-vision flow for VLESS XHTTP with vlessenc encryption (#5157) The flow selector was hidden and the vless:// link omitted flow= because: 1. The backend gate (inboundCanEnableTlsFlow) only accepted tcp+tls/reality. 2. The PR #5185 frontend check used `encryption === 'vlessenc'`, which never matches — the stored value is a generated ML-KEM dotted string, not the CLI subcommand name. Fix: extend inboundCanEnableTlsFlow to also return true for XHTTP when a non-none vlessenc encryption/decryption value is present. Update all three call-sites (inbound.go TlsFlowCapable field, client_crud.go clientWithInboundFlow, inbound_clients.go copy-flow path) and the sub/service.go link generator. Scope is XHTTP-only: TCP without tls/reality is intentionally excluded. Add inbound_protocol_test.go covering the new and existing gate combinations, extend client_flow_isolation_test.go with xhttp+vlessenc cases, and add frontend tests for canEnableTlsFlow with real ML-KEM key values. --------- Co-authored-by: rqzbeh <rqzbeh@users.noreply.github.com> Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
@@ -16,16 +16,16 @@ const SS_BLAKE3_CHACHA20 = '2022-blake3-chacha20-poly1305';
|
||||
|
||||
export interface CapabilityProtocolSlice {
|
||||
protocol: string;
|
||||
settings?: { encryption?: string; decryption?: string };
|
||||
streamSettings?: { network?: string; security?: string };
|
||||
}
|
||||
|
||||
export interface CapabilityVlessSlice extends CapabilityProtocolSlice {
|
||||
settings?: { clients?: { flow?: string }[] };
|
||||
settings?: { encryption?: string; decryption?: string; clients?: { flow?: string }[] };
|
||||
}
|
||||
|
||||
export interface CapabilityShadowsocksSlice {
|
||||
protocol: string;
|
||||
settings?: { method?: string };
|
||||
export interface CapabilityShadowsocksSlice extends CapabilityProtocolSlice {
|
||||
settings?: { encryption?: string; method?: string };
|
||||
}
|
||||
|
||||
export function canEnableTls(values: CapabilityProtocolSlice): boolean {
|
||||
@@ -39,11 +39,28 @@ export function canEnableReality(values: CapabilityProtocolSlice): boolean {
|
||||
return REALITY_NETWORKS.includes(values.streamSettings?.network ?? '');
|
||||
}
|
||||
|
||||
// VLESS encryption (vlessenc / ML-KEM) is on when encryption or decryption holds
|
||||
// a generated value (e.g. "mlkem768x25519plus.native.0rtt.<key>") rather than
|
||||
// the "none"/"" sentinel. The value is never the literal "vlessenc" (that is the
|
||||
// `xray vlessenc` subcommand). decryption is the server-side value; encryption is
|
||||
// stored for link generation — either being set means it is on.
|
||||
function hasVlessEncryption(settings: CapabilityProtocolSlice['settings']): boolean {
|
||||
const isSet = (v?: string) => v != null && v !== '' && v !== 'none';
|
||||
return isSet(settings?.encryption) || isSet(settings?.decryption);
|
||||
}
|
||||
|
||||
export function canEnableTlsFlow(values: CapabilityProtocolSlice): boolean {
|
||||
if (values.protocol !== 'vless') return false;
|
||||
const network = values.streamSettings?.network;
|
||||
const security = values.streamSettings?.security;
|
||||
if (security !== 'tls' && security !== 'reality') return false;
|
||||
if (values.streamSettings?.network !== 'tcp') return false;
|
||||
return values.protocol === 'vless';
|
||||
|
||||
// Classic XTLS Vision: raw TCP carried over TLS or REALITY.
|
||||
if (network === 'tcp' && (security === 'tls' || security === 'reality')) return true;
|
||||
|
||||
// vlessenc carries Vision over XHTTP without transport TLS.
|
||||
if (network === 'xhttp' && hasVlessEncryption(values.settings)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function canEnableStream(values: { protocol: string }): boolean {
|
||||
|
||||
Reference in New Issue
Block a user