fix(xray): hot-apply Hysteria client changes without replacing the inbound (#6606)

* fix(xray): hot-apply Hysteria client changes without replacing the inbound

diffInboundUsers only allowed per-user AlterInbound ops for vless, vmess
and trojan. For a hysteria inbound every client add/remove/update became
DelInbound + AddInbound: the UDP listener was recreated and all QUIC
sessions of that inbound were lost. quic-go sends no stateless reset, so
every connected client stalled until its idle timeout (30s by default)
after each unrelated client mutation.

XrayAPI.AddUser already builds a hysteria account and Xray-core's
hysteria server implements AddUser/RemoveUser, so adding the protocol to
userDiffableProtocols is sufficient.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(xray): say which branch each drop-guard protocol takes

With hysteria in userDiffableProtocols its dropped client reaches the
guard through the per-user diff, so the test named for protocols the
diff cannot handle no longer described its hysteria case.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: MHSanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
SERGE BLCHV
2026-09-27 01:03:43 +05:00
committed by GitHub
parent 6ab718f813
commit 6ac0c88084
3 changed files with 29 additions and 4 deletions
+1 -1
View File
@@ -221,7 +221,7 @@ func droppedClients(oldIb, newIb *InboundConfig) []UserOp {
return dropped
}
var userDiffableProtocols = map[string]struct{}{"vless": {}, "vmess": {}, "trojan": {}}
var userDiffableProtocols = map[string]struct{}{"vless": {}, "vmess": {}, "trojan": {}, "hysteria": {}}
// diffInboundUsers emits per-user AlterInbound ops when two same-tag inbounds
// differ only in settings.clients, so the handler (and its listener) survives.