Add connection history per peer with country and network lookup

- The stats sampler records sessions per peer: start, end, address and
  traffic. A session ends when the peer goes quiet or is disabled; a new
  one starts when the device changes networks. Stored in stats.json and
  kept as long as the daily traffic history (max 1000 per peer).
- Country and network operator come from the free DB-IP Lite databases
  (CC BY 4.0), downloaded monthly and looked up locally, so peer
  addresses never leave the server. Settings → Data retention can switch
  this off, which deletes the databases.
- API: GET /peers/{id}/sessions; peer stats include the current location;
  settings include the database status.
- Web UI and iOS app: connection history card, location line, country
  code in the peer list (web), switch in data retention.

Claude-Session: https://claude.ai/code/session_01RAnLbyQZ5ZTA7KqwXP98nw
This commit is contained in:
Daniel Redetzke
2026-10-03 19:21:10 +03:00
parent f31bb360c9
commit 37ab26b415
15 changed files with 707 additions and 21 deletions
+7 -2
View File
@@ -187,6 +187,10 @@ func run(configPath string) error {
return fmt.Errorf("open stats: %w", err)
}
geo := newGeo(dataDir, cfg.Stats.geoEnabled())
defer geo.Close()
stats.geo = geo
webTLS, err := setupTLS(cfg, dataDir)
if err != nil {
slog.Error("tls setup failed", "err", err)
@@ -200,13 +204,14 @@ func run(configPath string) error {
auth := newAuth(store)
app := &App{
store: store, kernel: kernel, recon: recon, stats: stats, auth: auth, tls: webTLS,
logPath: logPath, logw: logw, started: time.Now(), shutdown: shutdown,
logPath: logPath, logw: logw, geo: geo, started: time.Now(), shutdown: shutdown,
}
var wg sync.WaitGroup
wg.Add(2)
wg.Add(3)
go func() { defer wg.Done(); recon.Run(stop) }()
go func() { defer wg.Done(); stats.Run(stop) }()
go func() { defer wg.Done(); geo.Run(stop) }()
go func() {
t := time.NewTicker(10 * time.Minute)
defer t.Stop()