Skip to main content

Server Mode

Server mode turns a cairn peer into an always-on node that provides store-and-forward messaging, traffic relaying, and multi-device synchronization.

What Server Mode Enables

Store-and-Forward

When a peer goes offline, messages sent to it are stored on the server node. When the peer reconnects, queued messages are delivered automatically. No messages are lost due to temporary disconnections.

Personal Relay

The server peer can relay traffic between peers that cannot connect directly -- for example, when both are behind restrictive NATs. Unlike a public relay, your server node is under your control and only relays traffic for your paired peers.

Multi-Device Sync

The server acts as a hub for syncing data across multiple devices. All devices pair with the server, and the server forwards messages between them. This is the foundation for applications like folder sync across a laptop, phone, and desktop.

Configuration Options

Enable server mode when creating a node by using create_server instead of create:

use cairn_p2p::{Node, CairnConfig, create_server};

let mut config = CairnConfig::default();
config.storage_path = Some("/var/lib/cairn/data".into());
config.max_message_retention_secs = Some(86400 * 7); // 7 days

let node = create_server(config)?;
node.start().await?;
println!("Server Peer ID: {}", node.peer_id());

Headless Pairing

Server nodes typically run unattended, so interactive PIN entry is impractical. cairn supports two headless pairing methods.

Pre-Shared Key (PSK)

Configure the server with a PSK. Clients pair by providing the same key -- no interactive PIN exchange required.

// Server side
let mut config = CairnConfig::default();
config.psk = Some("my-secret-pairing-key".into());
let node = create_server(config)?;
node.start().await?;
// Server automatically accepts peers that present this PSK

// Client side
let peer_id = node.pair_with_psk("my-secret-pairing-key", server_peer_id).await?;

Pre-Approved Peers

Configure the server with a list of peer IDs that are automatically accepted without any pairing ceremony.

let mut config = CairnConfig::default();
config.approved_peers = vec![
"5Hb7...peer1".into(),
"8Kx2...peer2".into(),
];
let node = create_server(config)?;
node.start().await?;
// Listed peers can connect directly without pairing

Integration with Signaling and Relay Infrastructure

A server-mode peer works alongside the cairn signaling and relay infrastructure:

  • Signaling: The server connects to a signaling server for peer discovery. Clients find the server through signaling rather than hardcoding IP addresses.
  • Relay (TURN): If direct connections fail (e.g., restrictive NATs), the server can use a TURN relay as a fallback transport.

Configure these when creating the server node:

let mut config = CairnConfig::default();
config.signal_servers = vec!["ws://signal.example.com:8443".into()];
config.turn_servers = vec!["turn:relay.example.com:3478".into()];
let node = create_server(config)?;

For details on deploying signaling and relay servers, see the Infrastructure documentation.