Traversal & relays

Reachability becomes another measured path.

The traversal stack adopted STUN, replaced TURN with an Atlas-native relay, and replaced ICE with rendezvous over that relay — so a relayed path and a punched direct path are just links in the bond, scheduled like everything else. This page is the mechanics; the managed service around them lives at nexusatlas.net.

Opt-in ([traversal], default off)Hosted relays live · EU + NA
The whole sequence

Watch two NATs open — and one that won’t.

Relayed, then rendezvous, then direct. The beat worth waiting for is the third: the punched path is not a mode and not a new link — it is wwan0, the underlay link that was already there, with its endpoint for this peer discovered at runtime. From that instant the ordinary probe loop measures it and the ordinary scheduler ranks it, beside the relay that carried the tunnel until then. All of it is opt-in: [traversal] enabled defaults to false, and with it off no netcheck task is spawned at all.

Two nodes, two NATs — relayed, then direct, then the pair that stays relayedSimulation
Phase
Mapping behaviour at NAT-B

One mapping serves every destination, so the public address netcheck read off the relay is the address node A can aim at. Both ends sort their candidate lists by the same total order — server-reflexive first, then host, then by address — which is what makes them try the same pair at the same moment. Without that agreement two nodes can trade candidates forever and still never have their packets cross.

relay-eulink carrying the traffic
74 msend-to-end RTT
1 linklinks in the bond
netcheck: NAT-B mapping
What you’re watching: a simulation of the real sequence — netcheck out of the link’s own socket, candidates carried as a rendezvous payload inside the relay session both ends already hold, then a trial in which the candidate is written into the link’s per-peer endpoint slot. The timings and addresses are invented for legibility; the mechanism, the vocabulary and both outcomes are the daemon’s. The relay is never torn down — after a successful punch it simply loses on score and stays warm.
From the data socket

STUN out of the same 5-tuple

Each underlay link probes the STUN servers out of its own socket — the mapping discovered is the mapping data gets, not the mapping some separate test socket got. Results (public endpoints + RFC 4787 classification per link) land in the stats sidecar, GET /api/netcheck, and atlasd status.

Two IPs, always

Why every relay answers STUN on two addresses

Distinguishing endpoint-independent from address-dependent mapping requires replies from two different server IPs — two ports on one IP cannot do it. Every Nexus Atlas relay carries two public IPv4 addresses and answers STUN on both, so one relay is a complete observation pair. Config validation rejects single-IP STUN lists for exactly this reason.

Ordinary member

[[link]] type = "relay" — probed, scored, scheduled

Peer traffic rides encrypted envelopes addressed to the peer’s static key through a relay server — but the link is otherwise ordinary: its own socket, its own probes, its own RTT in the same scheduler. That is what lets the bond hold a relayed path and a direct path at once and shift between them without any reconnect. Peers need no endpoint on a relay link: identity is the public key; addresses are discovered at runtime.

66 bytes

Envelope overhead, accounted for globally

Adding any relay link shrinks the global fragment payload by the 66-byte envelope so relayed datagrams never exceed the path MTU. And a relay link sharing a modem with a direct link needs its own listen_port — otherwise SO_REUSEPORT silently load-balances the two sockets against each other; validation catches it.

Under a second

Outbound-only bring-up

A node behind carrier-grade NAT becomes reachable through its relay session in under a second, with no inbound rule and no public IP — the relay session both ends already hold doubles as the rendezvous channel for everything that follows.

Rendezvous

Candidates over the relay you already share

Peers exchange server-reflexive and local candidates through the established relay session — no signalling service exists or is needed — then aim at each other simultaneously. The crossing probes open both NATs.

Not a new link

A punched path is a discovered endpoint

The punch writes the peer’s public endpoint into an existing configured link’s slot for that peer. The probe loop then probes it out of that link’s socket, a probe-ack returns, the monitor marks it alive with a real RTT, and it enters the scheduler beside the relay path — which stays in the bond as a warm standby. The relay→direct switchover is an ordinary scheduler decision; a failed punch costs nothing.

Measured

Proven behind two CGNATs

The namespace harness builds two daemons each behind its own stateful NAT (with real latency — zero-delay namespaces let connection tracking steal the port tuple and deadlock any punch): tunnel up via relay, correct NAT classification, direct path punched under endpoint-independent mapping, relay-only under endpoint-dependent mapping (the CGNAT case), traffic never dropping across the transition.

Signed map

Ed25519 discovery with rollback rejection

A relay link that omits its server resolves it from a relay map signed by an offline key whose public half is compiled into the daemon — HTTPS is transport, not trust. Clients verify, cache the last good map on disk, and reject older signed maps as rollbacks: a compromised control plane can’t forge membership, and a directory outage never becomes a tunnel outage. Static per-link config always wins over discovery.

Shipped

Relay auto-election, make-before-break

Each end STUN-sweeps its relay candidates, advertises its RTT vector to the peer over the relay control channel, and both independently compute the same deterministic joint ranking — cost = max(my leg, your leg), hash tie-break — converging on the same shared relay set with no negotiation. Exactly relay_paths sessions stay active; failure re-elects the next-best on both sides with a grace overlap. Hardware-verified: with a punched direct path up, killing both relays cost 0% loss over 123 seconds — relays are warm standbys, not the path. Measured

The relay itself

One binary, zero disk state

nexus-atlas-relay: STUN on both public addresses, a session registry keyed by client static keys, opaque-envelope forwarding with per-session crypto, keepalives that hold the NAT binding, and session telemetry to the control plane. It authenticates clients; it cannot read the tunneled payload it forwards.

Gateways & exits

When the far end is the internet itself.

Relays make two of your nodes reachable. Hosted gateways are the other case: an Atlas daemon you terminate a bonded tunnel on — published in a second signed map (same offline key, its own canonical form and expiry, so neither map can impersonate the other), with region, endpoints, co-located STUN addresses and a coarse load hint.

Live today Live service

Hosted gateway + relay locations in the EU (Germany) and North America (Canada), verified end-to-end from a phone: listed with live RTT (32 ms / 125 ms from Sofia), selected, Noise session up, both bonded links at 0% probe loss. Measured

Full-tunnel exit

A gateway can carry the whole device: default route through the bond, NAT at the gateway’s side, DNS pinned through the tunnel — the “reach the internet through a bonded exit” mode the Android wizard configures.

Self-publish

Gateways self-register and heartbeat through a registry sidecar reading the daemon’s stats snapshot; publication requires outside-in STUN verification, and a dead or firewalled gateway un-publishes itself. Private estates simply stay out of the public map. The service → nexusatlas.net

The metadata boundary

What a hosted relay can and cannot see.

“Encrypted” is not a substitute for a precise boundary. Here it is.

A relay observes

  • Outer source addresses and ports
  • Authenticated node identities (static public keys)
  • Session timing, liveness and forwarded byte counts

A relay cannot observe

  • Inner IP packets or application payloads
  • Video, sensor or command content
  • Anything requiring the tunnel’s keys — it holds none of them
Scope note: this boundary is the hosted traversal model. Multi-hop mesh forwarding through your own fleet is a different mode with per-hop re-encryption by trusted member nodes — stated precisely on the security page, because your review will ask.
Request an evaluation

Behind CGNAT is not offline.

Two nodes, two carrier NATs, zero port forwarding: reachable in under a second, direct when the NATs allow it. Bring your worst SIM.