From 237707b31c4eec85396e1edc456028d9b44fde30 Mon Sep 17 00:00:00 2001 From: Alireza Ahmadi Date: Sun, 22 Mar 2026 18:29:58 +0100 Subject: [PATCH] fix conn tracker memory leak #1056 --- core/box.go | 6 ++++++ core/tracker_conn.go | 14 ++++++++++++++ core/tracker_stats.go | 8 ++++++++ 3 files changed, 28 insertions(+) diff --git a/core/box.go b/core/box.go index 172ca11..aa91b7f 100644 --- a/core/box.go +++ b/core/box.go @@ -554,6 +554,12 @@ func (s *Box) Close() error { err = errors.Join(err, closeErr) s.logger.Trace("close logger completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") s.logger.Info("sing-box closed (live time: ", F.Seconds(time.Since(s.createdAt).Seconds()), "s)") + if s.statsTracker != nil { + s.statsTracker.Reset() + } + if s.connTracker != nil { + s.connTracker.Reset() + } return err } diff --git a/core/tracker_conn.go b/core/tracker_conn.go index 5b38a0f..2bd3384 100644 --- a/core/tracker_conn.go +++ b/core/tracker_conn.go @@ -29,6 +29,20 @@ func NewConnTracker() *ConnTracker { } } +func (c *ConnTracker) Reset() { + c.access.Lock() + defer c.access.Unlock() + for _, connInfo := range c.connections { + if connInfo.Conn != nil { + _ = connInfo.Conn.Close() + } + if connInfo.PacketConn != nil { + _ = connInfo.PacketConn.Close() + } + } + c.connections = make(map[string]*ConnectionInfo) +} + func (c *ConnTracker) generateConnectionID() string { return uuid.Must(uuid.NewV4()).String() } diff --git a/core/tracker_stats.go b/core/tracker_stats.go index 2247660..2592693 100644 --- a/core/tracker_stats.go +++ b/core/tracker_stats.go @@ -34,6 +34,14 @@ func NewStatsTracker() *StatsTracker { } } +func (c *StatsTracker) Reset() { + c.access.Lock() + defer c.access.Unlock() + c.inbounds = make(map[string]Counter) + c.outbounds = make(map[string]Counter) + c.users = make(map[string]Counter) +} + func (c *StatsTracker) getReadCounters(inbound string, outbound string, user string) ([]*atomic.Int64, []*atomic.Int64) { var readCounter []*atomic.Int64 var writeCounter []*atomic.Int64