From c123f163c20d5f54cb92fc1421c844955cddbaaf Mon Sep 17 00:00:00 2001 From: RPRX <63339210+RPRX@users.noreply.github.com> Date: Tue, 2 Dec 2025 13:28:00 +0000 Subject: [PATCH] XTLS Vision: Discard expired pre-connect conn automatically https://t.me/projectXray/4538408 https://github.com/XTLS/Xray-core/pull/5270#issuecomment-3602122299 --- proxy/vless/outbound/outbound.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/proxy/vless/outbound/outbound.go b/proxy/vless/outbound/outbound.go index 504b2126..17e82210 100644 --- a/proxy/vless/outbound/outbound.go +++ b/proxy/vless/outbound/outbound.go @@ -57,7 +57,12 @@ type Handler struct { testpre uint32 initpre sync.Once - preConns chan stat.Connection + preConns chan *ConnExpire +} + +type ConnExpire struct { + Conn stat.Connection + Expire time.Time } // New creates a new VLess outbound handler. @@ -141,25 +146,33 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte if h.testpre > 0 && h.reverse == nil { h.initpre.Do(func() { - h.preConns = make(chan stat.Connection) + h.preConns = make(chan *ConnExpire) for range h.testpre { // TODO: randomize go func() { defer func() { recover() }() ctx := xctx.ContextWithID(context.Background(), session.NewID()) for { - time.Sleep(time.Millisecond * 200) // TODO: randomize conn, err := dialer.Dial(ctx, rec.Destination) if err != nil { errors.LogWarningInner(ctx, err, "pre-connect failed") continue } - h.preConns <- conn + h.preConns <- &ConnExpire{Conn: conn, Expire: time.Now().Add(time.Minute * 2)} // TODO: customize & randomize + time.Sleep(time.Millisecond * 200) // TODO: customize & randomize } }() } }) - if conn = <-h.preConns; conn == nil { - return errors.New("closed handler").AtWarning() + for { + connTime := <-h.preConns + if connTime == nil { + return errors.New("closed handler").AtWarning() + } + if time.Now().Before(connTime.Expire) { + conn = connTime.Conn + break + } + connTime.Conn.Close() } }