From 62f707c2bb4ed2920a0c8d82aa0965b1853a047e Mon Sep 17 00:00:00 2001 From: realyxl Date: Sat, 1 Aug 2026 13:35:42 +0800 Subject: [PATCH] hysteria2: Fix obfs silently disabling socket buffer sizing SalamanderPacketConn and GeckoPacketConn embed the net.PacketConn interface, which hides SetReadBuffer/SetWriteBuffer. quic-go's type assertion in setReceiveBuffer/setSendBuffer then fails and the socket keeps net.core.rmem_default instead of the 8 MB it asks for. Re-expose both methods, resolving the underlying conn with common.Cast as hysteria/hop.go does. --- hysteria2/gecko.go | 8 ++++++++ hysteria2/salamander.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/hysteria2/gecko.go b/hysteria2/gecko.go index 7578b39..5b5552f 100644 --- a/hysteria2/gecko.go +++ b/hysteria2/gecko.go @@ -68,6 +68,14 @@ func (g *GeckoPacketConn) Upstream() any { return g.PacketConn } +func (g *GeckoPacketConn) SetReadBuffer(bytes int) error { + return trySetReadBuffer(g.PacketConn, bytes) +} + +func (g *GeckoPacketConn) SetWriteBuffer(bytes int) error { + return trySetWriteBuffer(g.PacketConn, bytes) +} + func (g *GeckoPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) { if len(p) == 0 { return 0, nil diff --git a/hysteria2/salamander.go b/hysteria2/salamander.go index a18ea5f..e0bd028 100644 --- a/hysteria2/salamander.go +++ b/hysteria2/salamander.go @@ -2,6 +2,7 @@ package hysteria2 import ( "net" + "os" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" @@ -73,6 +74,34 @@ func (s *SalamanderPacketConn) Upstream() any { return s.PacketConn } +func (s *SalamanderPacketConn) SetReadBuffer(bytes int) error { + return trySetReadBuffer(s.PacketConn, bytes) +} + +func (s *SalamanderPacketConn) SetWriteBuffer(bytes int) error { + return trySetWriteBuffer(s.PacketConn, bytes) +} + +func trySetReadBuffer(conn net.PacketConn, bytes int) error { + udpConn, isUDPConn := common.Cast[interface { + SetReadBuffer(bytes int) error + }](conn) + if !isUDPConn { + return os.ErrInvalid + } + return udpConn.SetReadBuffer(bytes) +} + +func trySetWriteBuffer(conn net.PacketConn, bytes int) error { + udpConn, isUDPConn := common.Cast[interface { + SetWriteBuffer(bytes int) error + }](conn) + if !isUDPConn { + return os.ErrInvalid + } + return udpConn.SetWriteBuffer(bytes) +} + type VectorisedSalamanderPacketConn struct { SalamanderPacketConn writer N.VectorisedPacketWriter