Platform Features

Native Encrypted Mesh Networking

The distributed sensor walkthrough on this blog demonstrates how Mycelium instances can be networked together using TCP_Send and TCP_Receive directives — a flexible approach that works well for forwarding decoded telemetry to a central collector. But configuring each socket, coordinating port numbers, and managing connection state across dozens of edge nodes adds friction at deployment time.

Mycelium now includes a native peer-to-peer encrypted mesh built into every instance. There is no mode to enable and no additional daemon to run — the mesh starts with the process. Nodes on the same LAN discover each other automatically within seconds using UDP broadcast beacons. Nodes across subnets or WAN links are added with a single command. Once connected, every node in the mesh can reach every other node for command routing, data forwarding, and live RF transport.

Identity and Security

Every Mycelium node has a persistent Ed25519 keypair stored at ~/.config/mycelium/node_key, generated automatically on first run. The 32-byte public key is the node's identity — globally unique and cryptographically unforgeable.

Each TCP connection between nodes goes through a full key exchange. X25519 ephemeral keys are derived from the Ed25519 seed, and ECDH produces a shared secret. That secret is fed into HKDF-SHA256 to derive an AES-256-GCM session key unique to that connection and direction. Every frame sent after the handshake is encrypted and authenticated.

Automatic Discovery

Nodes broadcast a UDP beacon to the LAN every 15 seconds. The beacon carries the node's TCP port and its Ed25519 public key. Any Mycelium instance that receives a beacon from an unknown node immediately initiates a TCP connection and handshake. From the operator's perspective, two Mycelium instances started on the same network will find each other without any configuration:

For cross-subnet or WAN connections, a single command is sufficient:

node add -h 10.0.1.5 -p 7556

Remote Command Routing

Once nodes are connected, any CLI command can be executed on a remote node by prefixing it with @NODE. The command is routed over the encrypted mesh, executed on the target, and the result is returned to the local shell. This works for every command in the Mycelium command set — tool configuration, directive management, execution control:

@node_b tool show
@node_b execute -n ground_station
@node_b stop -t aircraft_tool
@node_b node show

The local shell blocks until the reply arrives, so remote commands feel synchronous. This makes it practical to script multi-node deployments from a single control point using standard .mycelium scripts.

Tool Data Routing — NODE:TOOL Addressing

The Send_To_Tool, Append_From_Tool, and Insert_From_Tool directive actions accept a NODE:TOOL address. When the node part names a remote node, the data is routed over the encrypted mesh and delivered directly to the target tool's inbox on the other side. No TCP socket configuration, no custom forwarding directives:

# Directive on node_a: forward decoded ACARS frames to node_b's aggregator tool
directive create -t rx_tool -n forward -c Any -a Send_To_Tool
directive set -t rx_tool -n forward -a Send_To_Tool -T node_b:aggregator

When the node part is omitted or matches the local node name, the delivery is local — the same action works for both cases without modification. This makes scripts portable: the same directive stack runs identically as a standalone sensor or as part of a multi-node pipeline.

MeshSDR — Simulating RF Links Over the Mesh

MeshSDR is a family of virtual SDR plugins that carry live IQ samples over the mesh instead of physical RF hardware. From the tool chain's perspective, a MeshSDR looks identical to a HackRF or RTL-SDR. Directives do not change. The only difference is the SDR type used at setup time:

Three MeshSDR types are available:

  • MeshTx — transmit only; serializes IQ samples and routes them to a named tool on a remote node
  • MeshRx — receive only; dequeues incoming IQ packets and presents them as SDR samples to the local tool chain
  • MeshDuplex — bidirectional; combines both directions for full-duplex RF simulation between two nodes

Both ends must be tuned to the same frequency. The transmitter embeds its frequency in each IQ packet, and the receiver matches on it — the same mechanism used by physical SDRs for channel selection.

The Colony Map

The Mycelium web interface includes a Colony tab that renders a live SVG topology map of the mesh. The local node sits at the center. Direct neighbors appear in green with solid edges. Nodes reachable through multiple hops appear in cyan with dashed edges. Edge labels show hop count. The map updates live over WebSocket as nodes join and leave.

digraph { graph [bgcolor="transparent" fontname="Inter" rankdir=TB pad=0.5] node [fontname="Inter" fontsize=11 fontcolor="#e2e8f0" style=filled fillcolor="#1a1033" color="#8b5cf6" penwidth=1.5 margin="0.2,0.12" shape=box] edge [color="#8b5cf6" fontcolor="#a78bfa" fontname="Inter" fontsize=9 arrowsize=0.8] subgraph cluster_node_a { label="node_a (Node A)" fontcolor="#e2e8f0" color="#22c55e" style=dashed bgcolor="#0f0a1e" gs_sdr [label="MeshDuplex SDR" shape=cylinder] gs_tool [label="ACARS\nground_station"] gs_sq [label="ACARS_Squitter_Start\nACARS_Auto_Ack_Start" shape=ellipse] gs_sdr -> gs_tool -> gs_sq } subgraph cluster_node_b { label="node_b (Node B)" fontcolor="#e2e8f0" color="#06b6d4" style=dashed bgcolor="#0f0a1e" ac_sdr [label="MeshDuplex SDR" shape=cylinder] ac_tool [label="ACARS\naircraft_tool"] ac_dir [label="Aircraft directive stack\n(logon, position, ack)" shape=ellipse] ac_sdr -> ac_tool -> ac_dir } gs_sdr -> ac_sdr [label="IQ over encrypted mesh\n(129.125 MHz)" style=dashed color="#22c55e"] ac_sdr -> gs_sdr [label="IQ over encrypted mesh\n(129.125 MHz)" style=dashed color="#06b6d4"] }

Putting It Together: ACARS Over Mesh

A practical demonstration of the mesh combines all three capabilities — remote commands, data routing, and MeshSDR — in a bidirectional ACARS simulation. One node runs a ground station. A second node runs a simulated aircraft. The two communicate over the mesh as if connected by a physical RF link at 129.125 MHz. No antennas, no attenuators, no lab hardware required.

The ground station script runs on node_a:

#!/usr/bin/Myce

# Ground station — ACARS at 129.125 MHz over mesh
sdr create -n gs_sdr -t MeshDuplex
sdr set -n gs_sdr -M node_b:aircraft_tool

tool create -p ACARS -n ground_station
tool set -n ground_station -r gs_sdr -f 129125000 -m AM:MSK

# Broadcast ground station presence and auto-acknowledge downlinks
directive create -t ground_station -n squitter -c Always -a ACARS_Squitter_Start
directive set -t ground_station -n squitter -a ACARS_Squitter_Start -p XA -i ORD -I KORD -N 1

directive create -t ground_station -n ack -c Always -a ACARS_Auto_Ack_Start

directive create -t ground_station -n listen -c Null -a Receive
directive create -t ground_station -n log    -c Any  -a Log -f /var/log/acars_ground.log -a

execute -n ground_station

The aircraft script runs on node_b. Once started (either directly or via @node_b from the ground station node), it performs a logon sequence and begins exchanging messages with the ground station over the mesh link:

#!/usr/bin/Myce

# Aircraft simulation — communicates with node_a ground station
sdr create -n ac_sdr -t MeshDuplex
sdr set -n ac_sdr -M node_a:ground_station

tool create -p ACARS -n aircraft_tool
tool set -n aircraft_tool -r ac_sdr -f 129125000 -m AM:MSK

directive create -t aircraft_tool -n listen -c Null -a Receive
directive create -t aircraft_tool -n respond -c Any -a Transmit
directive create -t aircraft_tool -n log    -c Any -a Log -f /var/log/acars_aircraft.log -a

execute -n aircraft_tool

Both nodes decode each other's transmissions, log the exchange, and respond to uplinks automatically. The ground station and aircraft never directly share an IP address in the scripts — the mesh handles routing transparently.

Routing and Scale

The current mesh router uses flooding with TTL (default 8 hops) and message-ID deduplication to prevent loops. Every node in the mesh can reach every other node through the shortest available path. As nodes are added, the topology updates via heartbeat and route advertisement — no manual routing configuration is required at any scale.

For deployments where dozens of sensor nodes need to route data to a single aggregator, NODE:TOOL forwarding replaces the per-node TCP socket setup that the manual approach requires. The aggregator node's name is the only configuration that needs to be consistent across edge scripts.



← Back to Blog