Session 50: Design document reorganization and gossip protocol

- Create fips-gossip-protocol.md with wire formats for TreeAnnounce,
  FilterAnnounce, LookupRequest/LookupResponse
- Refactor fips-routing.md to reference gossip protocol for wire formats
- Update fips-session-protocol.md: remove reconciliation section,
  condense peer connection section
- Update spanning-tree-dynamics.md with gossip protocol reference
- Reorganize README.md with suggested reading order
- Remove obsolete fips-architecture-review.md
This commit is contained in:
Johnathan Corgan
2026-02-01 17:42:17 +00:00
parent 5830f54039
commit 7c2e11c5de
6 changed files with 468 additions and 325 deletions
+58 -15
View File
@@ -2,22 +2,65 @@
Protocol design specifications and analysis for the Federated Interoperable Peering System.
## Protocol Design
## Suggested Reading Order
| Document | Description |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| [fips-design.md](fips-design.md) | Core protocol specification: goals, architecture, identity, addressing, spanning tree |
| [fips-routing.md](fips-routing.md) | Routing architecture: Bloom filters, discovery protocol, session establishment |
| [fips-wire-protocol.md](fips-wire-protocol.md) | Wire protocol: format, session indices, roaming, replay protection, DoS defense |
| [fips-transports.md](fips-transports.md) | Transport protocol characteristics: UDP, Ethernet, Tor, radio, and other link types |
| [spanning-tree-dynamics.md](spanning-tree-dynamics.md) | Detailed study of spanning tree gossip protocol behavior and convergence |
Start with the high-level architecture, then work through session flow, routing
concepts, and finally the wire-level protocol details.
### 1. Architecture and Overview
| Document | Description |
|------------------------------------------|-------------------------------------------------------------|
| [fips-design.md](fips-design.md) | Core protocol: goals, identity, addressing, spanning tree |
### 2. Protocol Flow (How Traffic Works)
| Document | Description |
|------------------------------------------------------|-----------------------------------------------------------|
| [fips-session-protocol.md](fips-session-protocol.md) | End-to-end session flow, Noise KK encryption, terminology |
### 3. Routing (How Packets Find Their Way)
| Document | Description |
|--------------------------------------------------------|-------------------------------------------------------------|
| [fips-routing.md](fips-routing.md) | Routing concepts: bloom filters, discovery, greedy routing |
| [spanning-tree-dynamics.md](spanning-tree-dynamics.md) | Tree protocol behavior: convergence, partitions, recovery |
| [fips-gossip-protocol.md](fips-gossip-protocol.md) | Wire formats: TreeAnnounce, FilterAnnounce, Lookup messages |
### 4. Link Layer (How Peer Connections Work)
| Document | Description |
|------------------------------------------------|---------------------------------------------------------------|
| [fips-wire-protocol.md](fips-wire-protocol.md) | Transport layer: Noise IK, session indices, roaming, security |
| [fips-transports.md](fips-transports.md) | Transport-specific: UDP, Ethernet, Tor, radio characteristics |
## Implementation
| Document | Description |
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| [fips-architecture.md](fips-architecture.md) | Software architecture: entities, state machines, transport abstractions, configuration |
| [fips-architecture-review.md](fips-architecture-review.md) | Architecture review issues and resolution status |
| [fips-tun-driver.md](fips-tun-driver.md) | TUN interface driver: reader/writer threads, ICMPv6, packet flow |
| [fips-state-machines.md](fips-state-machines.md) | Phase-based state machine pattern: peer lifecycle, transitions, timeout handling |
| [fips-session-protocol.md](fips-session-protocol.md) | Session protocol: traffic flow, crypto sessions, terminology |
| Document | Description |
|--------------------------------------------------|------------------------------------------------------------------|
| [fips-architecture.md](fips-architecture.md) | Software architecture: entities, state machines, configuration |
| [fips-tun-driver.md](fips-tun-driver.md) | TUN interface driver: reader/writer threads, ICMPv6, packet flow |
| [fips-state-machines.md](fips-state-machines.md) | Phase-based state machine pattern: peer lifecycle, transitions |
## Document Cross-References
```text
fips-design.md
│
▼
fips-session-protocol.md
│ │
┌─────────┘ └─────────┐
▼ ▼
fips-routing.md fips-wire-protocol.md
│ │
▼ │
spanning-tree-dynamics.md │
│ │
└───────────┬───────────────────┘
▼
fips-gossip-protocol.md
│
▼
fips-transports.md
```
-137
View File
@@ -1,137 +0,0 @@
# FIPS Architecture Document Review
**Document reviewed**: fips-architecture.md
**Last updated**: 2025-01-29
This document tracks open issues and deferred items for the FIPS architecture.
Issues are organized by priority. Resolved items have been archived.
---
## Summary
| # | Issue | Priority | Status | Notes |
| -- | ---------------------- | -------- | -------- | -------------------- |
| 11 | Config validation | Low | OPEN | Add validation rules |
| 12 | Default rationales | Low | OPEN | Document reasoning |
| 14 | Gateway details | Low | OPEN | Incomplete spec |
| 15 | DiscoveredPeer hint | Low | OPEN | Type mismatch |
| 2 | Auth protocol ref | High | DEFERRED | Wire protocol work |
| 3 | Concurrency model | High | DEFERRED | Future iteration |
| 4 | Keepalive format | High | DEFERRED | Wire protocol work |
| 7 | Error handling | Medium | DEFERRED | Future iteration |
| 10 | Init/shutdown | Medium | DEFERRED | Future iteration |
**Resolved (archived):** 1, 5, 6, 8, 9, 13
---
## Open Issues - Low Priority
### 11. Configuration Validation Rules
**Issue**: No validation rules specified:
- What if `filter.size` is not a power of 2?
- What if `peer.keepalive.timeout` < `peer.keepalive.interval`?
- What if `timeout.adaptive.min` > `timeout.adaptive.max`?
**Resolution needed**: Add validation rules or defer to implementation.
---
### 12. Default Value Rationales
**Issue**: Several defaults lack rationale:
- `filter.scope = 2`: Why 2?
- `tree.parent.hold_time = 10s`: Why 10 seconds?
- `filter.stale.threshold = 300s`: Based on what analysis?
**Resolution needed**: Add brief rationale comments or design rationale document.
---
### 14. Gateway/Subnet Routing Details Incomplete
**Issue**: Document mentions `leaf_dependents` but doesn't explain:
- How a node becomes a gateway for a subnet
- How gateway prefixes are advertised in Bloom filters
- Configuration for gateway mode
**Resolution needed**: Expand gateway section or reference future gateway
design document.
---
### 15. DiscoveredPeer Hint Field Mismatch
**Issue**: Transport trait shows `discover() -> Result<Vec<DiscoveredPeer>>` but
event shows `DiscoveredPeer { transport_id, addr, hint: Option<PublicKey> }`.
The discover() return type doesn't show the hint field.
**Resolution needed**: Align trait signature with event structure.
---
## Deferred Items
### Wire Protocol (Future Work)
These items will be addressed when the wire protocol section is developed:
| # | Issue | Description |
| --- | ----------------------- | ----------------------------------------------------------------------------------------- |
| 2 | Auth protocol reference | Architecture references "FIPS auth handshake" but doesn't define or reference fips-design |
| 4 | Keepalive format | `peer.keepalive.interval` configured but no message type defined; RTT measurement unclear |
### Future Architecture Iterations
These items are deferred to future design iterations:
| # | Issue | Description |
| --- | ----------------- | -------------------------------------------------------------------------------------------- |
| 3 | Concurrency model | No specification for threading model, state machine driving, or transport isolation |
| 7 | Error handling | No systematic error handling definitions for signature failures, malformed packets, or codes |
| 10 | Init/shutdown | Startup sequence, transport ordering, shutdown procedure, departure announcement |
---
## Edge Cases for Future Consideration
### Network Dynamics
- **Root node failure**: Election timing, in-flight session impact, proactive backup
- **Rapid peer churn**: 500ms debounce may cause filter oscillation
- **Network partition healing**: Session conflicts, stale cache recovery
### Transport Edge Cases
- **Startup timing**: Tor takes 30s-2min while UDP is instant; node status during window
- **MTU mismatch**: Path includes links with different MTUs (Ethernet 1500 vs LoRa 222)
- **Clock skew**: TreeAnnounce timestamps; 5-minute tolerance from fips-design.md
### Security Considerations
- **Memory exhaustion**: Many fake peers
- **CPU exhaustion**: Signature verification flooding
- **Bandwidth exhaustion**: Bloom filter spam
### Configuration Edge Cases
- **Conflicting peers**: Same npub with different addresses; discovered vs configured conflict
- **TUN unavailable**: Permissions, kernel module; relay-only mode possibility
---
## Resolved Items (Archived)
| # | Issue | Resolution |
| --- | ------------------- | -------------------------------------------------------------------------------------- |
| 1 | Coordinate ordering | Standardized on `[self, parent, ..., root]` (node→root) in all documents |
| 5 | Cache naming | Removed misplaced `coord_cache` from TreeState; clarified config sections |
| 6 | Peer/Link lifecycle | Clarified: transports static, links on-demand driven by peer lifecycle |
| 8 | Memory bounds | Added Resource Limits config: max_peers, max_transports, pending limits, memory budget |
| 9 | Timer management | Non-issue: async runtimes (tokio) handle hundreds of timers efficiently at this scale |
| 13 | Terminology | Standardized Transport/Link terminology in fips-design.md and fips-transports.md |
+376
View File
@@ -0,0 +1,376 @@
# FIPS Gossip Protocol
This document specifies the wire formats and exchange rules for FIPS gossip
messages: TreeAnnounce, FilterAnnounce, and the discovery protocol
(LookupRequest/LookupResponse).
For conceptual background on how these protocols work:
- Spanning tree dynamics: [spanning-tree-dynamics.md](spanning-tree-dynamics.md)
- Routing design and bloom filter concepts: [fips-routing.md](fips-routing.md)
---
## 1. Message Type Summary
All gossip messages are link-layer messages, encrypted with per-peer Noise IK
session keys. They travel one hop (peer-to-peer), though their effects may
propagate further through subsequent gossip.
| Type | Purpose | Direction | Trigger |
|------|---------|-----------|---------|
| TreeAnnounce | Spanning tree state | Bidirectional | Peer connect, parent change, periodic |
| FilterAnnounce | Bloom filter reachability | Bidirectional | Peer connect, filter change |
| LookupRequest | Coordinate discovery | Flooded | Route cache miss |
| LookupResponse | Return coordinates | Routed back | LookupRequest reaches target |
---
## 2. TreeAnnounce
TreeAnnounce messages propagate spanning tree state between peers. Each node
announces its parent selection and ancestry, enabling peers to compute tree
coordinates and distances.
### 2.1 Wire Format
```text
TreeAnnounce {
sequence: u64, // Monotonic, increments on parent change
timestamp: u64, // Unix timestamp (seconds)
parent: NodeId, // 32 bytes, SHA-256(npub) of selected parent
ancestry: Vec<AncestryEntry>, // Path from self to root
signature: Signature, // 64 bytes, signs (sequence || timestamp || parent || ancestry)
}
AncestryEntry {
node_id: NodeId, // 32 bytes
sequence: u64, // That node's sequence number
timestamp: u64, // That node's timestamp
signature: Signature, // That node's signature over its declaration
}
```
### 2.2 Field Semantics
**sequence**: Incremented each time the node changes its parent declaration.
Higher sequence numbers supersede lower ones for conflict resolution.
**timestamp**: Used for distributed consistency. A declaration is considered
stale if `now - timestamp > ROOT_TIMEOUT` (default 60 minutes for root).
**parent**: The node_id of the selected parent. If `parent == self.node_id`,
the node is declaring itself as root.
**ancestry**: The chain from this node up to the root. The first entry is this
node's own declaration, followed by parent, grandparent, etc. Each entry is
signed by the declaring node, allowing verification of the entire chain.
### 2.3 Size Estimate
| Component | Size |
|-----------|------|
| sequence | 8 bytes |
| timestamp | 8 bytes |
| parent | 32 bytes |
| signature | 64 bytes |
| Per ancestry entry | 32 + 8 + 8 + 64 = 112 bytes |
For tree depth D: `112 + D * 112` bytes. At depth 10: ~1.2 KB.
### 2.4 Exchange Rules
**On peer connection:**
1. After Noise IK handshake completes, both peers send TreeAnnounce
2. Each peer processes the received announcement (see §2.5)
3. If processing triggers a parent change, send updated TreeAnnounce to all peers
**On parent change:**
1. Increment sequence number
2. Update timestamp
3. Sign new declaration
4. Send TreeAnnounce to all peers
**Periodic refresh:**
1. Root refreshes every 30 minutes (prevents stale root detection)
2. Non-root nodes forward root refresh when received
3. Nodes may refresh their own declaration periodically (implementation choice)
### 2.5 Processing Rules
When receiving TreeAnnounce from peer P:
```text
1. Verify signature on sender's declaration
2. Verify signatures on all ancestry entries
3. For each entry in ancestry:
- If entry.sequence > stored.sequence: update stored entry
- If entry.sequence == stored.sequence && entry.timestamp > stored.timestamp: update
- Otherwise: keep existing entry
4. Update peer P's record with new ancestry
5. Re-evaluate parent selection:
- If better path to root available: change parent, announce to all peers
- Apply stability threshold to prevent flapping
```
### 2.6 Rate Limiting
To prevent announcement storms during reconvergence:
- Minimum interval between announcements to same peer: 500ms
- If change occurs during cooldown: mark pending, send after cooldown
- Coalesce multiple pending changes into single announcement
---
## 3. FilterAnnounce
FilterAnnounce messages propagate Bloom filter reachability information. Each
node's filter indicates which destinations are reachable through it.
### 3.1 Wire Format
```text
FilterAnnounce {
filter: BloomFilter, // 4096 bytes (32,768 bits)
ttl: u8, // Remaining propagation hops
sequence: u64, // For freshness/deduplication
}
BloomFilter {
bits: [u8; 4096], // Bit array
hash_count: u8, // Number of hash functions (typically 7)
}
```
### 3.2 Field Semantics
**filter**: Contains node_ids reachable through this peer. Uses k=7 hash
functions for near-optimal false positive rate at expected fill levels.
**ttl**: Remaining propagation depth. Starts at K (typically 2), decremented
each hop. At TTL=0, entries are not propagated further.
**sequence**: Monotonic counter for this node's filter. Allows receivers to
detect stale or duplicate announcements.
### 3.3 Filter Contents
A node's outgoing filter to peer Q contains:
1. This node's own node_id
2. Node_ids of leaf-only dependents (nodes using this node as sole peer)
3. Entries from filters received from other peers (not Q) with TTL > 0
This creates K-hop reachability scope. With K=2, entries propagate ~4 hops
before TTL exhaustion.
### 3.4 Exchange Rules
**On peer connection:**
1. After TreeAnnounce exchange, send FilterAnnounce
2. Filter contains current reachability view
**On filter change:**
Triggering events:
- Peer connects or disconnects
- Received filter changes outgoing filter
- Local state change (new leaf dependent, become gateway)
Rate limiting:
- Minimum interval between filter announcements: 500ms
- Debounce rapid changes into single announcement
**Processing received filter:**
```text
1. Store: peer_filters[P] = received.filter
2. If received.ttl > 0:
- Include entries in next announcement to other peers
- Decrement TTL for propagated entries
3. Recompute own outgoing filters if changed
```
### 3.5 Filter Expiration
Bloom filters cannot remove individual entries. Expiration handled by:
- **Peer disconnect**: Remove that peer's filter entirely, recompute
- **Filter replacement**: Each FilterAnnounce replaces the previous one
- **Implicit timeout**: If no updates from peer within threshold, consider stale
---
## 4. LookupRequest
LookupRequest initiates coordinate discovery for destinations not covered by
local Bloom filters.
### 4.1 Wire Format
```text
LookupRequest {
request_id: u64, // Unique identifier for this request
target: NodeId, // 32 bytes, who we're looking for
origin: NodeId, // 32 bytes, who's asking
origin_coords: Vec<NodeId>, // Origin's ancestry (for return path)
ttl: u8, // Remaining propagation hops
visited: CompactBloomFilter,// ~256 bytes, prevents loops
}
CompactBloomFilter {
bits: [u8; 256], // Smaller filter for visited set
hash_count: u8,
}
```
### 4.2 Field Semantics
**request_id**: Randomly generated, used to match responses and detect
duplicates.
**target**: The node_id being searched for.
**origin**: The node_id of the original requester. Used for response routing.
**origin_coords**: The requester's current tree coordinates. Enables greedy
routing of the response back to origin.
**ttl**: Propagation limit. Prevents unbounded flooding.
**visited**: Compact Bloom filter tracking nodes that have seen this request.
Prevents redundant processing and loops.
### 4.3 Propagation Rules
When receiving LookupRequest:
```text
1. Check visited filter - if self likely present, drop (already processed)
2. Add self to visited filter
3. Decrement TTL
4. Check if target is local:
- If target == self.node_id: generate LookupResponse
- If target in local peer_filters: may respond on behalf (optional)
5. If TTL > 0 and not found locally:
- Forward to peers not in visited filter
- Optionally prioritize peers whose filter indicates target "maybe" present
```
### 4.4 Rate Limiting
- Track recently seen request_ids, drop duplicates
- Limit requests per origin per time window
- Limit total outstanding requests
---
## 5. LookupResponse
LookupResponse returns the target's coordinates to the requester.
### 5.1 Wire Format
```text
LookupResponse {
request_id: u64, // Echoes LookupRequest.request_id
target: NodeId, // 32 bytes, confirms who was found
target_coords: Vec<NodeId>, // Target's ancestry (the key payload)
proof: Signature, // 64 bytes, target signs to prove existence
}
```
### 5.2 Field Semantics
**request_id**: Matches the original request, allowing requester to correlate.
**target**: Confirms the identity found.
**target_coords**: The target's current tree coordinates. This is the primary
payload - enables greedy routing to the target.
**proof**: Target's signature over `(request_id || target || target_coords)`.
Prevents malicious nodes from claiming reachability and blackholing traffic.
### 5.3 Routing
LookupResponse uses greedy tree routing based on `origin_coords` from the
request:
```text
1. Response created at target (or node with target in filter)
2. Each hop forwards toward origin using tree distance
3. Origin receives response, caches target_coords
```
### 5.4 Security
The proof signature is critical:
- Without it, any node could claim to be (or know) any target
- Requester verifies signature against target's known public key
- Invalid signatures cause response to be dropped
---
## 6. Message Type Codes
Within the link-layer message framing:
| Type Code | Message |
|-----------|---------|
| 0x10 | TreeAnnounce |
| 0x11 | FilterAnnounce |
| 0x12 | LookupRequest |
| 0x13 | LookupResponse |
These are carried inside the encrypted link-layer payload after Noise IK
handshake completion.
---
## 7. Timing Parameters
| Parameter | Default | Notes |
|-----------|---------|-------|
| ROOT_REFRESH_INTERVAL | 30 min | Root regenerates timestamp |
| ROOT_TIMEOUT | 60 min | Root declaration considered stale |
| TREE_ENTRY_TTL | 5-10 min | Individual entry expiration |
| FILTER_TTL_HOPS | 2 | Bloom filter propagation depth |
| ANNOUNCE_MIN_INTERVAL | 500 ms | Rate limit for announcements |
| LOOKUP_TTL | 8 | Discovery request propagation limit |
| LOOKUP_TIMEOUT | 5 sec | Time to wait for response |
---
## 8. Encoding
All multi-byte integers are little-endian. NodeId is 32 bytes (SHA-256 hash).
Signatures are 64 bytes (secp256k1 Schnorr).
Variable-length fields (ancestry, coordinates) are prefixed with a 2-byte
length count indicating number of entries.
```text
Vec<T> encoding:
count: u16 (little-endian)
items: T[count]
```
---
## References
- [spanning-tree-dynamics.md](spanning-tree-dynamics.md) - Tree protocol behavior
- [fips-routing.md](fips-routing.md) - Routing concepts and algorithms
- [fips-wire-protocol.md](fips-wire-protocol.md) - Link-layer framing
- [fips-session-protocol.md](fips-session-protocol.md) - End-to-end sessions
+22 -70
View File
@@ -1,10 +1,11 @@
# FIPS Routing Design
**Status**: Work in Progress
This document describes the routing architecture for FIPS, including Bloom
filter reachability, discovery protocol, greedy tree routing, and session
establishment.
filter reachability, discovery protocol, greedy tree routing, and routing
session establishment.
For wire formats and exchange rules, see [fips-gossip-protocol.md](fips-gossip-protocol.md).
For spanning tree dynamics and convergence, see [spanning-tree-dynamics.md](spanning-tree-dynamics.md).
## Overview
@@ -107,45 +108,19 @@ Filters are updated on events rather than periodic refresh:
3. Received filter changes outgoing filter — recompute, send updates
4. Local state change — new leaf dependent, become gateway, etc.
**Rate limiting:**
Updates are rate-limited to prevent storms during reconvergence. See
[fips-gossip-protocol.md](fips-gossip-protocol.md) §3 for FilterAnnounce wire
format and exchange rules.
To prevent update storms, rate-limit or debounce updates:
### Filter Contents
```rust
const MIN_UPDATE_INTERVAL: Duration = Duration::from_millis(500);
A node's outgoing filter to peer Q contains:
fn maybe_send_update(&mut self, peer: PeerId) {
if self.last_send_time[peer].elapsed() < MIN_UPDATE_INTERVAL {
self.pending_update[peer] = true;
return;
}
// ... send update
}
```
1. This node's own Node ID
2. Node IDs of leaf-only dependents
3. Entries from filters received from other peers (not Q) with TTL > 0
### Filter Announcement Message
```rust
struct FilterAnnounce {
filter: BloomFilter, // 4 KB
ttl: u8, // Remaining propagation hops
sequence: u64, // Freshness / deduplication
}
```
### Propagation Rules
When node N sends a FilterAnnounce to peer Q:
1. Include N's own Node ID
2. Include N's leaf-only dependents
3. Include entries from filters received from other peers (not Q) with TTL > 0
When node N receives FilterAnnounce from peer P:
1. Store: `peer_filters[P] = received.filter`
2. If `received.ttl > 0`: include P's filter contents in N's next announcement
to other peers, with TTL decremented
This creates K-hop reachability scope through TTL-based propagation.
### K-Hop Scope Emergence
@@ -179,25 +154,7 @@ Bloom filters.
- Route cache miss
- After cached route failure
### Message Formats
```rust
struct LookupRequest {
request_id: u64,
target: NodeId, // Who we're looking for
origin: NodeId, // Who's asking
origin_coords: Vec<NodeId>, // Origin's ancestry (for return path)
ttl: u8, // Propagation limit
visited: BloomFilter, // Prevent loops (compact, ~256 bytes)
}
struct LookupResponse {
request_id: u64,
target: NodeId,
target_coords: Vec<NodeId>, // Target's ancestry — the key payload
proof: Signature, // Target signs to prove existence
}
```
For wire formats, see [fips-gossip-protocol.md](fips-gossip-protocol.md) §4-5.
### Discovery Flow
@@ -234,17 +191,10 @@ Each router forwards toward the origin using tree distance.
### Security
**Target signs response:**
```rust
struct LookupResponse {
// ...
proof: Signature, // Sign(request_id || target || target_coords)
}
```
Without this, a malicious node could claim reachability for any target and
blackhole traffic. The signature proves the target authorized the route.
The target signs the LookupResponse with a proof covering
`(request_id || target || target_coords)`. Without this signature, a malicious
node could claim reachability for any target and blackhole traffic. The
signature proves the target authorized the route.
### Caching
@@ -621,6 +571,8 @@ When nodes join/leave:
## References
- [fips-design.md](fips-design.md) — Overall FIPS architecture
- [fips-gossip-protocol.md](fips-gossip-protocol.md) — Wire formats for TreeAnnounce, FilterAnnounce, Lookup
- [fips-session-protocol.md](fips-session-protocol.md) — Traffic flow, crypto sessions, terminology
- [fips-wire-protocol.md](fips-wire-protocol.md) — Link-layer transport and Noise IK handshake
- [fips-transports.md](fips-transports.md) — Transport protocol characteristics
- [spanning-tree-dynamics.md](spanning-tree-dynamics.md) — Tree protocol details
- [spanning-tree-dynamics.md](spanning-tree-dynamics.md) — Tree protocol dynamics and convergence
+9 -102
View File
@@ -456,116 +456,23 @@ Per-packet signatures would add:
Since Noise already provides authentication through key binding, signatures
are redundant. This matches WireGuard and Lightning's approach.
**Reconciliation note**: §3.1 mentions packets being "signed by source" -
this should be updated to reflect AEAD-only authentication.
---
## 7. Peer Connection Establishment
Before any of the traffic flows described above can occur, nodes must establish
authenticated peer connections using Noise IK. See [fips-design.md](fips-design.md)
§1 for full protocol details and [fips-architecture.md](fips-architecture.md)
for the startup sequence.
Before any session-layer traffic can flow, nodes must establish authenticated
link-layer connections with their peers using Noise IK. See
[fips-wire-protocol.md](fips-wire-protocol.md) for the complete wire protocol
specification including handshake flow, session lifecycle, index management,
roaming support, and transport-specific considerations.
### 7.1 Connection Flow Summary (Noise IK)
All messages use TLV framing (see fips-design.md §6 Wire Format):
```text
┌────────┬────────┬────────────────────────────────────┐
│ Type │ Length │ Payload │
│ 1 byte │ 2 bytes│ Variable │
└────────┴────────┴────────────────────────────────────┘
```
**Outbound (to static peer):**
```text
Config: npub + transport hint (e.g., "udp:192.168.1.1:4000")
│
▼
Create link via transport
│
▼
Send: [0x01][0x00 0x52][82-byte Noise msg1]
Type=NoiseIKMsg1, Length=82
│
▼
Recv: [0x02][0x00 0x21][33-byte Noise msg2]
Type=NoiseIKMsg2, Length=33
│
▼
Noise session established → link encrypted → begins tree gossip
```
**Inbound (peer connects to us):**
```text
Transport receives packet from unknown address
│
▼
Parse TLV: Type=0x01 (NoiseIKMsg1)
│
▼
Process msg1 → learn peer's identity from encrypted static key
│
▼
Send: [0x02][0x00 0x21][33-byte Noise msg2]
│
▼
Noise session established → link encrypted → begins tree gossip
```
### 7.2 Post-Authentication
After successful Noise handshake:
After successful Noise IK handshake:
1. **Link encrypted**: All subsequent messages use AEAD encryption
2. **TreeAnnounce exchange**: Both peers send their current tree state
2. **TreeAnnounce exchange**: Both peers send their current spanning tree state
3. **FilterAnnounce exchange**: Both peers send their bloom filters
4. **Peer is Active**: Can now participate in routing and forwarding
The first TreeAnnounce from a new peer may trigger parent reselection if that
peer offers a better path to root.
---
## 8. Document Reconciliation
This section tracks items that need reconciliation with existing design docs
or earlier sections of this document.
### 8.1 Completed Updates (Session 47)
| Location | Status | Notes |
|----------------------------------|--------|----------------------------------------------------|
| fips-design.md §1 Peer Auth | ✓ Done | Replaced custom handshake with Noise IK |
| fips-design.md §6 Messages | ✓ Done | Split into LinkMessageType + SessionMessageType |
| protocol.rs | ✓ Done | Removed Hello/Challenge/Auth/AuthAck types |
| protocol.rs | ✓ Done | Added SessionDatagram for link-layer encapsulation |
| This document §6 | ✓ Done | Updated to two-layer Noise IK architecture |
| This document §7 | ✓ Done | Updated connection flow for Noise IK |
### 8.2 Previous Updates (Session 40)
| Location | Status | Notes |
|----------------------------------|--------|-----------------------------------------------------|
| §3.1 | ✓ Done | Updated to AEAD authentication |
| fips-routing.md Part 4 | ✓ Done | Renamed to "Routing Session Establishment" |
| fips-routing.md SessionSetup/Ack | ✓ Done | Added `handshake_payload` for crypto handshake |
| fips-design.md §7 Encryption | ✓ Done | Updated to reference Noise instead of NIP-44 |
| fips-architecture.md Config | ✓ Done | Renamed to "Routing Session", added "Crypto Session"|
### 8.3 Design Doc Alignment Summary
The following decisions from this document have been propagated:
1. **Two-layer architecture**: Link layer (Noise IK peer auth) and session layer
(Noise KK end-to-end) operate independently with separate keys
2. **Session terminology** (§5.4): "Routing Session" vs "Crypto Session" distinction
now consistent across all docs
3. **Combined establishment** (§5.5): SessionSetup/SessionAck carry optional
`handshake_payload` for session-layer Noise KK handshake
4. **Message type split**: LinkMessageType for hop-by-hop, SessionMessageType for
end-to-end (carried inside SessionDatagram)
peer offers a better path to root. See [fips-gossip-protocol.md](fips-gossip-protocol.md)
for TreeAnnounce and FilterAnnounce wire formats.
+3 -1
View File
@@ -2,9 +2,11 @@
A detailed study of the gossip-based spanning tree protocol, focusing on
operational behavior under various mesh conditions. This document complements
[FIPS-DESIGN.md](FIPS-DESIGN.md) with step-by-step walkthroughs of protocol
[fips-design.md](fips-design.md) with step-by-step walkthroughs of protocol
dynamics rather than message formats and data structures.
For wire formats, see [fips-gossip-protocol.md](fips-gossip-protocol.md) §2 (TreeAnnounce).
The protocol is based on Yggdrasil v0.5's CRDT gossip design.
## Contents