P2P Networking
Lowkey uses libp2p 0.56 for all peer-to-peer networking.
On this page
Protocol Stack
+-------------------------------------------------------------+
| Application Layer |
| +---------+ +---------+ +---------+ +------------------+ |
| |Kademlia | |Gossipsub| | Relay | | Request-Response | |
| | DHT | | PubSub | |Circuits | | (Chunk Transfer) | |
| +---------+ +---------+ +---------+ +------------------+ |
+-------------------------------------------------------------+
| Protocol Layer |
| +---------+ +---------+ +----------+ +---------+ |
| |Identify | | Ping | |Rendezvous| | AutoNAT | |
| +---------+ +---------+ +----------+ +---------+ |
+-------------------------------------------------------------+
| Multiplexing: Yamux |
+-------------------------------------------------------------+
| Security: Noise Protocol |
+-------------------------------------------------------------+
| Transport: TCP |
+-------------------------------------------------------------+
Core Protocols
Kademlia DHT
Distributed key-value storage and peer discovery.
| Key Pattern | Example | Usage |
|---|---|---|
manifest:{file_id} |
manifest:a1b2c3d4... |
File metadata |
kw:{token} |
kw:music |
Keyword index |
provider:{chunk_id} |
provider:a1b2c3d4... |
Chunk providers |
Gossipsub
Publish-subscribe messaging with mesh-based routing.
let config = gossipsub::ConfigBuilder::default()
.heartbeat_interval(Duration::from_secs(10))
.validation_mode(gossipsub::ValidationMode::Permissive)
.message_id_fn(content_based_id)
.build()?;
Request-Response
Direct unicast messaging for chunk transfer.
let config = request_response::Config::default()
.with_request_timeout(Duration::from_secs(30));
request_response::Behaviour::new(
[(CHUNK_PROTOCOL, ProtocolSupport::Full)],
config
)
Relay
NAT traversal via relay circuits through the seed node.
// Client mode
relay::client::Behaviour::new(local_peer_id)
// Server mode (seed node)
relay::Config {
max_reservations: 256,
max_circuits: 512,
..Default::default()
}
Other Protocols
| Protocol | Purpose |
|---|---|
| Rendezvous | Peer discovery without DHT lookup |
| Identify | Exchange peer metadata (public key, addresses) |
| AutoNAT | Detect NAT type and external address |
| DCUtR | Upgrade relay connections to direct |
| Ping | Connectivity checking |
PubSub Topics
| Topic | Purpose | Message Format |
|---|---|---|
lowkey-files |
File share announcements | JSON manifest |
lowkey-chunk-req |
Chunk request broadcast (fallback) | {t, from, chunk} |
lowkey-chunk-resp |
Chunk responses | {t, to, chunk, ok, data_b64} |
lowkey-stats |
Network statistics | JSON stats |
Connection Lifecycle
+----------+ +----------+ +----------+
| Peer A | | Seed | | Peer B |
+----+-----+ +----+-----+ +----+-----+
| | |
| 1. Connect to seed | |
|------------------->| |
| | |
| 2. Rendezvous | |
| register | |
|------------------->| |
| | |
| | 3. Connect to seed |
| |<-------------------|
| | |
| | 4. Rendezvous |
| | discover |
| |<-------------------|
| | |
| 5. Response with Peer A info |
|<----------------------------------------|
| | |
| 6. Direct connection attempt |
|<----------------------------------------|
| | |
| 7. (If NAT) Relay circuit via seed |
|<-------------------+-------------------->|
| | |
Transport Configuration
// Normal mode
tcp::tokio::Transport::new(tcp::Config::default())
.upgrade(libp2p::core::upgrade::Version::V1)
.authenticate(noise::Config::new(&local_key)?)
.multiplex(yamux::Config::default())
.boxed()
Seed Node
The seed node provides:
- DHT Bootstrap - Initial peer discovery
- Relay Server - NAT traversal for clients
- Rendezvous Server - Fast peer lookup
- Metrics Collection - Network statistics aggregation
Address: /ip4/141.253.120.2/tcp/4001/p2p/12D3KooWE5samB4h2tv2uPo7oWzPRsXeND4ymcQGK7knZUJpgFex