fix(traffic): restore quota-disabled inbounds when their traffic is reset (#6962)

An inbound switched off by its own traffic cap came back on the periodic reset, but the admin per-inbound reset and Reset All Traffic only zeroed the counters. After that nothing could tell it from a hand-disabled inbound, so it stayed off with every client on it. Both admin resets now re-enable the inbounds their cap switched off, using the predicate the periodic job used, now in the service next to disableInvalidInbounds; expired and hand-disabled inbounds stay off.
This commit is contained in:
25f2002654
2026-11-02 20:20:25 +05:30
committed by GitHub
parent 1796352600
commit eae4725d99
9 changed files with 184 additions and 38 deletions
+43 -10
View File
@@ -832,14 +832,33 @@ func (s *InboundService) resetClientTrafficLocked(id int, clientEmail string) (b
return needRestart, nil, nil
}
func (s *InboundService) ResetAllTraffics() error {
// ResetAllTraffics zeroes every inbound's counters and brings back the inbounds a traffic
// cap switched off; left off, every client on them would stay dead.
func (s *InboundService) ResetAllTraffics() (bool, error) {
var restore []int
err := submitTrafficWrite(func() error {
db := database.GetDB()
var err error
restore, err = quotaDisabledInboundIDs(db, time.Now().UnixMilli())
if err != nil {
return err
}
return s.resetAllTrafficsLocked()
})
if err == nil {
s.propagateResetAllTrafficsToNodes()
if err != nil {
return false, err
}
return err
needRestart := false
for _, id := range restore {
nr, err := s.SetInboundEnable(id, true)
if err != nil {
logger.Warning("ResetAllTraffics: re-enable quota-disabled inbound", id, "failed:", err)
continue
}
needRestart = needRestart || nr
}
s.propagateResetAllTrafficsToNodes()
return needRestart, nil
}
func (s *InboundService) resetAllTrafficsLocked() error {
@@ -878,23 +897,37 @@ func (s *InboundService) propagateResetAllTrafficsToNodes() {
})
}
func (s *InboundService) ResetInboundTraffic(id int) error {
// ResetInboundTraffic zeroes one inbound's counters and brings it back when
// its own traffic cap was what switched it off.
func (s *InboundService) ResetInboundTraffic(id int) (bool, error) {
var inbound *model.Inbound
var quotaOff bool
if err := submitTrafficWrite(func() error {
db := database.GetDB()
if err := db.Model(model.Inbound{}).
Where("id = ?", id).
var err error
quotaOff, err = quotaDisabledInbound(db, id, time.Now().UnixMilli())
if err != nil {
return err
}
if err := db.Model(model.Inbound{}).Where("id = ?", id).
Updates(map[string]any{"up": 0, "down": 0}).Error; err != nil {
return err
}
var err error
inbound, err = s.GetInbound(id)
if err != nil {
return err
}
return nil
}); err != nil {
return err
return false, err
}
needRestart := false
if quotaOff {
nr, err := s.SetInboundEnable(id, true)
if err != nil {
logger.Warning("ResetInboundTraffic: re-enable quota-disabled inbound", id, "failed:", err)
}
needRestart = needRestart || nr
}
if inbound != nil && inbound.NodeID != nil {
if rt, rterr := s.runtimeFor(inbound); rterr == nil {
@@ -905,7 +938,7 @@ func (s *InboundService) ResetInboundTraffic(id int) error {
logger.Warning("ResetInboundTraffic: runtime lookup failed:", rterr)
}
}
return nil
return needRestart, nil
}
func (s *InboundService) DelDepletedClients(id int) (err error) {