How it works

One daemon. Everything else is a link.

Nexus Atlas is a userspace Layer-3 transport: it owns a TUN interface, and every physical path is just a UDP socket it measures and schedules — fiber and Ethernet, satellite, cellular, microwave, Wi-Fi, 802.11ah HaLow, 802.11s mesh, MANET and serial telemetry radios, Bluetooth, and custom SDR waveforms alike. The rule is simply that it carries a UDP datagram; the bond neither knows nor cares what the physics underneath look like. This page walks a packet end to end, then opens the engine.

Rust · tokio · one binaryNo kernel module
The data path

A packet’s life, transmit side.

Applications see a normal network interface (atlas0, e.g. 10.0.100.1/24). The kernel routes into it; the daemon does the rest. Every number here is the shipping default.

01 · Ingress

Read from TUN

The daemon reads raw IPv4 packets from the TUN device. Destination lookup is longest-prefix match over per-peer allowed_ips — malformed CIDRs are load-time errors, never runtime panics. (IPv6 inside the tunnel is the one long-standing documented gap; the underlay speaks IPv6.)

02 · Classify

Service class, if QoS is on

With [qos] enabled, a DSCP-first classifier (then port heuristics, then fallback) assigns one of six classes. The class and reliability mode pack into a previously unused header byte — wire-compatible with non-QoS builds, and with QoS off the data path is byte-identical to the pre-QoS engine. transport deep-dive ↗

03 · Fragment

Split at 1428 bytes

Inner packets larger than the fragment payload split into fragments sharing an ID, reassembled out of order on the far side, with a janitor reaping half-arrived buffers. The payload ceiling is 1428 B — a 1500 B underlay path less 28 B of IP and UDP and our own 44 — and it is fixed, not negotiated: the daemon shrinks it when a relay link is present so relayed datagrams still fit, but it does not grow to exploit a jumbo-frame underlay. A full-size video frame still crosses a PPP link over a 64 kbps serial radio.

04 · Encrypt

Noise IK by default — and a security layer you can replace

Out of the box, sessions come from a Noise IK handshake — X25519 key agreement, ChaCha20-Poly1305 AEAD, BLAKE2s — with deterministic tie-breaking when both sides initiate at once, and make-before-break rekeying every 2 minutes or 1 GiB with zero measured loss. security ↗

The whole security layer is a module, not a hard-coding. Identity, handshake, cipher suite and peer authorization sit behind narrow interfaces; the rest of the engine only ever asks for “make me a session with this peer” and “seal this fragment”. Nothing about scheduling, fragmentation, routing or traversal knows which algorithms answered. That seam is the point: cryptography is one of the few things an operator is frequently not free to choose, and a transport that welds one suite into its data path is unusable the moment a national standard, an accreditation regime or an internal policy says otherwise.

What that means concretely. Within the Noise framework the primitive set is a parameter of the same handshake, so moving to a different key agreement, AEAD or hash — an accredited module, a mandated national algorithm set, or the X25519 + ML-KEM-768 hybrid — is a build-time change rather than a redesign. Replacing the handshake framework outright with something else entirely is a bounded integration at that same boundary, not a fork of the engine. Today the default build ships the suite above; the FIPS-validated and post-quantum variants are specified engineering, not shipped features Roadmap — so if a programme is obliged to run a particular suite, that is precisely where the work lands, and the answer is an integration conversation rather than a “no”. One honest constraint comes with it: there is no cipher negotiation on the wire by explicit decision — one protocol version, one build across the fleet — so a suite is a fleet-wide choice, not a per-session one.

Authorization is pluggable today, separately from the crypto. The handshake proves a peer holds its key; deciding whether that key may join the network — and with which addresses — is a swappable component behind a single trait. Three providers ship (a static allowlist, a hot-reloaded keyfile, an external command hook), and an embedder can replace the module wholesale with their own PKI, an HSM, a corporate identity service or a bespoke enrolment protocol without touching the data path. So an operator runs the cryptography and the authorization scheme they want — or the ones their organisation and accreditation oblige them to run. Every failure mode fails closed. the providers ↗

05 · Schedule

Pick links, per packet

Eight strategies decide per packet — not per flow — using each link’s live EWMA RTT, jitter, windowed loss and declared capacity. Redundancy is a first-class outcome: the adaptive modes escalate from one to two to three simultaneous paths and step back down. bonding & scheduling ↗

06 · Transmit

Plain UDP, per-link sockets

Each [[link]] is a UDP socket bound to its device (SO_BINDTODEVICE) with its own bounded send queue (32 packets, drop-on-full, non-blocking) and its own rebind watchdog — a wedged or re-enumerated USB radio recovers without touching the other links. Relay links ride 66-byte encrypted envelopes through a relay server instead of a direct endpoint. traversal ↗

07 · Deliver

Verify, dedup, reassemble — or forward

Receive-side: AEAD verification, a 2048-entry per-session anti-replay window (checked after authentication), fragment reassembly, TUN egress. If the inner destination is another mesh node, the packet is instead re-fragmented and re-encrypted toward the next hop — relays are trusted fleet members, stated plainly. mesh ↗

What the overhead actually is. The protocol adds 44 bytes per fragment — 8 outer header + 20 inner header + 16 AEAD tag. On the wire, UDP + IPv4 add another 28, so the honest per-packet figure is 72 bytes. The latency cost is measured continuously by the daemon itself: p50 0.18 ms / p95 0.42 ms added, published in the bonding-tax ledger. Measured
Stage 03 · Fragment

The fragments of one packet do not travel together.

Splitting an oversized packet is ordinary. What is not ordinary is that the scheduler decides per fragment rather than per flow — so fragment #0 can leave on the Ethernet link and fragment #1 on the satellite. Arriving out of order is therefore the normal case on every packet rather than a fault to recover from, and the reassembly buffer is built around that, with a janitor so a half-arrived packet costs memory for a bounded time and no longer.

One oversized packet, three links, and the buffer that waits for the slow fragmentSimulation
Inner packet
Links

The ceiling is 1428 bytes: an assumed 1500-byte underlay path, less 28 bytes of IPv4 and UDP, less our own 44 bytes of header and tag. It is a compile-time constant — not a negotiation, and not a function of the tunnel MTU, which the fragmenter never reads. So it never grows to exploit a jumbo-frame underlay.

1428 Bfragment payload ceiling
order the fragments arrived in
0buffers reaped incomplete
What you’re watching: a simulation, slowed down — the packet rate, the path latencies and the janitor’s countdown are all compressed. The mechanism is the shipping one: the 1428-byte ceiling and the 66-byte relay envelope that shrinks it are compile-time constants; a fragment carries its index and the total, never a byte offset, so completion is a count rather than a jigsaw; buffers are keyed per source peer and fragment id, so one peer’s missing fragment can never stall another’s; and a buffer is dropped 10 seconds after its first fragment landed — measured from that arrival and never refreshed by later ones. The wait from first fragment to complete packet is measured on every multi-fragment packet and published in the bonding-tax ledger.
Stage 07 · Deliver

The receiver keeps the first copy and drops the second.

Dedup is the last step of the lifecycle above, and it is the step that makes redundancy affordable: send the same packet down two routes that share no intermediate node, keep whichever copy lands first, discard the rest. Cut a relay under one of them and there is nothing to reroute — the other copy is already on the wire.

Two routes out of different first hops — and the duplicate the receiver throws awaySimulation
Paths in use

Two routes leaving on different first hops, both carrying the same packet. The receiver keeps whichever copy arrives first and drops the later one before reassembly, so the application is handed exactly one. Cutting a relay on one route costs nothing measurable, because the copy on the other route was already travelling.

0duplicate copies discarded
bandwidth for one payload
0packets lost end to end
What you’re watching: a simulation, slowed down — the relay latencies and the ≈1.25 s dead-probe detection are shipping defaults, the packet rate is not. The mechanism is real: the receive path authenticates each fragment, and the shared multipath-dedup window recognises the relayed second copy and drops it before reassembly — per-hop re-encryption gives routed copies fresh nonces, so this is a separate check from the per-session replay window that already catches direct-path broadcast copies.
Engine anatomy

The parts that make the decisions.

The control loop around the data path: measurement in, topology shared, decisions out. Nothing here requires a controller — every box runs on every node.

Link monitor

Per-(peer, link) probes on each link’s own clock — 250 ms default, per-link configurable — smoothed with EWMA (α = 0.2), windowed jitter and loss, dead after 5 consecutive misses. A link is never assumed alive before its first completed round-trip, and sequence numbers ride real fragments so data loss is measured directly.

LSDB + SPF

A link-state database flooded to established peers — per-link cost and RSSI, served prefixes, node names, optional position and velocity — with aging, refresh and tombstones. Dijkstra runs over it for multi-hop routes; the dashboard’s topology view reads the same structure.

Scheduler

The per-packet chooser: cost models over live measurements, hysteresis and dwell timers so escalation is instant but de-escalation is deliberate, and per-class policy overrides when QoS is on.

Mesh control plane

CRDT membership with authenticated join, encrypted gossip (v2: ChaCha20-Poly1305 with per-opcode domain separation), and Ed25519-signed configuration epochs with a commit-confirmed apply lifecycle on every node.

Traversal

Netcheck (NAT classification from the data socket), relay clients, rendezvous and hole punching, deterministic relay election — all opt-in; with [traversal] off, none of it runs.

Telemetry

A once-per-second stats snapshot every consumer shares — CLI, dashboard, REST, the video governor — plus a Unix socket where radio adapters inject RSSI, noise and buffer depth from the hardware itself.

Version byte

One protocol version, checked on decode

The fleet runs one binary everywhere by policy; there is deliberately no version negotiation. Mixed builds fail loudly instead of corrupting silently.

Spare bits

New features ride unused fields

The service-class byte packs into a semantically unused header field; the FEC flag took a spare bit. Both shipped without a version bump — old nodes simply ignore them.

In-payload markers

Rekey without a wire change

Rekey initiations carry their marker inside the encrypted Noise payload; builds that predate it degrade to their peer-restart path instead of misparsing.

Specifications

The engine on one table.

Defaults in parentheses where configurable; everything on this table is the shipping implementation, not a target.

PropertyValue
ImplementationRust, userspace, tokio async runtime; one binary per architecture (x86-64, ARM64) on glibc with OpenSSL 3 — Debian 12, Ubuntu 22.04, RHEL 9 or newer; no kernel module, no DKMS
InterfaceLinux TUN (atlas0), inner IPv4, MTU 1420 (configurable)
Links per daemonNo fixed limit; 6 dissimilar types bonded on one node in the field (2× serial radio, Bluetooth-PPP, Wi-Fi ad-hoc, 802.11s mesh, Ethernet)
Declared link capacitytypically 64 kbps – 1.5 Gbps, per link
CryptographyNoise IK · X25519 · ChaCha20-Poly1305 · BLAKE2s
Rekeyevery 120 s or 1 GiB (configurable) · make-before-break · 0 measured loss
Anti-replay2048-entry sliding window per session, post-authentication
Overhead44 B/fragment protocol (+28 B UDP/IPv4 = 72 B on-wire) · 66 B relay envelope
Probing250 ms default, per-link override · EWMA α 0.2 · dead after 5 misses (≈1.25 s)
Scheduling8 strategies, per-packet; per-class policies with QoS on
MeshLSDB flood · Dijkstra SPF · relay TTL 8 hops · dual-SPF multipath
Reweighting cadencetypically configured 0.1–0.75 s — a response cadence, not a recovery guarantee
FootprintRuns on single-board computers around 15 g; the same binary runs on servers
Test estateUnit, integration and full-system coverage on every change — end-to-end suites drive real daemons through link loss, key rotation, config rollback and carrier-NAT traversal; dependency and licence auditing gate every merge
LicenceProprietary, subscription — persistent nodes licensed, ephemeral nodes free; signed offline licence files, no kill switch
CrateWhat it is
nexus-atlas-protoWire types and serialization — headers, probes, mesh, relay envelopes; no I/O
nexus-atlas-coreThe engine: data path, crypto, scheduler, link monitor, LSDB/SPF, mesh, traversal, config lifecycle
atlasdThe daemon binary — keygen · run · status · stats · monitor · web · enroll · config …
nexus-atlas-qosTraffic classes: classifier, priority queues, deadlines, per-class multipath, adaptive escalation
nexus-atlas-fecSystematic GF(256) Reed–Solomon erasure coding, implemented from scratch, pure and deterministic
nexus-atlas-bundleStore-carry-forward bundle queue with pluggable backends (memory / write-ahead-log file)
nexus-atlas-terrainDEM line-of-sight, Fresnel and diffraction analysis → a terrain risk score (crate built; engine wiring in development)
nexus-atlas-stunMinimal STUN — RFC 8489 binding + RFC 5780 OTHER-ADDRESS — for netcheck and the relays
nexus-atlas-relayThe relay server binary: STUN observation pair + authenticated opaque-envelope forwarder + rendezvous

Plus nexus-atlas-web (the dashboard SPA the daemon embeds) and a shared telemetry crate the four external radio adapters build on — see integrations.

System architecture

Four tiers, one process.

The whole product on one page, before the detail below takes it apart. Applications never learn any of it exists; everything from the tunnel interface down to the peers is what the daemon does on their behalf.

Nexus Atlas — system architecture the daemonnot ours
Nexus Atlas system architecture Four tiers. Applications write into the atlas0 tunnel interface and the engine takes over: a data path of crypto, fragmentation, scheduling and anti-replay, over a control plane of routing, link-state database, mesh membership and link monitoring. Below it, per-link UDP sockets, the wire format and session lifecycle. Below that, the physical bearers — satellite, cellular, microwave, Wi-Fi and Ethernet — all carrying the same bonded tunnel to peers, some reached directly and some through a relay hop. APPLICATION LAYER Applications any IP traffic, unchanged atlas0 the tunnel the daemon owns NEXUS ATLAS ENGINE DATA PATH — EVERY PACKET CONTROL PLANE — MEASUREMENT IN, DECISIONS OUT cryptoNoise IK · AEAD fragmentsplit · reassemble schedulerper packet anti_replay2048-entry window link_monitorprobes · EWMA lsdbflood · Dijkstra SPF routenext hop meshCRDT · signed epochs sealed fragments, each already assigned to a link TRANSPORT LAYER Per-link sockets one UDP socket per [[link]], bound to its device Wire format 44 B of header and tag · one version, no negotiation Session lifecycle handshake · make-before-break rekey PHYSICAL LINKS — NOT OURS GEO VSATsatellite · global reachhigh latency, its own probe clockIN THE BOND LTE / 5Gcellular · wide coverageroams without dropping the sessionIN THE BOND Microwavepoint to pointbehaves like fibre until the weatherIN THE BOND Wi-Fi / Ethernetlocal · highest throughputshortest reach of the fourIN THE BOND PEER MESH SELF-FORMING · MULTI-HOP ONE BONDED TUNNEL · ENCRYPTED · FRAGMENTED Peer βdirect session · 1 hop Peer γdirect session · relay-capable Peer δreached through γ · 2 hops relay hop
Everything named in monospace is a real module. The layered view below walks the same tiers with the full module list and the honest caveats — this one is the shape of it.
The stack

The same crates, stacked into a running system.

Five layers between an application socket and a peer on the far side of the bond. Only the two solid bands are the daemon; everything above and below belongs to somebody else — the kernel, the radios, the peers. Every name set in monospace is a real crate or module in the workspace, so this picture and the table above describe the same thing.

From an application socket to a peer, through one process inside the daemonoutside itthe engine
Layer 01

Applications

Unchanged, and unaware.

Any IP traffic

Ordinary sockets in ordinary programs. Nothing links against Atlas, nothing is recompiled for it, and no application ever learns that it has more than one path.

atlas0

The TUN interface the daemon owns — inner IPv4, MTU 1420 by default, one address per node. The kernel routes into it and that is the entire integration surface. tun_device.rs

the kernel routes into atlas0; the daemon reads raw IPv4 packets out of it

Layer 02

The engine

One library crate, nexus-atlas-core. The atlasd binary is a thin CLI over it, and the Android app embeds the same code through a JNI bridge.

Data path — every packet, every time
crypto

Noise IK sessions — X25519, ChaCha20-Poly1305, BLAKE2s. Sealing and opening happen here and nowhere else, behind an interface the rest of the engine cannot see past.

fragment

Splits inner packets at 1428 bytes and reassembles them out of order on the far side, with a janitor reaping half-arrived buffers.

scheduler

Eight strategies choosing links per packet rather than per flow, from live RTT, jitter, windowed loss and declared capacity.

anti_replay

A 2048-entry sliding window per session, checked after authentication — never before it.

multipath_dedup

A shared time window on the receive side that drops the second and later copies of a packet sent down more than one route.

qosopt-in

Service classes, priority queues, deadline budgets and store-carry-forward. Switched off, the data path is byte-identical to the pre-QoS engine.

Control plane — measurement in, topology shared, decisions out
link_monitor

Per-(peer, link) probes on each link's own clock, EWMA-smoothed, dead after five consecutive misses. It also holds whatever the radio adapters have told it.

lsdb

The link-state database flooded to established peers — costs, served prefixes, names, optional position — with Dijkstra SPF run over it.

route

Next-hop selection when the inner destination belongs to another node rather than to this one.

static_fibopt-in

Operator-declared end-to-end paths that bypass SPF entirely, for when the topology is a policy decision.

mesh

CRDT membership with authenticated join, encrypted gossip, and signed configuration epochs with a commit-confirmed apply on every node.

traversalopt-in

NAT classification from the data socket, rendezvous, hole punching and relay election. Switched off, none of it runs.

sealed fragments, each already assigned to the link the scheduler chose for it

Layer 03

Wire and sockets

Still inside the process — the part that touches the operating system.

Per-link sockets

One UDP socket per [[link]], bound to its own device, each with its own bounded send queue that drops rather than blocks, and a watchdog that swaps in a fresh socket when an interface is re-enumerated. Two links on one device need distinct ports. transport.rs

Packet format

44 bytes per fragment — 8 outer header, 20 inner header, 16 bytes of AEAD tag. UDP and IPv4 add 28 more, so the honest on-wire figure is 72. One protocol version, checked on decode, with no negotiation. nexus-atlas-proto

Session lifecycle

Handshake, make-before-break rekeying on an interval or a byte count, and deterministic tie-breaking when both ends initiate at once. Rekey markers ride inside the encrypted payload, so adding them cost no wire change. engine/handshake.rs

one UDP datagram per fragment, out of the socket bound to that bearer

Layer 04

Bearers

Not ours. Anything that carries a datagram qualifies, and the bond scores each on its own terms.

GEO VSAT

Give it its own probe interval or the physics reads as loss.

LTE / 5G

Endpoint roaming keeps the session alive across a carrier address change.

Microwave

Behaves like fibre right up until the weather arrives.

Wi-Fi / Ethernet

A re-enumerated USB radio is rebound without disturbing the other links.

Serial radio

PPP over an adapter's pseudo-terminal; a 64 kbps link is a first-class member. adapters ↗

the same bonded session, spread across whichever bearers are alive right now

Layer 05

Peers

The far side. Every node runs this identical stack — there is no controller and no server tier.

One bonded tunnel

All five bearers above carry the same encrypted session to the same peer. There is no failover event to observe, because there was never a single link to fail over from.

Direct sessions

Peers that can reach each other exchange fragments directly, on whichever bearer is cheapest at that instant, re-decided packet by packet.

Reachable at two hops

A peer with no path of its own is reached through a fleet member that has one. Forwarding is hop by hop: the middle node decrypts and re-encrypts, so a relay is a trusted member, not a blind pipe. Relayed traffic lives to 8 hops. mesh ↗

How to read it. Solid bands with a raised ground are inside the atlasd process; dashed bands are outside it and belong to the kernel, the hardware or another machine. Names in monospace are the actual crates and modules — nexus-atlas-core is the engine library, and the boxes marked opt-in do nothing at all until a configuration file asks for them.
Scope

What Atlas is not.

Three honest boundaries that save everyone a meeting.

Not a radio or a waveform

Atlas doesn’t transmit RF; it rides whatever presents IP/UDP and bonds it with everything else — including MANET radios, which keep their own PHY expertise. The radio stays the radio.

What it rides on

Not a mesh Wi-Fi product

802.11s is one possible underlay, not the product. Atlas is the layer above: measurement, crypto, per-packet choice, and multi-hop routing across dissimilar bearers. Guidance on combining the two honestly: the mesh page.

Not a VPN service

There is no Atlas cloud your traffic must visit. Hosted relays and gateways exist for reachability — opt-in, and just as happily replaced by relays you run yourself. How reachability works

Request an evaluation

Walk the same path with your own traffic.

An evaluation build, your links, and an afternoon: the packet lifecycle on this page becomes numbers in your own dashboard.