From 6da70e80aab8c707137634d48bb93fd61e4592bf Mon Sep 17 00:00:00 2001 From: Hari Date: Wed, 18 Feb 2026 10:18:42 +0800 Subject: [PATCH] fix: consume TCP request frame type with StreamDispatcher --- core/server/server.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/core/server/server.go b/core/server/server.go index 7af28b2..d8e6afc 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -10,6 +10,7 @@ import ( "github.com/apernet/quic-go" "github.com/apernet/quic-go/http3" + "github.com/apernet/quic-go/quicvarint" "github.com/apernet/hysteria/core/v2/internal/congestion" "github.com/apernet/hysteria/core/v2/internal/protocol" @@ -210,11 +211,15 @@ func (h *h3sHandler) ProxyStreamHijacker(ft http3.FrameType, stream *quic.Stream return false, nil } - // Wraps the stream with QStream, which handles Close() properly - qStream := &utils.QStream{Stream: stream} - switch ft { case protocol.FrameTypeTCPRequest: + // StreamDispatcher only peeks the frame type. Consume it so ReadTCPRequest + // starts at address length, matching pre-upgrade StreamHijacker behavior. + if _, err := quicvarint.Read(quicvarint.NewReader(stream)); err != nil { + return false, err + } + // Wraps the stream with QStream, which handles Close() properly + qStream := &utils.QStream{Stream: stream} go h.handleTCPRequest(qStream) return true, nil default: