Fix FIPS_OVERHEAD constant and add CP flag MTU guard

FIPS_OVERHEAD was 150 but had two bugs: the session AEAD tag (16 bytes)
was listed in the comment but missing from the arithmetic, and the
coordinate budget (~60 bytes) was undersized and didn't belong in a
constant representing fixed data path overhead.

Corrected to 106 bytes (the actual fixed overhead without coordinates).
This increases effective_ipv6_mtu from 1322 to 1366 for standard
Ethernet, well above the IPv6 minimum of 1280.

Added a guard in send_session_data() that computes the total wire size
with coordinates before committing to include them. If adding coords
would exceed the transport MTU, the CP flag is skipped and the warmup
counter is not decremented. This prevents silently producing oversized
packets at tree depth 2+.

Updated design docs (ipv6-adapter, wire-formats, mesh-operation) with
corrected overhead values.
This commit is contained in:
Johnathan Corgan
2026-02-19 14:18:34 +00:00
parent 7df1f21429
commit 999144f59a
7 changed files with 100 additions and 47 deletions
+12 -10
View File
@@ -119,17 +119,19 @@ after all layers of wrapping.
| Layer | Overhead | Purpose |
| ----- | -------- | ------- |
| Link encryption | 37 bytes | 16-byte outer header + 5-byte inner header + 16-byte AEAD tag |
| SessionDatagram envelope | 36 bytes | type + ttl + path_mtu + src_addr + dest_addr |
| Link encryption | 37 bytes | 16-byte outer header + 5-byte inner header (timestamp + msg_type) + 16-byte AEAD tag |
| SessionDatagram body | 35 bytes | ttl + path_mtu + src_addr + dest_addr (msg_type counted in inner header) |
| FSP header | 12 bytes | 4-byte prefix + 8-byte counter (used as AEAD AAD) |
| FSP inner header | 6 bytes | 4-byte timestamp + 1-byte msg_type + 1-byte inner_flags (inside AEAD) |
| Session AEAD tag | 16 bytes | ChaCha20-Poly1305 tag on session-encrypted payload |
| **Minimal total** | **107 bytes** | |
| Coordinates (if present) | ~43 bytes | Depth-dependent, first few packets only |
| **Worst case total** | **150 bytes** | With CP flag set for depth-3 paths |
| **Data path total** | **106 bytes** | `FIPS_OVERHEAD` constant |
The `FIPS_OVERHEAD` constant (150 bytes) is used for conservative MTU
calculations.
Coordinate piggybacking (CP flag) adds variable overhead: `2 + entries × 16`
per coordinate, with both src and dst coords sent. The send path skips the
CP flag if adding coords would exceed the transport MTU.
The `FIPS_OVERHEAD` constant (106 bytes) represents the fixed data path
overhead and is used for MTU calculations.
### Effective IPv6 MTU
@@ -143,14 +145,14 @@ For typical deployments:
| Transport MTU | Effective IPv6 MTU | Notes |
| ------------- | ------------------ | ----- |
| 1472 (UDP/Ethernet) | 1322 | Standard deployment |
| 1280 (UDP minimum) | 1130 | Below IPv6 minimum |
| 1472 (UDP/Ethernet) | 1366 | Standard deployment |
| 1280 (UDP minimum) | 1174 | Below IPv6 minimum |
IPv6 mandates that every link support at least 1280 bytes. The minimum
transport path MTU for the IPv6 adapter is therefore:
```text
1280 + 150 = 1430 bytes
1280 + 106 = 1386 bytes
```
Transports with smaller MTUs (LoRa at ~250 bytes, serial at 256 bytes) cannot
+2 -2
View File
@@ -515,8 +515,8 @@ routing decisions but retains its own end-to-end encryption and identity.
| LookupResponse | ~400 bytes | Response to discovery | Yes (greedy routed) |
| SessionDatagram + SessionSetup | ~232402 bytes | Session establishment | Yes (routed) |
| SessionDatagram + SessionAck | ~122 bytes | Session confirmation | Yes (routed) |
| SessionDatagram + Data (minimal) | ~107 bytes + payload | Bulk traffic | Yes (routed) |
| SessionDatagram + Data (with CP) | ~150 bytes + payload | Warmup/recovery | Yes (routed) |
| SessionDatagram + Data (minimal) | 106 bytes + payload | Bulk traffic | Yes (routed) |
| SessionDatagram + Data (with CP) | 106 + coords + payload | Warmup/recovery | Yes (routed) |
| SessionDatagram + CoordsRequired | 70 bytes | Cache miss error | Yes (routed) |
| SessionDatagram + PathBroken | 70+ bytes | Dead-end error | Yes (routed) |
| Disconnect | 2 bytes | Link teardown | No (peer-to-peer) |
+5 -7
View File
@@ -648,14 +648,12 @@ Layer 0: Transport
| Layer | Overhead | Component |
| ----- | -------- | --------- |
| Link encryption | 37 bytes | 16 outer header (AAD) + 5 inner header + 16 AEAD tag |
| SessionDatagram | 36 bytes | 1 type + 1 ttl + 2 path_mtu + 16 src + 16 dest |
| Link encryption | 37 bytes | 16 outer header (AAD) + 5 inner header (timestamp + msg_type) + 16 AEAD tag |
| SessionDatagram body | 35 bytes | 1 ttl + 2 path_mtu + 16 src + 16 dest (msg_type counted in inner header) |
| FSP header | 12 bytes | 4 prefix + 8 counter |
| FSP inner header | 6 bytes | 4 timestamp + 1 msg_type + 1 inner_flags (inside AEAD) |
| Session AEAD tag | 16 bytes | Poly1305 tag on session-encrypted payload |
| **Minimal total** | **107 bytes** | |
| Coordinates (if present) | ~43 bytes | Varies with tree depth |
| **Worst case** | **150 bytes** | `FIPS_OVERHEAD` constant |
| **Data path total** | **106 bytes** | `FIPS_OVERHEAD` constant |
### At Each Transit Node
@@ -717,8 +715,8 @@ endpoint session keys).
| Scenario | Wire Size | Notes |
| -------- | --------- | ----- |
| Encrypted frame minimum | 37 bytes | Empty body |
| SessionDatagram + Data (minimal) | 37 + 36 + 12 + 6 + payload + 16 | 107 + payload |
| SessionDatagram + Data (with coords) | ~150 + payload | Worst case |
| SessionDatagram + Data (minimal) | 37 + 35 + 12 + 6 + payload + 16 | 106 + payload |
| SessionDatagram + Data (with coords) | 106 + coords + payload | Coords vary with tree depth |
| SessionDatagram + SessionSetup | ~275 bytes | Depth-3, both dirs |
| SessionDatagram + CoordsRequired | 37 + 36 + 38 = 111 bytes | Including link overhead |