mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Resolve architecture review items and reconcile terminology
- Standardize coordinate ordering to [self, parent, ..., root] across all docs - Fix 8 coordinate ordering instances in spanning-tree-dynamics.md - Clarify cache naming: discovery.cache and session.cache configure Node.coord_cache - Reconcile Transport vs Link terminology: - Transport = interface/medium (UDP socket, Ethernet NIC) - Link = connection instance to a specific peer - Update fips-design.md: replace FipsLink trait with architecture reference - Rename fips-links.md to "Transport Protocols", add terminology section - Update review doc: mark items 1, 5, 13 RESOLVED; items 2-4, 7 DEFERRED
This commit is contained in:
@@ -20,7 +20,10 @@ sometimes uses `[root, ..., self]` ordering.
|
||||
|
||||
**Resolution needed**: Standardize on one ordering across all documents.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: RESOLVED
|
||||
|
||||
**Resolution**: Standardized on `[self, parent, ..., root]` (node→root) ordering.
|
||||
Updated all coordinate/ancestry references in spanning-tree-dynamics.md.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,13 +37,17 @@ reference where it's defined.
|
||||
**Resolution needed**: Add reference to fips-design.md lines 115-205, or include
|
||||
summary in architecture document.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: DEFERRED (wire protocol)
|
||||
|
||||
**Note**: Will be addressed when wire protocol section is developed. Not a blocker
|
||||
for current architecture iteration.
|
||||
|
||||
---
|
||||
|
||||
### 3. Concurrency Model Unspecified
|
||||
|
||||
**Issue**: Document doesn't specify whether implementation should be:
|
||||
|
||||
- Single-threaded async
|
||||
- Multi-threaded with message passing
|
||||
- How state machines are driven (polling, callbacks, async/await)
|
||||
@@ -51,7 +58,10 @@ summary in architecture document.
|
||||
**Resolution needed**: Add "Concurrency Model" section specifying the expected
|
||||
runtime architecture.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: DEFERRED (future iteration)
|
||||
|
||||
**Note**: Architecture document is a work-in-progress. Concurrency model section
|
||||
will be added in a future design iteration.
|
||||
|
||||
---
|
||||
|
||||
@@ -65,13 +75,16 @@ is defined for keepalives. RTT measurement mechanism is unclear.
|
||||
**Resolution needed**: Clarify whether Dummy (0x00) message from fips-design.md
|
||||
is used, and how RTT is measured (request/response probing or passive observation).
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: DEFERRED (wire protocol)
|
||||
|
||||
**Note**: Will be addressed when wire protocol section is developed.
|
||||
|
||||
---
|
||||
|
||||
### 5. Cache Naming Confusion
|
||||
|
||||
**Issue**: Multiple cache references that may or may not be the same thing:
|
||||
|
||||
- `coord_cache: CoordCache` on Node (line 35)
|
||||
- `coord_cache: HashMap<Ipv6Addr, CachedCoords>` on TreeState (line 167)
|
||||
- `discovery.cache.max_entries` configuration (line 745)
|
||||
@@ -80,7 +93,12 @@ is used, and how RTT is measured (request/response probing or passive observatio
|
||||
**Resolution needed**: Clarify whether these are the same cache or different caches.
|
||||
If different, explain the distinction.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: RESOLVED
|
||||
|
||||
**Resolution**: Removed misplaced `coord_cache` from TreeState (it belongs only on
|
||||
Node). Added clarifying text in config section explaining that `discovery.cache`
|
||||
and `session.cache` configure the same underlying `Node.coord_cache` but are grouped
|
||||
by purpose (endpoint discovery vs transit routing).
|
||||
|
||||
---
|
||||
|
||||
@@ -93,6 +111,7 @@ but Links can exist before authentication completes, meaning Links exist without
|
||||
Peers temporarily.
|
||||
|
||||
**Resolution needed**: Clarify the relationship lifecycle:
|
||||
|
||||
- Link created on connection (before auth)
|
||||
- Peer created on successful auth
|
||||
- Peer always references exactly one Link
|
||||
@@ -105,6 +124,7 @@ Peers temporarily.
|
||||
### 7. Error Handling Strategy Absent
|
||||
|
||||
**Issue**: No systematic error handling definitions:
|
||||
|
||||
- Signature verification failure handling
|
||||
- Malformed packet handling
|
||||
- Error codes and response formats
|
||||
@@ -112,13 +132,16 @@ Peers temporarily.
|
||||
|
||||
**Resolution needed**: Add "Error Handling" section or reference to protocol spec.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: DEFERRED (future iteration)
|
||||
|
||||
**Note**: Error handling section will be added in a future design iteration.
|
||||
|
||||
---
|
||||
|
||||
### 8. Memory Bounds Missing
|
||||
|
||||
**Issue**: Configuration specifies cache sizes but no limits for:
|
||||
|
||||
- Maximum peers
|
||||
- Maximum transports
|
||||
- Maximum pending operations/queues
|
||||
@@ -146,12 +169,14 @@ be needed for efficient implementation at scale.
|
||||
### 10. Initialization/Shutdown Sequences
|
||||
|
||||
**Issue**: No startup sequence defined:
|
||||
|
||||
- Transport start order
|
||||
- TUN interface initialization relative to peering
|
||||
- Behavior when configured peers are unreachable
|
||||
- When node is "ready" to route
|
||||
|
||||
No shutdown procedure defined:
|
||||
|
||||
- Should nodes announce departure?
|
||||
- Session termination
|
||||
- TUN interface cleanup
|
||||
@@ -167,6 +192,7 @@ No shutdown procedure defined:
|
||||
### 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`?
|
||||
@@ -178,6 +204,7 @@ No shutdown procedure defined:
|
||||
### 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?
|
||||
@@ -189,19 +216,29 @@ No shutdown procedure defined:
|
||||
### 13. Terminology Inconsistency Across Documents
|
||||
|
||||
**Issue**: "Link" and "Transport" meanings differ between documents:
|
||||
|
||||
- fips-links.md uses "link" to mean underlying transport protocol
|
||||
- fips-architecture.md uses "Link" to mean connection over Transport
|
||||
- fips-design.md has `FipsLink` trait which is really a transport interface
|
||||
|
||||
**Resolution needed**: Standardize terminology or add glossary.
|
||||
|
||||
**Status**: OPEN
|
||||
**Status**: RESOLVED
|
||||
|
||||
**Resolution**: Updated fips-design.md and fips-links.md to use consistent terminology:
|
||||
|
||||
- Transport = interface/medium (UDP socket, Ethernet NIC, Tor client)
|
||||
- Link = connection instance to a specific peer over a transport
|
||||
- Renamed `trait FipsLink` section to reference architecture doc
|
||||
- Renamed `trait LinkDriver` section to reference architecture doc
|
||||
- Updated section headers and examples throughout both documents
|
||||
|
||||
---
|
||||
|
||||
### 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
|
||||
@@ -225,40 +262,49 @@ The discover() return type doesn't show the hint field.
|
||||
## Edge Cases Not Addressed
|
||||
|
||||
### Root Node Failure
|
||||
|
||||
- How long until new root is elected?
|
||||
- How are in-flight sessions affected?
|
||||
- Any proactive root backup mechanism?
|
||||
|
||||
### Rapid Peer Churn
|
||||
|
||||
- Debounce (500ms) may not be sufficient
|
||||
- Could lead to Bloom filter oscillation or announcement storms
|
||||
|
||||
### Network Partition Healing
|
||||
|
||||
- What happens to sessions that existed in both partitions?
|
||||
- How do routers with stale cache entries recover?
|
||||
|
||||
### Transport Startup Timing
|
||||
|
||||
- If Tor takes 180s but UDP is instant, what's node status during window?
|
||||
- Are Tor-only peers unreachable during Tor bootstrap?
|
||||
|
||||
### MTU Mismatch Across Path
|
||||
|
||||
- Path includes links with different MTUs (Ethernet 1500 vs LoRa 222)
|
||||
- No path MTU discovery or fragmentation strategy defined
|
||||
|
||||
### Clock Skew
|
||||
|
||||
- TreeAnnounce timestamps with significant clock skew
|
||||
- 5-minute tolerance in auth (fips-design.md) should be reflected here
|
||||
|
||||
### Resource Exhaustion Attacks
|
||||
|
||||
- Memory exhaustion via many fake peers
|
||||
- CPU exhaustion via signature verification flooding
|
||||
- Bandwidth exhaustion via Bloom filter spam
|
||||
|
||||
### Conflicting Peer Configurations
|
||||
|
||||
- Two configured peers with same npub but different addresses
|
||||
- Discovered peer conflicts with configured peer
|
||||
|
||||
### TUN Interface Unavailable
|
||||
|
||||
- TUN creation fails (permissions, kernel module)
|
||||
- Can node run in "relay-only" mode without TUN?
|
||||
|
||||
@@ -266,20 +312,20 @@ The discover() return type doesn't show the hint field.
|
||||
|
||||
## Resolution Tracking
|
||||
|
||||
| # | Issue | Priority | Status | Resolution |
|
||||
|---|-------|----------|--------|------------|
|
||||
| 1 | Coordinate ordering | High | OPEN | |
|
||||
| 2 | Auth protocol reference | High | OPEN | |
|
||||
| 3 | Concurrency model | High | OPEN | |
|
||||
| 4 | Keepalive format | High | OPEN | |
|
||||
| 5 | Cache naming | High | OPEN | |
|
||||
| 6 | Peer/Link relationship | Medium | OPEN | |
|
||||
| 7 | Error handling | Medium | OPEN | |
|
||||
| 8 | Memory bounds | Medium | OPEN | |
|
||||
| 9 | Timer management | Medium | OPEN | |
|
||||
| 10 | Init/shutdown | Medium | OPEN | |
|
||||
| 11 | Config validation | Low | OPEN | |
|
||||
| 12 | Default rationales | Low | OPEN | |
|
||||
| 13 | Terminology | Low | OPEN | |
|
||||
| 14 | Gateway details | Low | OPEN | |
|
||||
| 15 | DiscoveredPeer hint | Low | OPEN | |
|
||||
| # | Issue | Priority | Status | Resolution |
|
||||
|----|------------------------|----------|----------|-------------------------------|
|
||||
| 1 | Coordinate ordering | High | RESOLVED | node→root standardized |
|
||||
| 2 | Auth protocol ref | High | DEFERRED | wire protocol (future) |
|
||||
| 3 | Concurrency model | High | DEFERRED | future iteration |
|
||||
| 4 | Keepalive format | High | DEFERRED | wire protocol (future) |
|
||||
| 5 | Cache naming | High | RESOLVED | clarified in architecture |
|
||||
| 6 | Peer/Link relationship | Medium | OPEN | |
|
||||
| 7 | Error handling | Medium | DEFERRED | future iteration |
|
||||
| 8 | Memory bounds | Medium | OPEN | |
|
||||
| 9 | Timer management | Medium | OPEN | |
|
||||
| 10 | Init/shutdown | Medium | OPEN | |
|
||||
| 11 | Config validation | Low | OPEN | |
|
||||
| 12 | Default rationales | Low | OPEN | |
|
||||
| 13 | Terminology | Low | RESOLVED | fips-design, fips-links updated|
|
||||
| 14 | Gateway details | Low | OPEN | |
|
||||
| 15 | DiscoveredPeer hint | Low | OPEN | |
|
||||
|
||||
@@ -163,13 +163,13 @@ TreeState
|
||||
│ ├── sequence: u64 // monotonic
|
||||
│ └── signature: Signature
|
||||
├── my_coords: Vec<NodeId> // [self, parent, grandparent, ..., root]
|
||||
├── root: NodeId // elected root (smallest reachable node_id)
|
||||
└── coord_cache: HashMap<Ipv6Addr, CachedCoords> // for data packet routing
|
||||
└── root: NodeId // elected root (smallest reachable node_id)
|
||||
```
|
||||
|
||||
### Per-Peer State
|
||||
|
||||
From each peer, we receive and store:
|
||||
|
||||
- Their `ParentDeclaration`
|
||||
- Their `ancestry` (path from peer to root)
|
||||
|
||||
@@ -178,10 +178,12 @@ This provides their tree coordinates for routing decisions.
|
||||
### Bounded State
|
||||
|
||||
Each node's TreeState contains O(P × D) entries, not O(N):
|
||||
|
||||
- P = direct peer count
|
||||
- D = tree depth
|
||||
|
||||
A node knows only:
|
||||
|
||||
1. Its own parent declaration
|
||||
2. Direct peers' parent declarations
|
||||
3. Ancestry chains from each peer to root
|
||||
@@ -205,6 +207,7 @@ BloomState
|
||||
### Per-Peer State
|
||||
|
||||
Stored on Peer:
|
||||
|
||||
- `inbound_filter`: what they advertise to us (4KB Bloom filter)
|
||||
- `filter_sequence`: freshness/dedup
|
||||
- `filter_ttl`: remaining propagation hops
|
||||
@@ -244,6 +247,7 @@ TTL is decremented on contributed entries. Recomputation is cheap (4KB filter,
|
||||
- `Failed`: couldn't start
|
||||
|
||||
**Events:**
|
||||
|
||||
- `Start` (from config policy or API)
|
||||
- `Started` / `StartFailed`
|
||||
- `Shutdown`
|
||||
@@ -693,6 +697,7 @@ TransportConfig
|
||||
### Discovery
|
||||
|
||||
Discovery is per-transport:
|
||||
|
||||
- Transports emit `DiscoveredPeer { addr, hint }` events
|
||||
- Node matches against known peer configs or creates "unknown peer" entries
|
||||
- Policy (`auto_connect`, per-peer `connect_policy`) determines action
|
||||
@@ -744,6 +749,9 @@ Discovery is per-transport:
|
||||
| `discovery.cache.max_entries` | u32 | 10000 | Route cache size |
|
||||
| `discovery.cache.ttl` | duration | 300s | Cached coordinates expiry |
|
||||
|
||||
The discovery cache stores coordinates learned from LookupResponses for destinations
|
||||
this node wants to reach. This is the primary cache for endpoint nodes.
|
||||
|
||||
### Session Management
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
@@ -753,6 +761,11 @@ Discovery is per-transport:
|
||||
| `session.cache.ttl` | duration | 300s | Cached coordinates expiry |
|
||||
| `session.refresh.interval` | duration | 240s | Proactive session refresh |
|
||||
|
||||
The session cache stores coordinates learned from SessionSetup packets passing through
|
||||
this node as a transit router. Larger than discovery cache since routers see traffic
|
||||
for many destinations. Both caches are part of Node.coord_cache; these parameters
|
||||
configure the same underlying cache but are grouped by purpose.
|
||||
|
||||
### Peer Defaults
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
@@ -836,6 +849,6 @@ Discovery is per-transport:
|
||||
## References
|
||||
|
||||
- [fips-design.md](fips-design.md) — Overall FIPS protocol design
|
||||
- [fips-links.md](fips-links.md) — Link layer requirements
|
||||
- [fips-links.md](fips-links.md) — Transport protocols and characteristics
|
||||
- [fips-routing.md](fips-routing.md) — Routing, Bloom filters, discovery
|
||||
- [spanning-tree-dynamics.md](spanning-tree-dynamics.md) — Tree protocol dynamics
|
||||
|
||||
+47
-56
@@ -346,14 +346,18 @@ hysteresis ensures the tree remains stable under transient conditions.
|
||||
|
||||
### Tree Coordinates
|
||||
|
||||
A node's coordinate is its path from root:
|
||||
A node's coordinate is its path to root:
|
||||
|
||||
```text
|
||||
Coordinate = [root_id, ..., parent_id, self_id]
|
||||
Coordinate = [self_id, parent_id, ..., root_id]
|
||||
```
|
||||
|
||||
Coordinates are ordered self-to-root, so common ancestry is a suffix. This
|
||||
ordering is consistent across all FIPS documents.
|
||||
|
||||
**Distance metric**: Tree distance between two nodes is the sum of hops to their
|
||||
lowest common ancestor (LCA):
|
||||
lowest common ancestor (LCA). With self-to-root ordering, the LCA is found by
|
||||
comparing coordinate suffixes:
|
||||
|
||||
```
|
||||
dist(A, B) = depth(A) + depth(B) - 2 * depth(LCA(A, B))
|
||||
@@ -478,80 +482,66 @@ When greedy routing fails (local minimum):
|
||||
|
||||
## 5. Transport Abstraction Layer
|
||||
|
||||
### Link Interface
|
||||
FIPS is transport-agnostic. Transports are the physical or logical interfaces
|
||||
over which FIPS communicates (UDP sockets, Ethernet NICs, Tor clients, etc.).
|
||||
Links are connection instances to specific peers over a transport.
|
||||
|
||||
```rust
|
||||
trait FipsLink: Send + Sync {
|
||||
/// Unique identifier for this link type
|
||||
fn link_type(&self) -> &str;
|
||||
> **Note**: The Transport trait definition and detailed transport specifications
|
||||
> are in [fips-architecture.md](fips-architecture.md). This section provides a
|
||||
> conceptual overview. See [fips-links.md](fips-links.md) for transport
|
||||
> characteristics and requirements.
|
||||
|
||||
/// Maximum transmission unit
|
||||
fn mtu(&self) -> usize;
|
||||
### Transport Interface Concept
|
||||
|
||||
/// Estimated characteristics
|
||||
fn characteristics(&self) -> LinkCharacteristics;
|
||||
Each transport driver provides:
|
||||
|
||||
/// Send packet to peer
|
||||
async fn send(&self, peer: &PeerId, data: &[u8]) -> Result<()>;
|
||||
- **Identity**: Transport type identifier and configuration
|
||||
- **Lifecycle**: Start/stop the transport interface
|
||||
- **I/O**: Send/receive datagrams to/from transport-layer addresses
|
||||
- **Discovery**: Find potential peers (transport-specific mechanism)
|
||||
- **MTU**: Maximum packet size for this transport
|
||||
|
||||
/// Receive packet from any peer
|
||||
async fn recv(&self) -> Result<(PeerId, Vec<u8>)>;
|
||||
Transports handle framing, fragmentation, and any transport-layer encryption
|
||||
internally. The FIPS routing layer sees only FIPS packets.
|
||||
|
||||
/// List connected peers
|
||||
fn peers(&self) -> Vec<PeerId>;
|
||||
### Transport Types
|
||||
|
||||
/// Link-specific peer discovery (if supported)
|
||||
async fn discover(&self) -> Result<Vec<PeerInfo>>;
|
||||
}
|
||||
|
||||
struct LinkCharacteristics {
|
||||
latency_ms: u32,
|
||||
bandwidth_bps: u64,
|
||||
reliability: f32, // 0.0 - 1.0
|
||||
is_metered: bool,
|
||||
is_symmetric: bool,
|
||||
supports_broadcast: bool,
|
||||
}
|
||||
```
|
||||
|
||||
### Transport Implementations
|
||||
|
||||
#### TCP/TLS Link
|
||||
#### TCP/TLS Transport
|
||||
|
||||
Standard Yggdrasil-style IP peering with TLS encryption.
|
||||
|
||||
#### QUIC Link
|
||||
#### QUIC Transport
|
||||
|
||||
UDP-based with built-in encryption and multiplexing.
|
||||
|
||||
#### Radio Link (LoRa, HF, VHF/UHF)
|
||||
#### Radio Transport (LoRa, HF, VHF/UHF)
|
||||
|
||||
- Packet-based with size limits
|
||||
- May support broadcast
|
||||
- Often asymmetric (different TX/RX capabilities)
|
||||
- Requires careful bandwidth management
|
||||
|
||||
#### Serial Link (RS-232, USB, etc.)
|
||||
#### Serial Transport (RS-232, USB, etc.)
|
||||
|
||||
- Point-to-point
|
||||
- Framing protocol needed (SLIP, HDLC, etc.)
|
||||
- Good for isolated node pairs
|
||||
|
||||
#### Onion Link (Tor, I2P)
|
||||
#### Onion Transport (Tor, I2P)
|
||||
|
||||
- High latency
|
||||
- Strong anonymity properties
|
||||
- Special handling for circuit setup
|
||||
|
||||
#### Bluetooth/BLE Link
|
||||
#### Bluetooth/BLE Transport
|
||||
|
||||
- Short range
|
||||
- Discovery via scanning
|
||||
- Pairing considerations
|
||||
|
||||
### Multi-Link Routing
|
||||
### Multi-Transport Routing
|
||||
|
||||
A single node may have multiple links of different types:
|
||||
A single node may have multiple transports of different types:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
@@ -560,22 +550,23 @@ A single node may have multiple links of different types:
|
||||
│ │ Router Core │ │
|
||||
│ └──────────┬──────────┬───────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌──────┴───┐ ┌────┴────┐ │
|
||||
│ │ TCP Link │ │LoRa Link│ │
|
||||
│ └────┬─────┘ └────┬────┘ │
|
||||
└───────────┼────────────┼───────────────┘
|
||||
│ │
|
||||
┌────┴────┐ ┌────┴────┐
|
||||
│Internet │ │ Radio │
|
||||
│ Peers │ │ Peers │
|
||||
└─────────┘ └─────────┘
|
||||
│ ┌──────┴────┐ ┌───┴─────┐ │
|
||||
│ │ TCP │ │ LoRa │ │
|
||||
│ │ Transport │ │Transport│ │
|
||||
│ └────┬──────┘ └────┬────┘ │
|
||||
└───────────┼─────────────┼──────────────┘
|
||||
│ │
|
||||
┌────┴────┐ ┌─────┴────┐
|
||||
│Internet │ │ Radio │
|
||||
│ Peers │ │ Peers │
|
||||
└─────────┘ └──────────┘
|
||||
```
|
||||
|
||||
**Link selection for forwarding**:
|
||||
**Transport selection for forwarding**:
|
||||
|
||||
- Prefer link with best path to destination
|
||||
- Consider link characteristics (don't send bulk over LoRa)
|
||||
- Support explicit link preferences in routing hints
|
||||
- Prefer transport with best path to destination
|
||||
- Consider transport characteristics (don't send bulk over LoRa)
|
||||
- Support explicit transport preferences in routing hints
|
||||
|
||||
---
|
||||
|
||||
@@ -641,7 +632,7 @@ Lookup {
|
||||
LookupResponse {
|
||||
destination: [u8; 32],
|
||||
nonce: [u8; 16], // Echo from request
|
||||
coordinates: Vec<[u8; 32]>, // Path from root
|
||||
coordinates: Vec<[u8; 32]>, // Path to root [self, parent, ..., root]
|
||||
signature: [u8; 64],
|
||||
}
|
||||
```
|
||||
|
||||
+59
-58
@@ -1,9 +1,18 @@
|
||||
# FIPS Link Protocols
|
||||
# FIPS Transport Protocols
|
||||
|
||||
FIPS nodes peer with each other over a variety of link types. This document
|
||||
explores the requirements and characteristics of different link protocols
|
||||
FIPS nodes peer with each other over a variety of transport types. This document
|
||||
explores the requirements and characteristics of different transport protocols
|
||||
that FIPS can operate over.
|
||||
|
||||
## Terminology
|
||||
|
||||
- **Transport**: A physical or logical interface over which FIPS communicates
|
||||
(e.g., a UDP socket, Ethernet NIC, or Tor client)
|
||||
- **Link**: A connection instance to a specific peer over a transport
|
||||
|
||||
This document describes transport-level characteristics. See
|
||||
[fips-architecture.md](fips-architecture.md) for the Transport trait definition.
|
||||
|
||||
## Design Principles
|
||||
|
||||
FIPS is a Layer 3 (network) protocol. It exposes an IPv6 interface to local
|
||||
@@ -11,46 +20,46 @@ applications, with an address deterministically derived from the node's npub.
|
||||
This means existing UDP, TCP, and other IP-based applications work unmodified
|
||||
over FIPS.
|
||||
|
||||
However, this IPv6-over-links architecture requires care to avoid classic
|
||||
encapsulation pitfalls. In particular, running TCP over a reliable link (like
|
||||
TCP/IP overlay) creates "TCP-over-TCP" where retransmission and congestion
|
||||
However, this IPv6-over-transport architecture requires care to avoid classic
|
||||
encapsulation pitfalls. In particular, running TCP over a reliable transport
|
||||
(like TCP/IP overlay) creates "TCP-over-TCP" where retransmission and congestion
|
||||
control mechanisms at both layers interact adversely. FIPS prefers unreliable
|
||||
links for this reason.
|
||||
transports for this reason.
|
||||
|
||||
FIPS treats underlying connectivity as abstract links, regardless of whether
|
||||
those links are:
|
||||
FIPS treats underlying connectivity as abstract transports, regardless of
|
||||
whether those transports are:
|
||||
|
||||
- True L2 protocols (Ethernet, Bluetooth)
|
||||
- L4-over-L3 tunnels (UDP/IP) used as link substrate for NAT traversal
|
||||
- L4-over-L3 tunnels (UDP/IP) used as transport substrate for NAT traversal
|
||||
- Application-layer overlays (Tor, I2P)
|
||||
|
||||
Each link driver presents a uniform interface to the FIPS routing layer:
|
||||
send/receive datagrams to/from a link-layer peer address.
|
||||
Each transport driver presents a uniform interface to the FIPS routing layer:
|
||||
send/receive datagrams to/from a transport-layer peer address.
|
||||
|
||||
## Link Protocol Characteristics
|
||||
## Transport Characteristics
|
||||
|
||||
### Overlay Links (L3/L4 Substrate)
|
||||
### Overlay Transports (L3/L4 Substrate)
|
||||
|
||||
These links tunnel FIPS over an existing network layer, typically for internet
|
||||
connectivity or anonymity. Overlay links are expected to be the majority in
|
||||
early deployments, but all depend on existing IP/Internet infrastructure that
|
||||
FIPS is ultimately designed to replace.
|
||||
These transports tunnel FIPS over an existing network layer, typically for
|
||||
internet connectivity or anonymity. Overlay transports are expected to be the
|
||||
majority in early deployments, but all depend on existing IP/Internet
|
||||
infrastructure that FIPS is ultimately designed to replace.
|
||||
|
||||
| Link | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|------|---------------|------------|-----|---------|-------------|-----------|-----------|
|
||||
| Transport | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|-----------|---------------|------------|-----|---------|-------------|-----------|-----------|
|
||||
| UDP/IP | UDP datagram | IP:port | 1280-1472 | 1-500ms | Unreliable | High | DNS-SD, Nostr |
|
||||
| TCP/IP | Framed stream | IP:port | Stream | 10-500ms | Reliable | High | DNS-SD, Nostr |
|
||||
| WebSocket | WS frames | URL | Stream | 10-500ms | Reliable | High | Nostr |
|
||||
| Tor | TCP stream | .onion | Stream | 500ms-5s | Reliable | Low-Med | Static, Nostr |
|
||||
| I2P | I2P datagram | Destination | ~32K | 1-10s | Unreliable | Low | I2P directory |
|
||||
|
||||
### Shared Medium Links
|
||||
### Shared Medium Transports
|
||||
|
||||
These links operate over broadcast or multicast-capable media where multiple
|
||||
These transports operate over broadcast or multicast-capable media where multiple
|
||||
endpoints share the same physical or logical channel.
|
||||
|
||||
| Link | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|------|---------------|------------|-----|---------|-------------|-----------|-----------|
|
||||
| Transport | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|-----------|---------------|------------|-----|---------|-------------|-----------|-----------|
|
||||
| Ethernet | EtherType frame | MAC | 1500 | <1ms | Unreliable | High | Multicast |
|
||||
| WiFi Direct | 802.11 frame | MAC | 1500 | 1-10ms | Unreliable | High | Service discovery |
|
||||
| DOCSIS (Cable) | DOCSIS frame | MAC | 1500 | 10-50ms | Unreliable | 1M-1G | N/A (uses IP) |
|
||||
@@ -59,14 +68,15 @@ endpoints share the same physical or logical channel.
|
||||
| Zigbee | 802.15.4 frame | 16/64-bit | ~100 | 15-30ms | Reliable | 250 kbps | Network scan |
|
||||
| LoRa | Raw packet | Device addr | 51-222 | 100ms-10s | Unreliable | 0.3-50 kbps | Beacons |
|
||||
|
||||
### Point-to-Point Links
|
||||
### Point-to-Point Transports
|
||||
|
||||
These links connect exactly two endpoints with no shared medium or addressing.
|
||||
These transports connect exactly two endpoints with no shared medium or
|
||||
addressing.
|
||||
|
||||
| Link | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|--------|-----------------|------------|----------|-----------|-------------|-----------|------------|
|
||||
| Serial | SLIP/COBS frame | None (P2P) | 256-1500 | 1-100ms | Reliable | 9.6K-1M | Configured |
|
||||
| Dialup | PPP frame | None (P2P) | 1500 | 100-200ms | Reliable | 33.6-56K | Configured |
|
||||
| Transport | Encapsulation | Addressing | MTU | Latency | Reliability | Bandwidth | Discovery |
|
||||
|-----------|---------------|------------|----------|-----------|-------------|-----------|------------|
|
||||
| Serial | SLIP/COBS frame | None (P2P) | 256-1500 | 1-100ms | Reliable | 9.6K-1M | Configured |
|
||||
| Dialup | PPP frame | None (P2P) | 1500 | 100-200ms | Reliable | 33.6-56K | Configured |
|
||||
|
||||
### Notes
|
||||
|
||||
@@ -84,50 +94,41 @@ the routing layer.
|
||||
**Bandwidth**: Order of magnitude. Affects flow control and congestion
|
||||
decisions, but FIPS routing itself is low-bandwidth (control plane only).
|
||||
|
||||
## UDP/IP as Primary Internet Link
|
||||
## UDP/IP as Primary Internet Transport
|
||||
|
||||
For internet-connected nodes, UDP/IP is the recommended link protocol:
|
||||
For internet-connected nodes, UDP/IP is the recommended transport:
|
||||
|
||||
- **NAT traversal**: UDP hole punching enables peer connections through NAT
|
||||
- **Firewall compatibility**: UDP outbound rarely blocked; stateful firewalls
|
||||
pass return traffic
|
||||
- **No connection state**: Matches FIPS datagram model
|
||||
- **Low overhead**: 8-byte UDP header is negligible
|
||||
- **Avoids TCP-over-TCP**: As noted in Design Principles, unreliable links
|
||||
- **Avoids TCP-over-TCP**: As noted in Design Principles, unreliable transports
|
||||
avoid adverse interactions with application-layer TCP
|
||||
|
||||
Raw IP with a custom protocol number would be cleaner but is blocked by most
|
||||
NAT devices and firewalls, limiting deployment to networks without NAT.
|
||||
|
||||
## Link Driver Interface
|
||||
## Transport Driver Interface
|
||||
|
||||
Each link driver implements:
|
||||
> **Note**: The definitive Transport trait is defined in
|
||||
> [fips-architecture.md](fips-architecture.md). This section provides a
|
||||
> simplified conceptual view.
|
||||
|
||||
```rust
|
||||
trait LinkDriver {
|
||||
type PeerAddr: Clone + Eq + Hash;
|
||||
Each transport driver provides:
|
||||
|
||||
/// Send a FIPS packet to a peer
|
||||
fn send(&self, peer: &Self::PeerAddr, data: &[u8]) -> Result<()>;
|
||||
- `send(addr, data)` — Send a FIPS packet to a transport-layer address
|
||||
- `recv()` — Receive a FIPS packet from any peer
|
||||
- `mtu()` — Maximum FIPS packet size for this transport
|
||||
- `discover()` — Find potential peers (transport-specific mechanism)
|
||||
|
||||
/// Receive a FIPS packet (blocking)
|
||||
fn recv(&self) -> Result<(Self::PeerAddr, Vec<u8>)>;
|
||||
|
||||
/// Link MTU (maximum FIPS packet size)
|
||||
fn mtu(&self) -> u16;
|
||||
|
||||
/// Discover potential peers (link-specific mechanism)
|
||||
fn discover(&self) -> Result<Vec<Self::PeerAddr>>;
|
||||
}
|
||||
```
|
||||
|
||||
Link drivers handle any necessary framing, fragmentation, or encryption
|
||||
at the link layer. The FIPS routing layer sees only FIPS packets.
|
||||
Transport drivers handle any necessary framing, fragmentation, or encryption
|
||||
at the transport layer. The FIPS routing layer sees only FIPS packets.
|
||||
|
||||
## Topics for Further Design
|
||||
|
||||
- Framing protocols for stream-based links (TCP, WebSocket)
|
||||
- Link-layer encryption requirements vs FIPS-layer encryption
|
||||
- Congestion control and flow control per link type
|
||||
- Multi-path: using multiple links to same peer
|
||||
- Link quality metrics for parent selection
|
||||
- Framing protocols for stream-based transports (TCP, WebSocket)
|
||||
- Transport-layer encryption requirements vs FIPS-layer encryption
|
||||
- Congestion control and flow control per transport type
|
||||
- Multi-path: using multiple transports to same peer
|
||||
- Transport quality metrics for parent selection
|
||||
|
||||
@@ -142,7 +142,7 @@ Immediate actions:
|
||||
│ └── Contains: B's declaration (parent=B, seq=1), B's ancestry (just B)
|
||||
│
|
||||
└── D sends TreeAnnounce to B:
|
||||
└── Contains: D's declaration (parent=A, seq=47), D's ancestry [A, D]
|
||||
└── Contains: D's declaration (parent=A, seq=47), D's ancestry [D, A]
|
||||
```
|
||||
|
||||
**T2: B processes D's announcement**
|
||||
@@ -175,18 +175,18 @@ B's state change:
|
||||
|
||||
TreeState_B = { (B, parent=D, seq=2), (D, parent=A, seq=47), (A, parent=A, seq=203) }
|
||||
Root_B = A
|
||||
Coordinate_B = [A, D, B]
|
||||
Coordinate_B = [B, D, A]
|
||||
```
|
||||
|
||||
**T4: B announces to D**
|
||||
|
||||
```
|
||||
B sends TreeAnnounce to D:
|
||||
└── Contains: B's new declaration (parent=D, seq=2), ancestry [A, D, B]
|
||||
└── Contains: B's new declaration (parent=D, seq=2), ancestry [B, D, A]
|
||||
|
||||
D receives and merges:
|
||||
├── TreeState_D now includes B's entry
|
||||
├── D's coordinate unchanged: [A, D]
|
||||
├── D's coordinate unchanged: [D, A]
|
||||
└── D can now route to B
|
||||
```
|
||||
|
||||
@@ -333,7 +333,7 @@ Adding a link can:
|
||||
|
||||
```
|
||||
Before: A ← B ← C ← D (linear chain, A is root)
|
||||
D's coordinate: [A, B, C, D], depth 3
|
||||
D's coordinate: [D, C, B, A], depth 3
|
||||
|
||||
New link: A ←→ D established
|
||||
|
||||
@@ -342,7 +342,7 @@ D receives A's announcement directly:
|
||||
├── D evaluates: going through A gives depth 1 vs current depth 3
|
||||
├── If improvement > stability threshold:
|
||||
│ └── D re-parents to A
|
||||
│ └── D's new coordinate: [A, D], depth 1
|
||||
│ └── D's new coordinate: [D, A], depth 1
|
||||
|
||||
After: A is root
|
||||
├── B (depth 1)
|
||||
@@ -466,7 +466,7 @@ When connectivity is restored:
|
||||
Link C ←→ D restored:
|
||||
|
||||
T1: C and D exchange TreeAnnounce
|
||||
C sends: root=A, ancestry [A, B, C]
|
||||
C sends: root=A, ancestry [C, B, A]
|
||||
D sends: root=D (assuming D < E), ancestry [D]
|
||||
|
||||
T2: D processes C's announcement
|
||||
@@ -1036,7 +1036,7 @@ T6: E receives B's announcement:
|
||||
E selects B as parent
|
||||
|
||||
T7: E announces to F:
|
||||
E's new ancestry: [A, B, E]
|
||||
E's new ancestry: [E, B, A]
|
||||
F learns about A
|
||||
F re-parents (E is still valid parent, now with path to A)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user