From 222e000b3ba60b949046f2d6a619a01e0fc3ce81 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Wed, 27 May 2026 13:11:32 +0200 Subject: [PATCH] feat(inbound-form): seed FinalMask with mkcp-original when KCP is selected Picking mKCP from the Transmission select used to leave finalmask.udp empty, so the inbound went out as unobfuscated mKCP unless the admin remembered to add the wrapper by hand in the FinalMask section. Hook into onNetworkChange so switching the network to kcp appends {type: 'mkcp-original', settings: {}} to finalmask.udp (only when no mkcp-original entry exists yet, so re-selecting kcp or editing other udp masks doesn't pile up duplicates). --- .../src/pages/inbounds/InboundFormModal.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/frontend/src/pages/inbounds/InboundFormModal.tsx b/frontend/src/pages/inbounds/InboundFormModal.tsx index 5227f134..f0b62c9f 100644 --- a/frontend/src/pages/inbounds/InboundFormModal.tsx +++ b/frontend/src/pages/inbounds/InboundFormModal.tsx @@ -1463,6 +1463,24 @@ export default function InboundFormModal({ if (k !== `${next}Settings`) delete cleaned[k]; } cleaned[`${next}Settings`] = newStreamSlice(next); + // mKCP wants a UDP mask wrapper on the FinalMask side; seed it with + // `mkcp-original` so the inbound boots with a sensible default + // instead of unobfuscated mKCP traffic. The user can still edit or + // clear the mask via the FinalMask section. + if (next === 'kcp') { + const fm = (cleaned.finalmask as Record | undefined) ?? {}; + const udp = Array.isArray(fm.udp) ? (fm.udp as unknown[]) : []; + const hasMkcp = udp.some((m) => { + const entry = m as { type?: string }; + return entry?.type === 'mkcp-original'; + }); + if (!hasMkcp) { + cleaned.finalmask = { + ...fm, + udp: [...udp, { type: 'mkcp-original', settings: {} }], + }; + } + } form.setFieldValue('streamSettings', cleaned); };