mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-23 03:17:14 +00:00
fix(db): clamp traffic counters below int64 max and repair overflowed rows
A counter pushed past int64 (multi-node setups hit this via historic delta-compounding bugs) makes SQLite silently promote the INTEGER cell to REAL. From then on the column no longer scans into the Go int64 field and every reader of client_traffics fails at once: the inbounds page, xray restarts, and node traffic sync all return "converting driver.Value type float64 to int64". Two-part fix: every unbounded "up = up + ?" add (local traffic, node delta merge, inbound counters, plus the Go-side outbound accumulation) now saturates at TrafficMax, a cap safely below math.MaxInt64 so one more delta cannot overflow; and a startup repair casts REAL-promoted cells back to INTEGER and clamps all traffic counters into [0, TrafficMax] across client_traffics, inbounds, outbound_traffics and node_client_traffics, restoring access to already-corrupted panels without manual sqlite surgery. Closes #5762
This commit is contained in:
@@ -42,6 +42,16 @@ func (s *OutboundService) AddTraffic(traffics []*xray.Traffic, clientTraffics []
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// saturatingAdd caps counters at database.TrafficMax: unlike the SQL paths,
|
||||
// this read-modify-write add happens in Go, where an int64 overflow silently
|
||||
// wraps negative instead of erroring (#5762).
|
||||
func saturatingAdd(a, b int64) int64 {
|
||||
if b > database.TrafficMax-a {
|
||||
return database.TrafficMax
|
||||
}
|
||||
return a + b
|
||||
}
|
||||
|
||||
func (s *OutboundService) addOutboundTraffic(tx *gorm.DB, traffics []*xray.Traffic) error {
|
||||
if len(traffics) == 0 {
|
||||
return nil
|
||||
@@ -61,9 +71,9 @@ func (s *OutboundService) addOutboundTraffic(tx *gorm.DB, traffics []*xray.Traff
|
||||
}
|
||||
|
||||
outbound.Tag = traffic.Tag
|
||||
outbound.Up = outbound.Up + traffic.Up
|
||||
outbound.Down = outbound.Down + traffic.Down
|
||||
outbound.Total = outbound.Up + outbound.Down
|
||||
outbound.Up = saturatingAdd(outbound.Up, traffic.Up)
|
||||
outbound.Down = saturatingAdd(outbound.Down, traffic.Down)
|
||||
outbound.Total = saturatingAdd(outbound.Up, outbound.Down)
|
||||
|
||||
err = tx.Save(&outbound).Error
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user