B5 rehearsal fix: sing-box stats registration needs all three lists
The B5 full-stack rehearsal caught a silent accounting killer: with the production switch set (inbound on, outbound off) the generated v2ray_api stats block omitted the outbounds list, and sing-box then registers NO counters at all — QueryStats answered zero entries while real traffic flowed (A/B against the real core: adding the list produced full user/inbound/outbound counters). - builder: whenever the stats block is generated, emit inbounds, users and outbounds together; the gates now only decide whether the block exists - master: enforce the inbound category gate at recording time in the agent traffic report (the whole-network accounting switch semantics: off period is never counted); onlines stay ungated - golden gate test updated to the corrected contract
This commit is contained in:
@@ -684,8 +684,21 @@ func (a *AgentController) reportTraffic(c *gin.Context) {
|
||||
jsonMsg(c, "Invalid request", err)
|
||||
return
|
||||
}
|
||||
// ITEM6 B5 recording gate: a sing-box core registers counters
|
||||
// only when every stats family is listed in its config, so the
|
||||
// generated config can no longer omit a switched-off category
|
||||
// (see the stats wiring in SingboxService). The whole-network
|
||||
// accounting switches (settings.trafficStatsSwitches, the
|
||||
// master switch on the Settings page) are therefore enforced
|
||||
// here, at recording time: with the inbound category off
|
||||
// (either direction), inbound totals and per-user traffic are
|
||||
// accepted but not recorded — the off period is never counted,
|
||||
// matching the switches' documented no-backfill semantics.
|
||||
// Online presence is not traffic accounting and stays ungated.
|
||||
sw := a.singboxService.GetTrafficStatsSwitches()
|
||||
recordInbound := sw.InboundUplink && sw.InboundDownlink
|
||||
db := database.GetDB()
|
||||
if agent.NodeID != nil {
|
||||
if recordInbound && agent.NodeID != nil {
|
||||
for _, ib := range req.Inbounds {
|
||||
if ib.Tag == "" || ib.Up+ib.Down <= 0 {
|
||||
continue
|
||||
@@ -699,15 +712,17 @@ func (a *AgentController) reportTraffic(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
var clientTraffics []*xray.ClientTraffic
|
||||
for _, u := range req.Users {
|
||||
if u.Email == "" || u.Up+u.Down <= 0 {
|
||||
continue
|
||||
if recordInbound {
|
||||
for _, u := range req.Users {
|
||||
if u.Email == "" || u.Up+u.Down <= 0 {
|
||||
continue
|
||||
}
|
||||
clientTraffics = append(clientTraffics, &xray.ClientTraffic{
|
||||
Email: u.Email,
|
||||
Up: u.Up,
|
||||
Down: u.Down,
|
||||
})
|
||||
}
|
||||
clientTraffics = append(clientTraffics, &xray.ClientTraffic{
|
||||
Email: u.Email,
|
||||
Up: u.Up,
|
||||
Down: u.Down,
|
||||
})
|
||||
}
|
||||
if len(clientTraffics) > 0 {
|
||||
if _, _, err := a.inboundService.AddTraffic(nil, clientTraffics); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user