Fix documentation drift from recent feature additions

Update 9 documentation files to match current implementation:
- Add missing rekey config section (node.rekey.*) and host mapping
  section to fips-configuration.md
- Update Ethernet frame format from [type:1][payload] to
  [type:1][length:2 LE][payload] in wire-formats and transport docs
- Fix Ethernet effective MTU from interface-1 to interface-3
- Mark rekey as Implemented in mesh-layer and session-layer status tables
- Change TCP default port examples from 443 to 8443
- Add rekey, persistent identity, host mapping, mesh size estimation to
  README features and status sections
- Update chaos scenario count from 16 to 20, add rekey topology to
  static test docs
This commit is contained in:
Johnathan Corgan
2026-03-11 03:11:12 +00:00
parent b33d6531ce
commit f37eb4b846
10 changed files with 87 additions and 29 deletions
+8
View File
@@ -14,15 +14,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Docker sidecar deployment for containerized services
- Comprehensive node and transport statistics via control socket
- fipstop TUI monitoring tool with smoothed metrics and quality indices
- fipstop peers display: transport type, direction, and tree roles
- Estimated mesh size from bloom filter cardinality
- ECN congestion signaling and transport congestion detection
- Persistent identity with key file management (`fipsctl keygen`)
- Periodic Noise rekey with fresh DH for forward secrecy (FMP + FSP)
- Host-to-npub static mapping: resolve `hostname.fips` via host map
populated from peer config aliases and `/etc/fips/hosts` file
- DNS responder auto-reloads hosts file on modification (no restart needed)
- Debian/Ubuntu `.deb` packaging via cargo-deb
- Systemd service packaging with tarball installer
- Build version metadata: git commit hash, dirty flag, and target triple
embedded in all binaries via `--version`
- Local CI runner script (`testing/ci-local.sh`)
- TCP transport node-level integration tests
- CI: expanded integration matrix, nextest JUnit reporting, workflow_dispatch
- CHANGELOG.md following Keep a Changelog format
### Fixed
@@ -32,6 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ethernet AEAD decryption failures caused by minimum-frame padding
- Link-dead detection skipping peers that never send data
- FMP version check added to TCP stream reader
- Control socket path mismatch between daemon and clients
- fips-dns.service pulling in systemd-resolved and hanging on missing fips0
### Changed
+6 -3
View File
@@ -42,11 +42,11 @@ endpoints.
- **Multi-transport** — UDP, TCP, and Ethernet today; designed for
Bluetooth, serial, radio, and Tor
- **Noise encryption** — hop-by-hop link encryption plus independent
end-to-end session encryption
end-to-end session encryption, with periodic rekey for forward secrecy
- **Nostr-native identity** — secp256k1 keypairs as node addresses, no
registration or central authority
- **IPv6 adaptation** — TUN interface maps npubs to fd00::/8 addresses for
unmodified IP applications
unmodified IP applications; static hostname mapping (`/etc/fips/hosts`)
- **Metrics Measurement Protocol** — per-link RTT, loss, jitter, and goodput
measurement
- **ECN congestion signaling** — hop-by-hop CE flag relay with RFC 3168 IPv6
@@ -248,8 +248,11 @@ UDP, TCP, and Ethernet but has not been tested beyond small meshes.
- Spanning tree construction with greedy coordinate routing
- Bloom filter discovery for finding nodes without global state
- Noise IK (link layer) and Noise XK (session layer) encryption
- Periodic Noise rekey with forward secrecy (FMP + FSP)
- Persistent node identity with key file management
- IPv6 TUN adapter with DNS resolution of `.fips` names
- Per-link metrics (RTT, loss, jitter, goodput)
- Static hostname mapping (`/etc/fips/hosts`) with auto-reload
- Per-link metrics (RTT, loss, jitter, goodput) and mesh size estimation
- ECN congestion signaling (hop-by-hop CE relay, IPv6 CE marking, kernel drop detection)
- UDP, TCP, and Ethernet transports
- Runtime inspection via `fipsctl` and `fipstop`
+35 -4
View File
@@ -194,6 +194,20 @@ outgoing link ETX ≥ `etx_threshold`, or kernel receive buffer drops detected o
any local transport. CE is relayed hop-by-hop: once set on any hop, the flag
stays set for all subsequent hops to the destination.
### Rekey (`node.rekey.*`)
Controls periodic Noise rekey for forward secrecy. When enabled, both FMP
(link-layer IK) and FSP (session-layer XK) sessions perform fresh Diffie-Hellman
key exchanges after a time or message count threshold, whichever comes first.
A 10-second drain window keeps the old session active for decryption during
cutover.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `node.rekey.enabled` | bool | `true` | Enable periodic Noise rekey on all links and sessions |
| `node.rekey.after_secs` | u64 | `120` | Initiate rekey after this many seconds on a session |
| `node.rekey.after_messages` | u64 | `65536` | Initiate rekey after this many messages sent on a session |
### Session / Data Plane (`node.session.*`)
Controls end-to-end session behavior and packet queuing.
@@ -268,6 +282,19 @@ with the node for routing.
The `dns.ttl` value should not exceed `node.cache.coord_ttl_secs` to avoid
stale address mappings.
### Host Mapping
The DNS resolver checks a host map before falling back to direct npub
resolution, enabling names like `gateway.fips` instead of `npub1...fips`.
The host map is populated from two sources:
1. **Peer aliases** — the `alias` field on configured peers in `peers:`.
2. **Hosts file**`/etc/fips/hosts`, one `hostname npub1...` per line.
Blank lines and `#` comments are allowed.
The hosts file is auto-reloaded on modification (mtime change) without
restarting the daemon. Hostnames are case-insensitive.
## Transports (`transports.*`)
### UDP (`transports.udp.*`)
@@ -288,7 +315,7 @@ Requires `CAP_NET_RAW` or running as root. Linux only.
|-----------|------|---------|-------------|
| `interface` | string | *(required)* | Network interface name (e.g., `"eth0"`, `"enp3s0"`) |
| `ethertype` | u16 | `0x2121` | EtherType |
| `mtu` | u16 | *(auto)* | Override MTU. Default: interface MTU minus 1 (for frame type prefix) |
| `mtu` | u16 | *(auto)* | Override MTU. Default: interface MTU minus 3 (for frame type + length prefix) |
| `recv_buf_size` | usize | `2097152` | Socket receive buffer size in bytes (2 MB) |
| `send_buf_size` | usize | `2097152` | Socket send buffer size in bytes (2 MB) |
| `discovery` | bool | `true` | Listen for discovery beacons from other nodes |
@@ -324,7 +351,7 @@ overhead.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `transports.tcp.bind_addr` | string | *(none)* | Listen address (e.g., `"0.0.0.0:443"`). If omitted, outbound-only mode. |
| `transports.tcp.bind_addr` | string | *(none)* | Listen address (e.g., `"0.0.0.0:8443"`). If omitted, outbound-only mode. |
| `transports.tcp.mtu` | u16 | `1400` | Default MTU. Per-connection MTU derived from `TCP_MAXSEG` when available. |
| `transports.tcp.connect_timeout_ms` | u64 | `5000` | Outbound connect timeout in milliseconds |
| `transports.tcp.nodelay` | bool | `true` | `TCP_NODELAY` (disable Nagle for low latency) |
@@ -514,6 +541,10 @@ node:
enabled: true # ECN congestion signaling (CE flag relay)
loss_threshold: 0.05 # MMP loss rate threshold for CE marking (5%)
etx_threshold: 3.0 # MMP ETX threshold for CE marking
rekey:
enabled: true # periodic Noise rekey for forward secrecy
after_secs: 120 # rekey interval (seconds)
after_messages: 65536 # rekey after N messages sent
control:
enabled: true
socket_path: null # null = auto ($XDG_RUNTIME_DIR → /run/fips → /tmp fallback)
@@ -542,7 +573,7 @@ transports:
# ethernet: # uncomment to enable (requires CAP_NET_RAW)
# interface: "eth0" # required: network interface name
# ethertype: 0x2121 # default EtherType
# mtu: null # null = interface MTU - 1 (typically 1499)
# mtu: null # null = interface MTU - 3 (typically 1497)
# recv_buf_size: 2097152 # 2 MB
# send_buf_size: 2097152 # 2 MB
# discovery: true # listen for beacons
@@ -551,7 +582,7 @@ transports:
# accept_connections: false # accept inbound handshakes
# beacon_interval_secs: 30 # beacon interval (min 10)
# tcp: # uncomment to enable TCP transport
# bind_addr: "0.0.0.0:443" # listen address (omit for outbound-only)
# bind_addr: "0.0.0.0:8443" # listen address (omit for outbound-only)
# mtu: 1400 # default MTU
# connect_timeout_ms: 5000 # outbound connect timeout
# nodelay: true # TCP_NODELAY
+1 -1
View File
@@ -573,7 +573,7 @@ an attacker sends invalid packets to elicit responses.
| Path MTU tracking (SessionDatagram) | **Implemented** |
| Metrics Measurement Protocol (MMP) | **Implemented** |
| ECN congestion signaling (CE relay, IPv6 marking) | **Implemented** |
| Rekey with index rotation | Planned |
| Rekey with index rotation | **Implemented** |
| Allowlist/blocklist | Planned |
## References
+1 -1
View File
@@ -538,7 +538,7 @@ MMP session metrics session=npub1tdwa...84le rtt=4.3ms loss=0.6% jitter=0.2ms go
| PathBroken handling | **Implemented** |
| Simultaneous initiation tie-breaker | **Implemented** |
| Flush coord cache on parent change | **Implemented** |
| Rekey | Planned |
| Rekey | **Implemented** |
| Path MTU tracking (FMP SessionDatagram field) | **Implemented** |
| Path MTU notification (end-to-end echo) | **Implemented** |
+10 -6
View File
@@ -272,16 +272,20 @@ EtherType 0x2121. SOCK_DGRAM mode
lets the kernel handle Ethernet header construction and parsing — the
transport deals only with payloads and MAC addresses.
A 1-byte frame type prefix disambiguates data frames (0x00) from discovery
beacons (0x01) on the receive path. This costs one byte of MTU but allows
beacons and data to share the same EtherType and socket.
Data frames use a 3-byte header: a 1-byte frame type (`0x00`) followed by
a 2-byte little-endian payload length. The length field allows the receiver
to trim Ethernet minimum-frame padding that would otherwise corrupt AEAD
verification. Beacon frames (`0x01`) use only the 1-byte type prefix
(fixed 34-byte payload). Beacons and data share the same EtherType and
socket.
| Property | Value |
| -------- | ----- |
| EtherType | 0x2121 |
| Socket type | AF_PACKET SOCK_DGRAM |
| Frame type prefix | 0x00 = data, 0x01 = beacon |
| Effective MTU | Interface MTU - 1 (typically 1499) |
| Data frame header | `[type:1][length:2 LE][payload]` |
| Beacon frame header | `[type:1][payload]` (fixed 34 bytes) |
| Effective MTU | Interface MTU - 3 (typically 1497) |
| Addressing | 6-byte MAC address |
| Platform | Linux only (`CAP_NET_RAW` required) |
@@ -396,7 +400,7 @@ removes it from the pool and aborts its receive task.
```yaml
transports:
tcp:
bind_addr: "0.0.0.0:443" # Listen address (omit for outbound-only)
bind_addr: "0.0.0.0:8443" # Listen address (omit for outbound-only)
mtu: 1400 # Default MTU
connect_timeout_ms: 5000 # Outbound connect timeout
nodelay: true # TCP_NODELAY (disable Nagle)
+8 -5
View File
@@ -23,11 +23,14 @@ transports (TCP, WebSocket, Tor) must delineate FIPS packets within the
byte stream; the common prefix `payload_len` field provides this
framing directly.
**Ethernet frame type prefix.** The Ethernet transport prepends a 1-byte
frame type before the FMP payload: `0x00` for data frames and `0x01` for
beacon (discovery) frames. This byte is consumed by the transport layer
and is not visible to FMP. The effective MTU for FMP is the interface
MTU minus one byte (typically 1499).
**Ethernet data frame header.** The Ethernet transport prepends a 3-byte
header before the FMP payload on data frames: a 1-byte frame type
(`0x00`) followed by a 2-byte little-endian payload length. The length
field allows the receiver to trim Ethernet minimum-frame padding that
would otherwise corrupt AEAD verification. Beacon frames (`0x01`) have
no length field (fixed 34-byte payload). These bytes are consumed by the
transport layer and are not visible to FMP. The effective MTU for FMP is
the interface MTU minus three bytes (typically 1497).
## Link-Layer Formats
+6 -4
View File
@@ -17,16 +17,18 @@ configurations.
| mesh | 5 | UDP | Sparse mesh, 6 links, multi-hop |
| chain | 5 | UDP | Linear chain, max 4-hop paths |
| mesh-public | 5+1 | UDP | Mesh with external public node |
| tcp-chain | 3 | TCP | Linear chain over TCP (port 443) |
| tcp-chain | 3 | TCP | Linear chain over TCP (port 8443) |
| rekey | 5 | UDP | Rekey integration test topology |
### [chaos/](chaos/) -- Stochastic Simulation
Automated network testing with configurable node counts, topology
algorithms (random geometric, Erdos-Renyi, chain, explicit), and fault
injection (netem mutation, link flaps, traffic generation, node
churn). 16 scenarios covering general stress testing, cost-based parent
selection, mixed link technologies (fiber/Bluetooth/WiFi), and
transport-specific validation (UDP, TCP, Ethernet). Scenarios are
churn). 20 scenarios covering general stress testing, cost-based parent
selection, mixed link technologies (fiber/Bluetooth/WiFi),
transport-specific validation (UDP, TCP, Ethernet), and ECN/congestion
testing. Scenarios are
defined in YAML and executed via a Python harness that manages the full
lifecycle: topology generation, Docker orchestration, fault scheduling,
log collection, and analysis.
+1 -1
View File
@@ -96,7 +96,7 @@ Explicit topologies exercising non-UDP transports.
via beacons, not static config. Minimal netem (1-5ms delay).
- **ethernet-mesh**: Mirrors `tcp-mesh` topology but with Ethernet instead of
TCP. UDP edges use static config; Ethernet edges use beacon discovery.
- **tcp-only**: 4-node ring using TCP on port 443. Tests connect-on-send,
- **tcp-only**: 4-node ring using TCP on port 8443. Tests connect-on-send,
FMP framing over TCP, and reconnection. Netem enabled (1-10ms delay, 0-1%
loss).
- **tcp-chain**: 4-node linear chain, all TCP. Tests multi-hop routing over
+11 -4
View File
@@ -90,14 +90,20 @@ appear in the topology file so that Docker nodes can peer with them.
### TCP Chain
Three nodes in a linear chain using TCP transport (port 443) instead of
Three nodes in a linear chain using TCP transport (port 8443) instead of
UDP: A -- B -- C. Each node peers only with its immediate neighbors.
Tests basic TCP transport connectivity and multi-hop routing over TCP.
The topology file sets `default_transport: tcp`, which causes config
generation to use TCP peer addresses (port 443), inject the TCP transport
generation to use TCP peer addresses (port 8443), inject the TCP transport
section, and remove the UDP transport section.
### Rekey
Same sparse mesh as the mesh topology (5 nodes, 6 links). Configs are
post-processed to use aggressive rekey timers (35s) for CI testing. The
`rekey-test.sh` script handles config injection and multi-phase verification.
## Configuration Management
### File Structure
@@ -114,7 +120,8 @@ testing/static/
│ ├── mesh.yaml # Mesh topology definition
│ ├── chain.yaml # Chain topology definition
│ ├── mesh-public.yaml # Mesh + external public node
── tcp-chain.yaml # TCP chain (3 nodes, port 443)
── tcp-chain.yaml # TCP chain (3 nodes, port 8443)
│ └── rekey.yaml # Rekey integration test (5 nodes)
├── generated-configs/ # Auto-generated (gitignored)
│ ├── npubs.env # NPUB_A=..., NPUB_B=..., etc.
│ ├── mesh/
@@ -319,7 +326,7 @@ removing rules first.
- **Capabilities**: `CAP_NET_ADMIN` (for TUN device creation)
- **Devices**: `/dev/net/tun` mapped into each container
- **DNS**: FIPS built-in resolver on `127.0.0.1:53`
- **Transport**: UDP on port 2121 (MTU 1472) or TCP on port 443
- **Transport**: UDP on port 2121 (MTU 1472) or TCP on port 8443
- **TUN**: `fips0` interface, MTU 1280
Each node resolves `<npub>.fips` DNS names to FIPS IPv6 addresses via its