diff --git a/frontend/src/schemas/protocols/stream/sockopt.ts b/frontend/src/schemas/protocols/stream/sockopt.ts index 877b776ab..27df9acb7 100644 --- a/frontend/src/schemas/protocols/stream/sockopt.ts +++ b/frontend/src/schemas/protocols/stream/sockopt.ts @@ -33,7 +33,7 @@ export const AddressPortStrategySchema = z.enum([ export type AddressPortStrategy = z.infer; export const HappyEyeballsSchema = z.object({ - tryDelayMs: z.number().int().min(0).default(0), + tryDelayMs: z.number().int().min(0).default(250), prioritizeIPv6: z.boolean().default(false), interleave: z.number().int().min(1).default(1), maxConcurrentTry: z.number().int().min(0).default(4), diff --git a/frontend/src/test/stream-wire-normalize.test.ts b/frontend/src/test/stream-wire-normalize.test.ts index 81c5db658..cac527736 100644 --- a/frontend/src/test/stream-wire-normalize.test.ts +++ b/frontend/src/test/stream-wire-normalize.test.ts @@ -10,6 +10,7 @@ import { validateRealityTarget, } from '@/lib/xray/stream-wire-normalize'; import { InboundFormSchema } from '@/schemas/forms/inbound-form'; +import { HappyEyeballsSchema } from '@/schemas/protocols/stream/sockopt'; import type { InboundFormValues } from '@/schemas/forms/inbound-form'; import { XHttpXmuxSchema } from '@/schemas/protocols/stream/xhttp'; @@ -204,6 +205,14 @@ describe('normalizeSockoptForWire', () => { }); expect(out?.domainStrategy).toBe('UseIP'); }); + + it('keeps a freshly toggled happyEyeballs (schema defaults) across the wire round trip', () => { + const out = normalizeSockoptForWire({ + happyEyeballs: HappyEyeballsSchema.parse({}), + }); + + expect(out?.happyEyeballs).toEqual({ tryDelayMs: 250 }); + }); }); describe('normalizeStreamSettingsForWire reality', () => {