From 7f82daa42f1c5fff844f83888eeaa16352a25fe7 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sun, 25 Oct 2026 15:54:53 +0100 Subject: [PATCH] feat(finalmask): tlshello fragment presets for client editors The host, JSON subscription and outbound mask editors now offer PattN's two chained tlshello fragment presets; a pick replaces the TCP mask list. The fragment length validator rejected a 0 minimum in every entry, but xray-core only refuses it in the last lengths entry. An earlier 0 is an empty segment, which the tlshello-0-len preset relies on. --- frontend/src/lib/xray/finalmask-presets.ts | 26 +++++++ .../xray/forms/transport/FinalMaskForm.tsx | 68 ++++++++++++----- frontend/src/test/finalmask-form.test.tsx | 75 ++++++++++++++++++- 3 files changed, 151 insertions(+), 18 deletions(-) create mode 100644 frontend/src/lib/xray/finalmask-presets.ts diff --git a/frontend/src/lib/xray/finalmask-presets.ts b/frontend/src/lib/xray/finalmask-presets.ts new file mode 100644 index 000000000..74d90fef5 --- /dev/null +++ b/frontend/src/lib/xray/finalmask-presets.ts @@ -0,0 +1,26 @@ +import type { TcpMask } from '@/schemas/protocols/stream/finalmask'; + +// PattN's client presets: one fragment splits the TLS ClientHello into three segments +// (the first may be empty), a second splits the next packet with a 1 ms delay. +export const TCP_MASK_PRESETS: Readonly> = Object.freeze({ + 'tlshello-0-len': [ + { + type: 'fragment', + settings: { packets: 'tlshello', lengths: ['0', '104', '1'], delays: ['0'], maxSplit: '0' }, + }, + { + type: 'fragment', + settings: { packets: '1-1', lengths: ['114', '1'], delays: ['1'], maxSplit: '11' }, + }, + ], + 'tlshello-6-98': [ + { + type: 'fragment', + settings: { packets: 'tlshello', lengths: ['6', '98', '1'], delays: ['0'], maxSplit: '0' }, + }, + { + type: 'fragment', + settings: { packets: '1-1', lengths: ['114', '1'], delays: ['1'], maxSplit: '11' }, + }, + ], +}); diff --git a/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx b/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx index fcc511b59..014253146 100644 --- a/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx +++ b/frontend/src/lib/xray/forms/transport/FinalMaskForm.tsx @@ -19,6 +19,7 @@ import type { NamePath } from 'antd/es/form/interface'; import { RandomUtil } from '@/utils'; import { activateOnKey } from '@/utils/a11y'; import { OutboundProtocols, UTLS_FINGERPRINT } from '@/schemas/primitives'; +import { TCP_MASK_PRESETS } from '@/lib/xray/finalmask-presets'; import { upgradeLegacyUdpHop } from '@/lib/xray/udphop-mask'; import { upgradeLegacyXdnsMasks, XDNS_LEGACY_EDNS0 } from '@/lib/xray/xdns-mask'; @@ -333,7 +334,14 @@ export default function FinalMaskForm({ return ( <> - {showTcp && } + {showTcp && ( + + )} {showUdp && ( {(fields, { add, remove }) => ( <> -