From 9525cabf4e70f27748956c08ed05802f4a65bee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 20 Dec 2023 19:42:04 +0800 Subject: [PATCH] Fix missing UDP timeout --- hysteria/service.go | 8 +++++++- hysteria2/service.go | 3 +++ hysteria2/service_packet.go | 4 +++- tuic/service.go | 3 +++ tuic/service_packet.go | 4 +++- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/hysteria/service.go b/hysteria/service.go index 92ada68..725ffc3 100644 --- a/hysteria/service.go +++ b/hysteria/service.go @@ -9,6 +9,7 @@ import ( "os" "runtime" "sync" + "time" "github.com/sagernet/quic-go" "github.com/sagernet/sing-quic" @@ -16,6 +17,7 @@ import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/auth" "github.com/sagernet/sing/common/baderror" + "github.com/sagernet/sing/common/canceler" E "github.com/sagernet/sing/common/exceptions" "github.com/sagernet/sing/common/logger" M "github.com/sagernet/sing/common/metadata" @@ -32,6 +34,7 @@ type ServiceOptions struct { XPlusPassword string TLSConfig aTLS.ServerConfig UDPDisabled bool + UDPTimeout time.Duration Handler ServerHandler // Legacy options @@ -58,6 +61,7 @@ type Service[U comparable] struct { quicConfig *quic.Config userMap map[string]U udpDisabled bool + udpTimeout time.Duration handler ServerHandler quicListener io.Closer } @@ -109,6 +113,7 @@ func NewService[U comparable](options ServiceOptions) (*Service[U], error) { userMap: make(map[string]U), handler: options.Handler, udpDisabled: options.UDPDisabled, + udpTimeout: options.UDPTimeout, }, nil } @@ -272,7 +277,8 @@ func (s *serverSession[U]) handleStream(stream quic.Stream) error { udpConn.closeWithError(E.Cause(err, "write server response")) return err } - go s.handler.NewPacketConnection(udpConn.ctx, udpConn, M.Metadata{ + newCtx, newConn := canceler.NewPacketConn(udpConn.ctx, udpConn, s.udpTimeout) + go s.handler.NewPacketConnection(newCtx, newConn, M.Metadata{ Source: s.source, Destination: M.ParseSocksaddrHostPort(request.Host, request.Port), }) diff --git a/hysteria2/service.go b/hysteria2/service.go index e8b65d8..ba86240 100644 --- a/hysteria2/service.go +++ b/hysteria2/service.go @@ -41,6 +41,7 @@ type ServiceOptions struct { SalamanderPassword string TLSConfig aTLS.ServerConfig UDPDisabled bool + UDPTimeout time.Duration Handler ServerHandler MasqueradeHandler http.Handler } @@ -62,6 +63,7 @@ type Service[U comparable] struct { quicConfig *quic.Config userMap map[string]U udpDisabled bool + udpTimeout time.Duration handler ServerHandler masqueradeHandler http.Handler quicListener io.Closer @@ -97,6 +99,7 @@ func NewService[U comparable](options ServiceOptions) (*Service[U], error) { quicConfig: quicConfig, userMap: make(map[string]U), udpDisabled: options.UDPDisabled, + udpTimeout: options.UDPTimeout, handler: options.Handler, masqueradeHandler: options.MasqueradeHandler, }, nil diff --git a/hysteria2/service_packet.go b/hysteria2/service_packet.go index 8ac6e03..0349fbb 100644 --- a/hysteria2/service_packet.go +++ b/hysteria2/service_packet.go @@ -3,6 +3,7 @@ package hysteria2 import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/canceler" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" ) @@ -47,7 +48,8 @@ func (s *serverSession[U]) handleUDPMessage(message *udpMessage) { s.udpAccess.Lock() s.udpConnMap[message.sessionID] = udpConn s.udpAccess.Unlock() - go s.handler.NewPacketConnection(udpConn.ctx, udpConn, M.Metadata{ + newCtx, newConn := canceler.NewPacketConn(udpConn.ctx, udpConn, s.udpTimeout) + go s.handler.NewPacketConnection(newCtx, newConn, M.Metadata{ Source: s.source, Destination: M.ParseSocksaddr(message.destination), }) diff --git a/tuic/service.go b/tuic/service.go index f9fb5ca..b57f9af 100644 --- a/tuic/service.go +++ b/tuic/service.go @@ -35,6 +35,7 @@ type ServiceOptions struct { AuthTimeout time.Duration ZeroRTTHandshake bool Heartbeat time.Duration + UDPTimeout time.Duration Handler ServiceHandler } @@ -53,6 +54,7 @@ type Service[U comparable] struct { passwordMap map[U]string congestionControl string authTimeout time.Duration + udpTimeout time.Duration handler ServiceHandler quicListener io.Closer @@ -88,6 +90,7 @@ func NewService[U comparable](options ServiceOptions) (*Service[U], error) { userMap: make(map[[16]byte]U), congestionControl: options.CongestionControl, authTimeout: options.AuthTimeout, + udpTimeout: options.UDPTimeout, handler: options.Handler, }, nil } diff --git a/tuic/service_packet.go b/tuic/service_packet.go index d4c31c3..5493d8a 100644 --- a/tuic/service_packet.go +++ b/tuic/service_packet.go @@ -3,6 +3,7 @@ package tuic import ( "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/auth" + "github.com/sagernet/sing/common/canceler" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" ) @@ -65,7 +66,8 @@ func (s *serverSession[U]) handleUDPMessage(message *udpMessage, udpStream bool) s.udpAccess.Lock() s.udpConnMap[message.sessionID] = udpConn s.udpAccess.Unlock() - go s.handler.NewPacketConnection(udpConn.ctx, udpConn, M.Metadata{ + newCtx, newConn := canceler.NewPacketConn(udpConn.ctx, udpConn, s.udpTimeout) + go s.handler.NewPacketConnection(newCtx, newConn, M.Metadata{ Source: s.source, Destination: message.destination, })