mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 12:44:22 +00:00
fix(frontend): QUIC udpHop.interval is a range string, not a number (B19)
User report: "streamSettings.finalmask.quicParams.udpHop.interval: Invalid input: expected string, received number". Three-part fix: - FinalMaskForm: Hop Interval input changed from InputNumber to Input with "e.g. 5-10" placeholder. xray-core spec says interval is a range string like '5-10' (seconds between min-max hops), not a single number. - FinalMaskForm: defaultQuicParams() seeds interval: '5-10' instead of the broken `interval: 5`. - QuicUdpHopSchema: preprocess coerces number → string for legacy DB rows that were written by the now-fixed buggy UI. Stops the load-time validation crash on existing inbounds. Tests still 296/296.
This commit is contained in:
parent
2b4686de99
commit
ce2fd2f0dd
2 changed files with 11 additions and 5 deletions
|
|
@ -91,7 +91,7 @@ function defaultQuicParams(): Record<string, unknown> {
|
||||||
brutalUp: 0,
|
brutalUp: 0,
|
||||||
brutalDown: 0,
|
brutalDown: 0,
|
||||||
hasUdpHop: false,
|
hasUdpHop: false,
|
||||||
udpHop: { ports: '20000-50000', interval: 5 },
|
udpHop: { ports: '20000-50000', interval: '5-10' },
|
||||||
maxIdleTimeout: 30,
|
maxIdleTimeout: 30,
|
||||||
keepAlivePeriod: 10,
|
keepAlivePeriod: 10,
|
||||||
disablePathMTUDiscovery: false,
|
disablePathMTUDiscovery: false,
|
||||||
|
|
@ -707,7 +707,7 @@ function QuicParamsForm({ base, form }: { base: (string | number)[]; form: FormI
|
||||||
<Input placeholder="e.g. 20000-50000" />
|
<Input placeholder="e.g. 20000-50000" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="Hop Interval (s)" name={[...base, 'udpHop', 'interval']}>
|
<Form.Item label="Hop Interval (s)" name={[...base, 'udpHop', 'interval']}>
|
||||||
<InputNumber min={5} />
|
<Input placeholder="e.g. 5-10" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -47,10 +47,16 @@ export type QuicCongestion = z.infer<typeof QuicCongestionSchema>;
|
||||||
|
|
||||||
// udpHop randomizes the QUIC port between a range every `interval` seconds
|
// udpHop randomizes the QUIC port between a range every `interval` seconds
|
||||||
// to dodge port-based blocking. Both fields are dash-range strings on the
|
// to dodge port-based blocking. Both fields are dash-range strings on the
|
||||||
// wire (e.g. '20000-50000', '5-10').
|
// wire (e.g. '20000-50000', '5-10'). preprocess coerces legacy DB rows
|
||||||
|
// where interval was stored as a number (UI bug — see B19 in commit history).
|
||||||
|
const StringRangeSchema = z.preprocess(
|
||||||
|
(v) => (typeof v === 'number' ? String(v) : v),
|
||||||
|
z.string(),
|
||||||
|
);
|
||||||
|
|
||||||
export const QuicUdpHopSchema = z.object({
|
export const QuicUdpHopSchema = z.object({
|
||||||
ports: z.string().default('20000-50000'),
|
ports: StringRangeSchema.default('20000-50000'),
|
||||||
interval: z.string().default('5-10'),
|
interval: StringRangeSchema.default('5-10'),
|
||||||
});
|
});
|
||||||
export type QuicUdpHop = z.infer<typeof QuicUdpHopSchema>;
|
export type QuicUdpHop = z.infer<typeof QuicUdpHopSchema>;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue