From d21e9b0abd3a3472c07fafd7f407f3a08d99e07a Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Fri, 26 Jan 2024 04:42:45 -0500 Subject: [PATCH] Try a better fix for rare ssl error with freedom splice It seems the root cause is if the flag set at the inbound pipe reader, it is a race condition and freedom outbound can possibly do splice at the same time with inbound xtls writer. Now we set the flag at the earliest and always do splice at the next buffer cycle. --- proxy/proxy.go | 2 -- proxy/vless/encoding/encoding.go | 18 +++++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/proxy/proxy.go b/proxy/proxy.go index ee131315..4dcb6bf9 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -13,7 +13,6 @@ import ( "math/big" "runtime" "strconv" - "time" "github.com/pires/go-proxyproto" "github.com/xtls/xray-core/common/buf" @@ -479,7 +478,6 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net if inbound.CanSpliceCopy == 1 { newError("CopyRawConn splice").WriteToLog(session.ExportIDToError(ctx)) runtime.Gosched() // necessary - time.Sleep(time.Millisecond) // without this, there will be a rare ssl error for freedom splice w, err := tc.ReadFrom(readerConn) if readCounter != nil { readCounter.Add(w) diff --git a/proxy/vless/encoding/encoding.go b/proxy/vless/encoding/encoding.go index b7fb66f5..5fe79c08 100644 --- a/proxy/vless/encoding/encoding.go +++ b/proxy/vless/encoding/encoding.go @@ -225,15 +225,6 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate var ct stats.Counter for { buffer, err := reader.ReadMultiBuffer() - if trafficState.WriterSwitchToDirectCopy { - if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { - inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter - } - rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) - writer = buf.NewWriter(rawConn) - ct = writerCounter - trafficState.WriterSwitchToDirectCopy = false - } if !buffer.IsEmpty() { if ct != nil { ct.Add(int64(buffer.Len())) @@ -242,6 +233,15 @@ func XtlsWrite(reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdate if werr := writer.WriteMultiBuffer(buffer); werr != nil { return werr } + if trafficState.WriterSwitchToDirectCopy { + rawConn, _, writerCounter := proxy.UnwrapRawConn(conn) + writer = buf.NewWriter(rawConn) + ct = writerCounter + trafficState.WriterSwitchToDirectCopy = false + if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.CanSpliceCopy == 2 { + inbound.CanSpliceCopy = 1 // force the value to 1, don't use setter + } + } } if err != nil { return err