From 523e5832993b5f768e1977f8092ff52ab4613f9f 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, 15 Jul 2025 09:56:53 +0000 Subject: [PATCH 1/2] UDP: Fix removeRay will close a connEntry that not belongs to it --- transport/internet/udp/dispatcher.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/transport/internet/udp/dispatcher.go b/transport/internet/udp/dispatcher.go index e6267d2f..f1cd5bfa 100644 --- a/transport/internet/udp/dispatcher.go +++ b/transport/internet/udp/dispatcher.go @@ -62,9 +62,14 @@ func (v *Dispatcher) getInboundRay(ctx context.Context, dest net.Destination) (* errors.LogInfo(ctx, "establishing new connection for ", dest) ctx, cancel := context.WithCancel(ctx) + entry := &connEntry{} removeRay := func() { - cancel() - v.RemoveRay() + if entry == v.conn { + cancel() + v.RemoveRay() + } else { + errors.LogError(ctx, "removeRay trying to remove a conn that not belongs to it, canceling.") + } } timer := signal.CancelAfterInactivity(ctx, removeRay, time.Minute) @@ -73,7 +78,7 @@ func (v *Dispatcher) getInboundRay(ctx context.Context, dest net.Destination) (* return nil, errors.New("failed to dispatch request to ", dest).Base(err) } - entry := &connEntry{ + *entry = connEntry{ link: link, timer: timer, cancel: removeRay, From 399ec65c8c0ebcbc62dcd68785b51cce0bdd8322 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, 15 Jul 2025 16:11:14 +0000 Subject: [PATCH 2/2] Prevent remove ray --- transport/internet/udp/dispatcher.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/transport/internet/udp/dispatcher.go b/transport/internet/udp/dispatcher.go index f1cd5bfa..b4b9a0d3 100644 --- a/transport/internet/udp/dispatcher.go +++ b/transport/internet/udp/dispatcher.go @@ -44,6 +44,10 @@ func NewDispatcher(dispatcher routing.Dispatcher, callback ResponseCallback) *Di func (v *Dispatcher) RemoveRay() { v.Lock() defer v.Unlock() + v.removeRay() +} + +func (v *Dispatcher) removeRay() { if v.conn != nil { common.Interrupt(v.conn.link.Reader) common.Close(v.conn.link.Writer) @@ -64,9 +68,11 @@ func (v *Dispatcher) getInboundRay(ctx context.Context, dest net.Destination) (* ctx, cancel := context.WithCancel(ctx) entry := &connEntry{} removeRay := func() { + v.Lock() + defer v.Unlock() if entry == v.conn { cancel() - v.RemoveRay() + v.removeRay() } else { errors.LogError(ctx, "removeRay trying to remove a conn that not belongs to it, canceling.") }