diff --git a/common/singbridge/pipe.go b/common/singbridge/pipe.go index d04ebda4..d6c0f3d8 100644 --- a/common/singbridge/pipe.go +++ b/common/singbridge/pipe.go @@ -4,8 +4,10 @@ import ( "context" "io" "net" + "time" "github.com/sagernet/sing/common/bufio" + "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/buf" "github.com/xtls/xray-core/transport" ) @@ -33,8 +35,26 @@ func (w *PipeConnWrapper) Close() error { return nil } +// This Read implemented a timeout to avoid goroutine leak. +// as a temporarily solution func (w *PipeConnWrapper) Read(b []byte) (n int, err error) { - return w.R.Read(b) + type readResult struct { + n int + err error + } + c := make(chan readResult, 1) + go func() { + n, err := w.R.Read(b) + c <- readResult{n: n, err: err} + }() + select { + case result := <-c: + return result.n, result.err + case <-time.After(300 * time.Second): + common.Close(w.R) + common.Interrupt(w.R) + return 0, buf.ErrReadTimeout + } } func (w *PipeConnWrapper) Write(p []byte) (n int, err error) {