mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
fix(outbounds): preserve SNI/TLS settings on transport change
Changing the transport in the outbound edit modal rebuilt streamSettings from scratch, dropping tlsSettings (and its serverName) while keeping security: 'tls'. On save xray received TLS with an empty SNI, so SNI-spoof tunnels connected but passed no traffic. Carry over tlsSettings/ realitySettings when the new network still supports the security mode, via a new applyNetworkChange helper. Fixes #4791.
This commit is contained in:
parent
039d05a743
commit
5fb18b8819
2 changed files with 31 additions and 14 deletions
|
|
@ -42,6 +42,7 @@ import {
|
|||
SERVER_PROTOCOLS,
|
||||
} from './outbound-form-constants';
|
||||
import {
|
||||
applyNetworkChange,
|
||||
buildAddModeValues,
|
||||
hysteriaStreamSlice,
|
||||
newStreamSlice,
|
||||
|
|
@ -231,20 +232,8 @@ export default function OutboundFormModal({
|
|||
// wsSettings, etc.) so the DU branch matches. Preserve security if
|
||||
// the new network supports it, otherwise force back to 'none'.
|
||||
function onNetworkChange(next: string) {
|
||||
if (next === 'hysteria') {
|
||||
form.setFieldValue('streamSettings', hysteriaStreamSlice());
|
||||
return;
|
||||
}
|
||||
const currentSecurity = form.getFieldValue(['streamSettings', 'security']) ?? 'none';
|
||||
const stillAllowed = canEnableTls({ protocol, streamSettings: { network: next, security: currentSecurity } });
|
||||
const stillReality = canEnableReality({ protocol, streamSettings: { network: next, security: currentSecurity } });
|
||||
const newSecurity =
|
||||
currentSecurity === 'tls' && !stillAllowed
|
||||
? 'none'
|
||||
: currentSecurity === 'reality' && !stillReality
|
||||
? 'none'
|
||||
: currentSecurity;
|
||||
form.setFieldValue('streamSettings', { ...newStreamSlice(next), security: newSecurity });
|
||||
const stream = (form.getFieldValue('streamSettings') ?? {}) as Record<string, unknown>;
|
||||
form.setFieldValue('streamSettings', applyNetworkChange(protocol, stream, next));
|
||||
}
|
||||
|
||||
function onXmuxToggle(checked: boolean) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { rawOutboundToFormValues } from '@/lib/xray/outbound-form-adapter';
|
||||
import { canEnableReality, canEnableTls } from '@/lib/xray/protocol-capabilities';
|
||||
import type { OutboundFormValues } from '@/schemas/forms/outbound-form';
|
||||
|
||||
import { MUX_PROTOCOLS } from './outbound-form-constants';
|
||||
|
|
@ -74,6 +75,33 @@ export function hysteriaStreamSlice(): Record<string, unknown> {
|
|||
};
|
||||
}
|
||||
|
||||
// Network change cascade: swap the per-network sub-key (tcpSettings,
|
||||
// wsSettings, etc.) so the DU branch matches. Carry over the security mode
|
||||
// and its settings (tlsSettings/realitySettings, including SNI serverName)
|
||||
// when the new network still supports it; otherwise fall back to 'none'.
|
||||
// Dropping tlsSettings here silently wiped the spoofed SNI on save (#4791).
|
||||
export function applyNetworkChange(
|
||||
protocol: string,
|
||||
prevStream: Record<string, unknown> | undefined,
|
||||
next: string,
|
||||
): Record<string, unknown> {
|
||||
if (next === 'hysteria') return hysteriaStreamSlice();
|
||||
const stream = prevStream ?? {};
|
||||
const currentSecurity = (stream.security as string) ?? 'none';
|
||||
const stillTls = canEnableTls({ protocol, streamSettings: { network: next, security: currentSecurity } });
|
||||
const stillReality = canEnableReality({ protocol, streamSettings: { network: next, security: currentSecurity } });
|
||||
const newSecurity =
|
||||
currentSecurity === 'tls' && !stillTls
|
||||
? 'none'
|
||||
: currentSecurity === 'reality' && !stillReality
|
||||
? 'none'
|
||||
: currentSecurity;
|
||||
const newStream: Record<string, unknown> = { ...newStreamSlice(next), security: newSecurity };
|
||||
if (newSecurity === 'tls' && stream.tlsSettings) newStream.tlsSettings = stream.tlsSettings;
|
||||
else if (newSecurity === 'reality' && stream.realitySettings) newStream.realitySettings = stream.realitySettings;
|
||||
return newStream;
|
||||
}
|
||||
|
||||
export function buildAddModeValues(): OutboundFormValues {
|
||||
return rawOutboundToFormValues({});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue