From 14bacec75ab9193aee64886d117d0ce819401237 Mon Sep 17 00:00:00 2001 From: Niko Marmeladkov Date: Tue, 23 Jun 2026 12:24:56 +0300 Subject: [PATCH] fix: remove duplicate user_manager instance and reset traffic counters after report - Remove second user_manager creation via serviceManager.Create to prevent double-counting (both instances tracked the same connections) - Reset per-user atomic counters after each successful traffic report so the control panel receives independent per-interval deltas instead of unbounded cumulative values --- box.go | 12 ------------ service/usermanager/manager.go | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/box.go b/box.go index db57d095..f500df12 100644 --- a/box.go +++ b/box.go @@ -441,18 +441,6 @@ func New(options Options) (*Box, error) { service.MustRegister[adapter.V2RayServer](ctx, v2rayServer) } } - if experimentalOptions.UserManager != nil { - err = serviceManager.Create( - ctx, - logFactory.NewLogger("service/user_manager"), - "user_manager", - C.TypeUserManager, - experimentalOptions.UserManager, - ) - if err != nil { - return nil, E.Cause(err, "create user_manager") - } - } if ntpOptions.Enabled { ntpDialer, err := dialer.New(ctx, ntpOptions.DialerOptions, ntpOptions.ServerIsDomain()) if err != nil { diff --git a/service/usermanager/manager.go b/service/usermanager/manager.go index 8cecb63d..10ed243e 100644 --- a/service/usermanager/manager.go +++ b/service/usermanager/manager.go @@ -576,6 +576,20 @@ func (m *Manager) reportTrafficToServer() { } resp.Body.Close() m.logger.Debug("traffic reported, users=", len(traffic)) + + // Reset counters after successful report so the next report only + // contains fresh traffic (delta since last report). + // This avoids overcounting when multiple nodes or user_manager + // instances report for the same user — the control panel always + // receives independent per-interval values. + m.trafficAccess.Lock() + for username := range traffic { + if stored, ok := m.traffic[username]; ok { + stored.Tx.Add(-traffic[username].Tx) + stored.Rx.Add(-traffic[username].Rx) + } + } + m.trafficAccess.Unlock() } // HTTP API