* fix(outbound): import Hysteria2 salamander from standard obfs params
The outbound share-link importers only reconstructed salamander from the
private fm=<json> finalmask dump. Every standard Hysteria2 link — and this
panel's own generator (internal/sub) since it stopped emitting fm= — carries
the obfuscation as the standard obfs=salamander & obfs-password=<pw> pair,
which the importers ignored. As a result, importing a normal Hysteria2 link
(pasted into the outbound form or pulled from a subscription) silently dropped
the salamander config and produced an outbound that negotiates plain QUIC
against a server expecting obfuscation.
Parse the standard obfs/obfs-password pair in both the Go importer
(internal/util/link, used by subscription + JSON import) and the frontend
form parser (outbound-link-parser.ts), folding it into finalmask.udp. A
salamander mask already supplied via fm= still wins, so 3x-ui→3x-ui links
are unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(outbound): address review — mport hop, password-less fm mask, tests
Follow-up to the automated PR review on #6166:
- Import the Hysteria2 UDP port-hopping range from the standard `mport`
param (finalmask.quicParams.udpHop.ports) in both importers — the same
class of gap as salamander: the subscription generator emits `mport`
standalone and no `fm=`, so port hopping was silently lost on import.
An `fm=`-supplied udpHop still wins.
- When `fm=` carries a salamander mask without a usable password, fill it
in from the obfs pair instead of treating the empty mask as authoritative
(would otherwise enable obfuscation with an empty password).
- Trim the duplicated rationale comments to two lines each.
- Tests: collapse the four per-case Go functions into table-driven
subtests; cover the obfs_password/obfsPassword aliases, case-insensitive
obfs value, append-onto-non-salamander-udp, password-less-fm fill, and the
mport paths; assert the fm-wins masks stay length 1 in both suites.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>