Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Development

Subnetra is written in pure Zig with zero third-party dependencies — only the standard library and raw syscalls via std.posix. This page covers building, testing, and the local integration harness.

Prerequisites

  • Zig 0.16.0 or later.
  • For the privileged integration harness: a Linux host (or the provided dev container) with /dev/net/tun and --privileged.

Build & test

# Native build (ReleaseSmall by default; -Doptimize=Debug for dev)
zig build

# Static cross-compile to each shipped target
zig build -Dtarget=x86_64-linux-musl     # amd64
zig build -Dtarget=aarch64-linux-musl    # arm64
zig build -Dtarget=arm-linux-musleabihf  # armv7 (hard float)
zig build -Dtarget=arm-linux-musleabi    # armv5 (soft float)

# Unit tests (must stay green before any commit)
zig build test

# Run the daemon
zig build run

Artifacts land in zig-out/bin/: subnetrad and subnetra.

Useful build steps

StepWhat it does
zig build testRun the unit tests
zig build vectorsPrint the wire-protocol conformance vectors (JSON) to stdout
zig build tools-testRun unit tests for the tools/ utilities
zig build tool:keygenBuild/run the per-link PSK generator
zig build tool:config-lintBuild/run the offline config validator
zig build tool:wire-decodeBuild/run the offline datagram inspector
zig build tool:mtu-probeBuild/run the end-to-end path-MTU prober

Project layout

PathPurpose
build.zig, build.zig.zonDual-binary build (daemon + control tool), static musl cross-compile; version single-sourced in .version
src/config.zigConfig parse + sanity checks
src/policy.zigCIDR longest-prefix match + lock-free RCU ActiveTree
src/crypto.zigChaCha20-Poly1305, monotonic nonce, anti-replay
src/reactor.zigWire header, egress dispatch, readiness reactor
src/peer.zigPer-peer endpoint + crypto registry
src/os/Comptime OS backend: linux.zig (epoll + /dev/net/tun), darwin.zig (poll(2) + utun), mod.zig (selector)
src/uds.zigControl socket + command tokenizer
src/stats.zigData-plane counters
src/netplan.zig--print-network-plan emitter
src/main.zig, src/subnetra.zigDaemon / control-tool entry points
tools/Out-of-tree helpers (never shipped in the daemon)
docs/Design docs, the normative protocol, deployment, and RFCs

Test-driven workflow

Pure logic ships with tests. The PRD’s acceptance tests include JSON/sanity checks, CIDR overlap/matching, RCU hot-swap safety, crypto invariance (ciphertext grows by exactly the 16-byte tag), and nonce-monotonic / anti-replay behavior. The wire protocol is pinned by known-answer vectors generated from the live code (zig build vectors) with a drift sentinel in zig build test.

Local integration testing (dev container)

The privileged hub-and-spoke harness is Linux-only, so a reproducible Linux container is provided under .devcontainer/. It is a development/test aid only — the shipped artifact stays a single static musl binary.

# Build the Linux toolchain image (Debian-slim + pinned Zig 0.16.0)
docker build -t subnetra-dev -f .devcontainer/Dockerfile .

# Run the integration / preflight harness
docker run --rm --privileged --device=/dev/net/tun \
    -v "$PWD":/workspace subnetra-dev test/integration/run.sh

test/integration/run.sh builds the binary, enforces the static-link and ≤ 512 KB constraints, smoke-runs the daemon, cross-builds the other musl arch, runs the unit tests, then runs a 3-node hub-and-spoke end-to-end test across network namespaces: real delivery spoke-A → Hub(relay) → spoke-B, on-wire encryption (no plaintext leak onto the underlay), a non-stalling RCU policy hot-update under load, honest drop counters, resilience under underlay loss (netem) with full recovery, and endpoint roaming / NAT remap.

For a throughput/PPS baseline, the sibling test/integration/bench.sh stands up the same star, builds -Doptimize=ReleaseFast (measurement only), and reads achieved pps / Gbps / hub-CPU% from each daemon’s own counters.

Contributing principles

Subnetra is governed by a strict operating contract (AGENT.md). In short: make surgical, goal-aligned changes; keep zig build test green; preserve the zero-dependency, single-threaded, allocation-free (data-plane), handshake-free invariants; and verify the binary still links statically and stays under the size budget before declaring a task done. See the Design Principles.