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.
This commit is contained in:
@@ -61,6 +61,38 @@ nonisolated struct PeerStats: Decodable, Hashable {
|
||||
let lastHandshake: Date?
|
||||
let endpoint: String
|
||||
let down24h, up24h, down30d, up30d, downTotal, upTotal: Int64
|
||||
let location: GeoInfo?
|
||||
}
|
||||
|
||||
/// Country and network of an address, from the server's DB-IP lookup.
|
||||
nonisolated struct GeoInfo: Decodable, Hashable {
|
||||
let country: String?
|
||||
let countryName: String?
|
||||
let asn: Int?
|
||||
let network: String?
|
||||
|
||||
/// "Germany · Deutsche Telekom AG" or "Local network".
|
||||
var label: String {
|
||||
[countryName ?? country, network].compactMap { $0 }.filter { !$0.isEmpty }.joined(separator: " · ")
|
||||
}
|
||||
}
|
||||
|
||||
/// One row of a peer's connection history.
|
||||
nonisolated struct ConnSession: Decodable, Identifiable, Hashable {
|
||||
let start: Date
|
||||
let end: Date
|
||||
let open: Bool
|
||||
let seconds: Int64
|
||||
let endpoint: String
|
||||
let ip: String
|
||||
let geo: GeoInfo?
|
||||
let down: Int64
|
||||
let up: Int64
|
||||
var id: String { "\(start.timeIntervalSince1970)-\(ip)" }
|
||||
}
|
||||
|
||||
nonisolated struct SessionsResponse: Decodable {
|
||||
let sessions: [ConnSession]
|
||||
}
|
||||
|
||||
nonisolated struct Peer: Decodable, Identifiable, Hashable {
|
||||
@@ -166,6 +198,12 @@ nonisolated struct LogSettings: Codable, Equatable {
|
||||
nonisolated struct StatsSettings: Codable, Equatable {
|
||||
var hourlyHours: Int
|
||||
var dailyDays: Int
|
||||
var geoip: Bool?
|
||||
}
|
||||
|
||||
nonisolated struct GeoStatus: Decodable {
|
||||
let enabled: Bool
|
||||
let updated: Date?
|
||||
}
|
||||
|
||||
nonisolated struct AppSettings: Decodable {
|
||||
@@ -175,6 +213,7 @@ nonisolated struct AppSettings: Decodable {
|
||||
var adminUsername: String
|
||||
var fingerprint: String
|
||||
var logPath: String
|
||||
var geo: GeoStatus?
|
||||
}
|
||||
|
||||
nonisolated struct SettingsResult: Decodable {
|
||||
|
||||
Reference in New Issue
Block a user