Files
umn/README.md
T
2026-08-31 16:44:54 -05:00

5.5 KiB

Ultra Mesh Network

Ultra Mesh Network is a small, user-space mesh for macOS. Every running laptop gets a stable IPv6-looking overlay address, discovers nearby nodes over regular Wi-Fi and Apple peer-to-peer Wi-Fi, and can relay encrypted traffic for nodes that are not directly connected.

It installs a narrowly routed IPv6 utun interface. Ordinary applications can reach live mesh nodes directly while existing logical streams, text commands, expose, and the SOCKS5 proxy remain available for compatibility.

Requirements and installation

  • macOS 14 or newer on a personally controlled laptop
  • Apple Command Line Tools with Swift 6
  • Wi-Fi enabled on both Macs

Copy this project to each laptop and run:

./scripts/test.sh
./scripts/install.sh
umn status
umn address

The installer builds locally, asks for administrator authorization once, installs a minimal root LaunchDaemon for utun and /128 route management, installs the scoped .mesh resolver, then starts umnd as a per-user LaunchAgent. Peer networking, keys, packet parsing, firewall state, and DNS remain in the unprivileged daemon. If prompted, allow local-network access. Identity and configuration live in ~/Library/Application Support/UltraMesh.

Use ./scripts/uninstall.sh to remove both daemons, the interface/routes, binaries, and installer-managed resolver. It deliberately preserves identity, aliases, and firewall configuration so reinstalling keeps the same mesh address.

Native IPv6

Set a local alias, then use standard applications without proxy settings:

umn alias set alice <mesh-address>
ping6 alice.mesh
ssh alice.mesh
curl http://alice.mesh:8080/
umn interface status

Only currently reachable, authenticated mesh addresses are installed as exact IPv6 /128 routes. The interface never installs a default route or a broad ULA prefix. The local DNS server listens on TCP and UDP 127.0.0.1:53535; /etc/resolver/mesh scopes only .mesh lookups to it. Aliases remain explicitly local and AAAA-only.

For development, run swift run umnd in one terminal and swift run umn status in another.

Text communication

On the receiving laptop:

umn address
umn firewall allow overlay 7000 --from any
umn text listen 7000

On the sender:

umn ping <receiver-mesh-address>
umn text send <receiver-mesh-address> 7000 "hello over the mesh"

Replace any with a specific mesh address to restrict the port. Opening a firewall port is not sufficient by itself: a local service must also be bound. When umn text listen exits, the binding disappears but the firewall rule remains.

Useful diagnostics:

umn peers
umn routes
umn firewall list
umn alias set alice <mesh-address>
umn ping alice.mesh

Aliases are stored locally and are not claimed network-wide.

HTTP and HTTPS

Run a local server and expose it on a logical mesh port:

# Host laptop
python3 -m http.server 8080 --bind 127.0.0.1
umn firewall allow overlay 80 --from any
umn expose 80 --to 127.0.0.1:8080

Start the client-side proxy:

umn alias set host <host-mesh-address>
umn proxy --listen 127.0.0.1:1080
curl --proxy socks5h://127.0.0.1:1080 http://host.mesh/

The proxy implements SOCKS5 CONNECT and binds only to loopback. A browser can use the same proxy after its SOCKS settings are pointed at 127.0.0.1:1080 with proxy-side DNS enabled.

HTTPS is passed through unchanged. The web server remains responsible for its TLS certificate, and a self-signed certificate will still produce the usual trust warning.

Design and current limits

  • Bonjour and Network.framework discover peers over infrastructure and Apple peer-to-peer Wi-Fi (includePeerToPeer). New routes recover automatically when an access-point path disappears while Wi-Fi remains enabled.
  • Signed link-state announcements and shortest-hop routing support multi-hop topologies. The implementation is bounded and tested for 32 live nodes and 16 hops.
  • Service payloads are authenticated and encrypted end-to-end with Curve25519, HKDF-SHA256, and ChaCha20-Poly1305. Relays see routing metadata but cannot read ports or content.
  • Streams use sequence numbers, acknowledgements, retransmission, and a 60-second recovery window. An active stream can continue after a route change if another path appears within that window.
  • The endpoint firewall permits outbound native connections and their bounded TCP/UDP return state. New inbound TCP/UDP flows require explicit rules such as umn firewall allow tcp 8080 --from any; logical services use overlay. ICMPv6 echo is rate-limited and related errors are admitted conservatively. Transit traffic is independent of endpoint rules.
  • Native packets are complete, signed, replay-protected IPv6 packets encrypted end-to-end. TCP retransmission and flow control are supplied by macOS; retransmissions use the current shortest-hop route.
  • IPv6 fragments, multicast, malformed packets, unsafe routing headers, and unsupported next headers are dropped. The native peer queue is bounded and control traffic takes priority.
  • Text is limited to 4 KiB. A logical stream is limited to 1 MiB total and the daemon supports at most 32 simultaneous streams.
  • There is no durable offline queue: a new operation with no live route fails immediately.
  • Membership is open. Identities are self-authenticating, but there is no global authority, revocation service, or Sybil resistance yet.
  • Apple peer-to-peer Wi-Fi works only between Apple devices. The documented mesh protocol is transport-independent so other bearers can be added later.

The on-wire details are in docs/protocol.md.