Refactor configuration handling and integrate command-line argument parsing with args.zig

This commit is contained in:
2026-08-01 23:28:06 +02:00
parent f902086e14
commit 250829e922
6 changed files with 68 additions and 7 deletions

137
config/config.toml Normal file
View File

@@ -0,0 +1,137 @@
[node]
id = "node-01"
data_dir = "/var/lib/zocket" # /$data_dir/$id/*
private_key = "/var/lib/zocket/node-01/identity.key" # ed25519, auto-generated on first run if missing, default = /$data_dir/$id/identity.key
# DEFAULT ASSUMPTION: ephemeral.
# A fresh keypair each restart is fine and expected as nothing is persisted to disk on purpose
# (see mesh.discoverability + mesh.trust below), everything mesh-wide is rediscovered via
# gossip/broadcast after (re)connecting to a seed peer in mesh.peers.
# EXCEPTION:
# If another node pins THIS node by pubkey in its own static mesh.peers[] entry, this
# key must be persisted (mount on a volume) as a pinned pubkey is a promise of a stable identity,
# and an ephemeral key breaks that pin on every restart.
# Only relevant for statically pinned, long-lived "hub" style nodes; auto-enrolled/broadcast-mode peers never need this.
[log]
level = "info" # debug | info | warn | error
format = "json" # json | text
output = "stdout" # stdout | /path/to/file.log
# ----
[listen.client]
enabled = true
bind = "0.0.0.0:8080"
[listen.client.tls]
enabled = false
cert = "/etc/zocket/client.crt"
key = "/etc/zocket/client.key"
[listen.client.auth]
mode = "token" # none | token
# If mode is set to "token", then the client_id is DERIVED from the matched
# identity's id below, never self-declared by the client.
# If mode is set to "none", any client may self-declare their client_id.
# On collision with an already-connected client_id, the NEW connection is rejected
# (first-connected wins) to prevent a second client from silently taking over another's routing identity.
[[listen.client.auth.identities]]
id = "discord-bot"
token = "sdfb08zbd98bzbh9r98gh98enb"
[[listen.client.auth.identities]]
id = "minecraft-mod"
token = "sv8sovz987w98ruw9fwbgfubwf"
[listen.client.access_control]
mode = "allowlist" # allowlist | blocklist | disabled
list = ["10.0.0.0/24", "127.0.0.1"] # IP | CIDR
[listen.client.limits]
max_message_bytes = 65536
max_frame_bytes = 65536
idle_timeout_secs = 300
ping_interval_secs = 30
max_missed_pongs = 2
max_connections = 256
[listen.client.limits.rate_limit]
enabled = true
messages_per_sec = 50
burst = 100
# ----
[listen.peer]
enabled = true
bind = "0.0.0.0:8181"
[listen.peer.tls]
enabled = false
cert = "/etc/zocket/peer.crt"
key = "/etc/zocket/peer.key"
require_client_cert = false
[listen.peer.auth]
mode = "pubkey" # pubkey
# Peer links can inject routes and broadcasts mesh-wide, so identity is always cryptographically verified, regardless of access_control.
# Every connecting peer proves possession of the private key matching a pubkey via a signed nonce challenge - no shared secret ever transits the wire.
# For a KNOWN node_id, the pubkey must match mesh.peers[].pubkey exactly, or the connection is rejected outright.
# For a claimed node_id that isn't yet known, see mesh.discoverability = "broadcast" below.
[listen.peer.access_control]
mode = "allowlist" # allowlist | blocklist | disabled
list = ["10.0.0.0/24", "127.0.0.1"] # IP | CIDR
[listen.peer.limits]
max_message_bytes = 1048576
idle_timeout_secs = 60
ping_interval_secs = 15
# ----
[mesh]
enabled = true
topology = "full" # full | static-partial | disabled
routing_mode = "gossip" # gossip | reactive | static
[mesh.discoverability]
mode = "static" # static | broadcast
# static: mesh.peers below is the complete, manually-maintained set of instances.
# broadcast: mesh.peers is just the initial seed; unknown nodes may connect and prove
# possession of a pubkey; they're auto-trusted and gossiped mesh-wide immediately.
# listen.peer.access_control is the real gate in this mode; scope it tightly.
[[mesh.peers]]
id = "node-02"
addr = "10.0.0.2:8181"
pubkey = "rijgeb8u845un34tun34tou3nt3ot3untz3otn3to"
reconnect = true
backoff_min_ms = 500
backoff_max_ms = 30000
[mesh.trust]
gossip_new_peers = true # propagate newly-enrolled peer identities to the rest of the mesh
[mesh.gossip]
seen_cache_ttl_secs = 300
route_ttl_secs = 0 # 0 = no expiry, rely on explicit ROUTE_REMOVE
[mesh.broadcast]
enabled = true
# Broadcasting (target = "*") is peer-only and never exposed to clients on listen.client.
# Floods across peer links using the same seen_cache dedup as gossip route announcements.
# only used if routing_mode = "reactive"
[mesh.reactive]
query_ttl_hops = 4
query_timeout_ms = 2000
negative_cache_secs = 30
# ----
# prometheus format
[metrics]
enabled = true
bind = "127.0.0.1:9090"