Skip to main content

Room Server Federation

Room Server Federation

Federation is the mechanism by which two or more MeshCore room servers, each serving their own local mesh island, share messages with one another over the internet — forming a single logical room that spans geographically separated areas. A message sent by a node in one city appears in real-time in the rooms of every other city that is federated into the same logical room.

Why Federate?

LoRa has a finite range (typically 5–30 km line-of-sight for outdoor deployments). A regional or national mesh network inevitably consists of multiple coverage islands separated by terrain, urban RF noise floors, or simply distance. Federation stitches these islands together at the application layer:

  • Regional emergency nets — multiple served-area room servers feed a shared regional room; net control can monitor all sectors simultaneously.
  • Community mesh expansion — neighbourhood A and neighbourhood B each have a room server; federation lets them talk as if they were on the same mesh.
  • Redundancy — if one room server loses internet, the local LoRa network continues to function. When internet returns, federation automatically re-synchronises the message backlog.

Federation Protocol Overview

MeshCore federation uses a publish-subscribe model over encrypted TLS connections between room servers. Each server acts as both a publisher (pushing messages it received first) and a subscriber (receiving messages from peers).


  [City A Room Server]──TLS──►[Federation Hub OR]──TLS──►[City B Room Server]
                                                          [City C Room Server]
                                                          [City D Room Server]

  OR (full mesh / peer-to-peer):

  [City A]──TLS──►[City B]
      │                │
      └──TLS──►[City C]──TLS──►[City D]

Messages carry a globally unique ID (GUID) assigned by the originating server. Every server tracks GUIDs it has seen; if a federated peer sends a message whose GUID is already known, it is silently dropped. This deduplication prevents infinite re-broadcast loops in meshes with cycles.

Configuring Federation

Add a [federation] section to /etc/meshcore/room.conf:

# /etc/meshcore/room.conf — federation section

[federation]
enabled = true

# Federation listen port (peers connect to this)
federation_port = 5001

# TLS certificate for this server (self-signed is acceptable for private federations)
tls_cert = /etc/meshcore/tls/server.crt
tls_key  = /etc/meshcore/tls/server.key

# Pre-shared federation secret — all peers must share this value
# Generate with: openssl rand -hex 32
federation_secret = "REPLACE_WITH_FEDERATION_PSK"

# List of remote peer room servers to connect to (host:port)
[[federation.peers]]
  name = "City B Room Server"
  addr = "cityb.example.com:5001"

[[federation.peers]]
  name = "City C Room Server"
  addr = "203.0.113.45:5001"

Generating TLS Certificates

sudo mkdir -p /etc/meshcore/tls
cd /etc/meshcore/tls

# Self-signed certificate valid for 10 years
sudo openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt   -days 3650 -nodes   -subj "/CN=$(hostname -f)/O=MeshCore Room/C=US"

sudo chown -R meshcore:meshcore /etc/meshcore/tls
sudo chmod 600 /etc/meshcore/tls/server.key

Opening the Federation Port

sudo ufw allow 5001/tcp comment "MeshCore Federation"

Message Routing Between Rooms

When a message arrives at Server A from a local LoRa node or TCP client:

  1. Server A stores the message locally and assigns it a GUID.
  2. Server A publishes the message to all connected federation peers (B, C, D).
  3. Each peer checks its GUID cache; if new, it stores the message and forwards it to its own connected TCP clients and re-broadcasts it over its local LoRa radio.
  4. Each peer marks the GUID as seen so it will reject re-delivery of the same message.

The end result: a single message from a field node in City A is heard by TCP clients and LoRa nodes in Cities B, C, and D within seconds (subject to internet latency).

When to Federate vs. Keep Rooms Separate

Situation Recommendation
Geographically adjacent communities want seamless comms Federate into one room
High-traffic local room, low-bandwidth internet link Keep separate — avoid saturating the WAN link
Two distinct organisations / net sections with different channel keys Keep separate rooms, optionally cross-post via a gateway script
Disaster coordination spanning multiple counties Federate all county rooms into a regional "EOC" room
Testing / development room Keep separate; never federate a dev room with production

Bandwidth Considerations

Each federated message is approximately 200–800 bytes over the wire (headers + payload + encryption overhead). At a typical LoRa data rate of 1–5 kbps, a single radio can generate at most a few hundred messages per hour. Federating 10 rooms at this rate produces around 1,000–3,000 messages per hour across the federation backbone — roughly 1–3 MB per hour, well within the capacity of any home broadband connection.

The limiting factor is usually the LoRa radio air time, not the internet link. However, if you federate many high-traffic rooms, monitor WAN utilisation to ensure you are not approaching your ISP's upload cap.

Network Topology Options

Star (Hub-and-Spoke)

One central room server acts as a hub; all others connect only to the hub. The hub must be highly available (VPS or colo-hosted). Failure of the hub partitions all spokes.

         [Hub]
        /  |        [A] [B] [C]

Full Mesh

Every server connects directly to every other server. Maximum redundancy; each server must maintain N-1 outbound TLS connections. Recommended for small federations (<6 servers).

  [A]──[B]
   |  X  |
  [C]──[D]

Ring

Each server connects to two neighbours. Messages circulate around the ring; GUID deduplication prevents loops. Acceptable redundancy for medium-sized federations.

Monitoring Federation Health

# Check which peers are currently connected
journalctl -u meshcore-room.service | grep -i "federation peer"

# Expected output lines:
# [INFO] Federation peer "City B" connected (TLS, latency 12ms)
# [INFO] Federation peer "City C" connected (TLS, latency 48ms)

The room server exposes a minimal HTTP status endpoint on port 5002 (configurable) when status_endpoint = true is set in the config. Hit http://<IP>:5002/status to get a JSON summary of connected peers, message counts, and queue depths.