fix(finalmask): hop client UDP through the udphop mask

xray-core 26.9.9 dropped finalmask.quicParams.udpHop for the client-only
"udphop" UDP mask {mode, interval, remoteIPs, remotePorts}. The panel kept
writing the old key, so hysteria/xhttp outbounds and JSON-subscription
clients silently stopped hopping ports.

An inbound keeps quicParams.udpHop: it is panel metadata advertised as the
link's mport, and a udphop mask on a listener fails with "udphop: client
only". The conversion (maskcompat.UpgradeLegacyUDPHop, intervalRemote mode)
runs only where a client config is produced:

- UDPHopClientMaskFix seeder over hosts, sub-JSON finalmask, cached
  outbound-subscription outbounds and template outbounds (never inbounds);
- GetXrayConfig heals template outbounds at build time;
- the JSON subscription upgrades each generated client stream;
- the Go and frontend link importers upgrade a legacy fm= param.

The finalmask editor gains a side prop: the client side lifts the dead key
on mount and offers a udphop mask editor (also for xhttp's HTTP/3 dial);
the inbound side keeps the UDP Hop switch, labelled as advertised.
This commit is contained in:
MHSanaei
2026-10-11 11:20:34 +02:00
parent 00aaef386f
commit ec0a57fc4f
22 changed files with 797 additions and 51 deletions
+9 -4
View File
@@ -147,11 +147,16 @@ TLS. Masks are configured per direction:
stream as Minecraft protocol traffic; requires a password, with optional
hostname and player usernames).
- **UDP masks** — `salamander`, `mkcp-legacy`, `header-custom`, `xdns`, `xicmp`,
`noise`, `sudoku`, `realm`. (`mkcp-legacy` reproduces the old mKCP header
obfuscation.)
`noise`, `sudoku`, `realm`, plus the client-only `udphop`. (`mkcp-legacy`
reproduces the old mKCP header obfuscation; `udphop` rotates the remote port —
and optionally the remote IP — on an interval or per connection to dodge port
blocking.)
- **QUIC params** — congestion control (`reno`, `bbr`, `brutal`, `force-brutal`),
Brutal up/down rates, `udpHop` (rotate the QUIC port across a range to dodge
port blocking), and receive-window tuning.
Brutal up/down rates, and receive-window tuning. On an inbound, **UDP Hop** sets
the port range advertised to clients (the share link's `mport` and the JSON
subscription's `udphop` mask); the server still listens on its own port. Since
Xray 26.9.9 a client hops only through the `udphop` mask, so the panel converts
an older client `quicParams.udpHop` to it.
FinalMask replaces the per-transport `header`/`seed` obfuscation that older Xray
builds exposed.