fix(sub): keep Hysteria2 mport on external-proxy links

genHysteriaLink only looked up the UDP hop range on the no-endpoint path,
after the externalProxy fan-out had already returned. An inbound with Hosts
therefore emitted per-host links without mport, so clients pinned themselves
to the single listening port and silently lost port hopping. Set the param
before the fan-out so every endpoint inherits it, matching the frontend
link builder and the Clash emitter.

Closes #6264
This commit is contained in:
Sanaei
2026-08-24 13:27:39 +02:00
parent f13baa9af5
commit 7a595cb46d
2 changed files with 36 additions and 3 deletions
+6 -3
View File
@@ -1209,6 +1209,12 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
protocol = "hysteria"
}
// Set before the externalProxy fan-out: a Host overrides only the
// address, so every endpoint inherits the inbound's UDP hop range.
if hopPorts := hysteriaHopPorts(stream); hopPorts != "" {
params["mport"] = hopPorts
}
// Fan out one link per External Proxy entry if any. Previously this
// generator ignored `externalProxy` entirely, so the link kept the
// server's own IP/port even when the admin configured an alternate
@@ -1238,9 +1244,6 @@ func (s *SubService) genHysteriaLink(inbound *model.Inbound, email string) strin
// No external proxy configured — use the inbound's resolved address so
// node-managed inbounds get the node's host instead of the central panel's.
if hopPorts := hysteriaHopPorts(stream); hopPorts != "" {
params["mport"] = hopPorts
}
link := fmt.Sprintf("%s://%s@%s", protocol, auth, joinHostPort(s.resolveInboundAddress(inbound), inbound.Port))
return buildLinkWithParams(link, params, s.genRemark(inbound, email, "", "quic"))
}