Browse Source

Fix ss2022 udp leak

Fangliding 1 week ago
parent
commit
0398123261
1 changed files with 27 additions and 3 deletions
  1. 27 3
      common/singbridge/packet.go

+ 27 - 3
common/singbridge/packet.go

@@ -2,10 +2,12 @@ package singbridge
 
 import (
 	"context"
+	"time"
 
 	B "github.com/sagernet/sing/common/buf"
 	"github.com/sagernet/sing/common/bufio"
 	M "github.com/sagernet/sing/common/metadata"
+	"github.com/xtls/xray-core/common"
 	"github.com/xtls/xray-core/common/buf"
 	"github.com/xtls/xray-core/common/net"
 	"github.com/xtls/xray-core/transport"
@@ -29,6 +31,8 @@ type PacketConnWrapper struct {
 	cached buf.MultiBuffer
 }
 
+// This ReadPacket implemented a timeout to avoid goroutine leak like PipeConnWrapper.Read()
+// as a temporarily solution
 func (w *PacketConnWrapper) ReadPacket(buffer *B.Buffer) (M.Socksaddr, error) {
 	if w.cached != nil {
 		mb, bb := buf.SplitFirst(w.cached)
@@ -47,10 +51,30 @@ func (w *PacketConnWrapper) ReadPacket(buffer *B.Buffer) (M.Socksaddr, error) {
 			return ToSocksaddr(destination), nil
 		}
 	}
-	mb, err := w.ReadMultiBuffer()
-	if err != nil {
-		return M.Socksaddr{}, err
+
+	// timeout
+	type readResult struct {
+		mb  buf.MultiBuffer
+		err error
+	}
+	c := make(chan readResult, 1)
+	go func() {
+		mb, err := w.ReadMultiBuffer()
+		c <- readResult{mb: mb, err: err}
+	}()
+	var mb buf.MultiBuffer
+	select {
+	case <-time.After(60 * time.Second):
+		common.Close(w.Reader)
+		common.Interrupt(w.Reader)
+		return M.Socksaddr{}, buf.ErrReadTimeout
+	case result := <-c:
+		if result.err != nil {
+			return M.Socksaddr{}, result.err
+		}
+		mb = result.mb
 	}
+
 	nb, bb := buf.SplitFirst(mb)
 	if bb == nil {
 		return M.Socksaddr{}, nil