From ea5a53ce6d9a0c055fb463f19b1a6c91c6f516d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E6=89=87=E6=BB=91=E7=BF=94=E7=BF=BC?= Date: Tue, 23 Dec 2025 11:10:58 +0000 Subject: [PATCH] Try fix --- common/buf/copy.go | 65 +++++++++++++++++++++----------- proxy/vless/outbound/outbound.go | 2 +- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/common/buf/copy.go b/common/buf/copy.go index 9ec5b50e..7589e0bb 100644 --- a/common/buf/copy.go +++ b/common/buf/copy.go @@ -115,12 +115,7 @@ func Copy(reader Reader, writer Writer, options ...CopyOption) error { for _, option := range options { option(&handler) } - var err error - if sReader, ok := reader.(*SingleReader); ok && false { - err = copyV(sReader, writer, &handler) - } else { - err = copyInternal(reader, writer, &handler) - } + err := copyInternal(reader, writer, &handler) if err != nil && errors.Cause(err) != io.EOF { return err } @@ -141,7 +136,31 @@ func CopyOnceTimeout(reader Reader, writer Writer, timeout time.Duration) error return writer.WriteMultiBuffer(mb) } -func copyV(r *SingleReader, w Writer, handler *copyHandler) error { +func TryCopyV(reader Reader, writer Writer, options ...CopyOption) error { + var doCopyV bool + if tr, ok := reader.(*TimeoutWrapperReader); ok { + if _, ok := tr.Reader.(*SingleReader); ok { + doCopyV = true + } + } + if _, ok := reader.(*SingleReader); ok { + doCopyV = true + } + if !doCopyV { + return Copy(reader, writer, options...) + } + var handler copyHandler + for _, option := range options { + option(&handler) + } + err := copyVInternal(reader, writer, &handler) + if err != nil && errors.Cause(err) != io.EOF { + return err + } + return nil +} + +func copyVInternal(r Reader, w Writer, handler *copyHandler) error { // channel buffer size is maxBuffer/maxPerPacketLen (ignore the case of many small packets) // default buffer size: // 0 in ARM MIPS MIPSLE @@ -162,23 +181,25 @@ func copyV(r *SingleReader, w Writer, handler *copyHandler) error { defer wg.Done() defer close(cache) for { - b, err := r.readBuffer() - if err == nil { - select { - case cache <- b: - // must be write error - case <-stopRead: - b.Release() + mb, err := r.ReadMultiBuffer() + for _, b := range mb { + if err == nil { + select { + case cache <- b: + // must be write error + case <-stopRead: + b.Release() + return + } + } else { + rErr = err + select { + case cache <- b: + case <-stopRead: + b.Release() + } return } - } else { - rErr = err - select { - case cache <- b: - case <-stopRead: - b.Release() - } - return } } }() diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 17e82210..078ee484 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -394,7 +394,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte err = encoding.XtlsRead(serverReader, clientWriter, timer, conn, trafficState, false, ctx) } else { // from serverReader.ReadMultiBuffer to clientWriter.WriteMultiBuffer - err = buf.Copy(serverReader, clientWriter, buf.UpdateActivity(timer)) + err = buf.TryCopyV(serverReader, clientWriter, buf.UpdateActivity(timer)) } if err != nil {