From da2248c516c7493919e049c6ae9725f70821b025 Mon Sep 17 00:00:00 2001 From: Soheil Fakour Date: Fri, 16 Oct 2026 10:33:45 +0330 Subject: [PATCH] Hysteria client: Reset stalled writes when the connection is closed (#7172) https://github.com/XTLS/Xray-core/pull/7172#issuecomment-6208589708 Fixes https://github.com/XTLS/Xray-core/issues/7169#issuecomment-6204450876 --------- Co-authored-by: LjhAUMEM --- transport/internet/hysteria/conn.go | 20 +++++++++++++++++++- transport/internet/hysteria/dialer.go | 1 + transport/internet/hysteria/hub.go | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/transport/internet/hysteria/conn.go b/transport/internet/hysteria/conn.go index 07b8f6d9f..5e801eed7 100644 --- a/transport/internet/hysteria/conn.go +++ b/transport/internet/hysteria/conn.go @@ -22,6 +22,12 @@ type interConn struct { client bool user *protocol.MemoryUser + lock chan struct{} + mu sync.Mutex +} + +func (c *interConn) unlock() { + <-c.lock } func (c *interConn) User() *protocol.MemoryUser { @@ -33,6 +39,9 @@ func (c *interConn) Read(b []byte) (int, error) { } func (c *interConn) Write(b []byte) (int, error) { + c.lock <- struct{}{} + defer c.unlock() + if c.client { c.client = false if _, err := c.stream.Write(append(quicvarint.Append(nil, FrameTypeTCPRequest), b...)); err != nil { @@ -40,11 +49,20 @@ func (c *interConn) Write(b []byte) (int, error) { } return len(b), nil } - return c.stream.Write(b) } func (c *interConn) Close() error { + c.mu.Lock() + defer c.mu.Unlock() + select { + case c.lock <- struct{}{}: + defer c.unlock() + default: + c.stream.CancelRead(0) + c.stream.CancelWrite(0) + return nil + } c.stream.CancelRead(0) return c.stream.Close() } diff --git a/transport/internet/hysteria/dialer.go b/transport/internet/hysteria/dialer.go index 1d7b8a95e..a6eed34c6 100644 --- a/transport/internet/hysteria/dialer.go +++ b/transport/internet/hysteria/dialer.go @@ -257,6 +257,7 @@ func (c *client) tcp(ctx context.Context) (stat.Connection, error) { remote: c.conn.RemoteAddr(), client: true, + lock: make(chan struct{}, 1), }, nil } diff --git a/transport/internet/hysteria/hub.go b/transport/internet/hysteria/hub.go index 0b3f449cd..441db8744 100644 --- a/transport/internet/hysteria/hub.go +++ b/transport/internet/hysteria/hub.go @@ -134,6 +134,7 @@ func (h *httpHandler) StreamDispatcher(ft http3.FrameType, stream *quic.Stream, remote: h.conn.RemoteAddr(), user: h.user, + lock: make(chan struct{}, 1), }) return true, nil default: