Count traffic per client address and report the busiest ones with the port totals

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-27 16:54:57 -06:00
1 parent b46e0813fe
commit ed9edbc9fd
7 files changed
+163 -17

No files matched your search

+12 -5
View File
@@ -73,6 +73,7 @@ type mapState struct {
rr atomic.Uint64
conns, bytesIn, bytesOut atomic.Int64
sources sourceTable // the same traffic per client address, for the top-sources list
epoch atomic.Int64 // current login generation; kept out of sig so a bump doesn't rebuild the resource
relayLn net.Listener // traefik mode: loopback port that reaches the targets through the tunnel
@@ -113,6 +114,7 @@ type Blacktip struct {
logq chan model.LogEntry
reportMu sync.Mutex
statsSince time.Time // when the traffic counters were last taken; guarded by reportMu
updating atomic.Bool
addrSig string // machine addresses a wildcard website was spread across, "" when none was
updateMsg string // outcome of the update Hammerhead asked for, reported back
@@ -610,11 +612,17 @@ func (b *Blacktip) report() {
st.Targets = append([]model.TargetHealth(nil), ms.health...)
ms.mu.Unlock()
rep.Status[id] = st
if c, in, out := ms.conns.Swap(0), ms.bytesIn.Swap(0), ms.bytesOut.Swap(0); c|in|out != 0 {
rep.Stats[id] = model.Stat{Conns: c, BytesIn: in, BytesOut: out}
if st, any := ms.takeStats(); any {
rep.Stats[id] = st
}
}
b.mu.Unlock()
now := time.Now()
if !b.statsSince.IsZero() {
rep.StatsSeconds = now.Sub(b.statsSince).Seconds()
}
prevSince := b.statsSince
b.statsSince = now
body, _ := json.Marshal(rep)
req, _ := http.NewRequest("POST", b.cfg.Hammerhead+"/edge/report", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+b.cfg.Token)
@@ -626,12 +634,11 @@ func (b *Blacktip) report() {
b.mu.Lock()
for id, st := range rep.Stats {
if ms := b.maps[id]; ms != nil {
ms.conns.Add(st.Conns)
ms.bytesIn.Add(st.BytesIn)
ms.bytesOut.Add(st.BytesOut)
ms.restoreStats(st)
}
}
b.mu.Unlock()
b.statsSince = prevSince // the traffic put back still spans from there
return
}
resp.Body.Close()