Skip to content

v0.7.0

Choose a tag to compare

@steeb-k steeb-k released this 31 Aug 21:24
· 16 commits to main since this release

Fixed

Android battery: the mesh no longer tunnels its own traffic through itself.

A phone reported 78% of a 13% battery drop with Nullgate merely running in the background. The cause turned out to be a routing loop rather than anything to do with pacing or wakelocks.

iroh advertises every non-loopback local interface address as a direct-address candidate — including our own tunnel's 10.99.0.x, which the interface enumeration has no reason to treat specially — and every member routes the whole 10.99.0.0/24. So a peer's virtual IP looked like a perfectly reachable UDP address, iroh scored it as a direct path (ranking it above the relay), and the mesh's own QUIC packets were routed into the mesh's own tunnel and re-sent over the connection they belonged to.

The loop feeds itself — every keepalive it carries is re-tunnelled — so it ratchets. On an idle desktop mesh it measured ~113 packets/second and ~1.5 MB/min (~2 GB/day), almost all of it relayed to the phone, keeping its radio out of idle around the clock. Two stray ICMP packets were enough to start it.

Three guards now, because the address leaks through QUIC NAT-traversal candidates that no iroh API filters:

  • the path selector never chooses a path into the virtual /24;
  • the tunnel pump drops packets sent from our own endpoint's bound ports, so the bogus path also starves and gets retired;
  • on Android the VpnService excludes Nullgate itself from Nullgate's own tunnel (the same thing Tailscale does).

This is strictly a connectivity improvement — it removes a fake path that iroh was preferring over the working one. The guards are per-device, so a given pair of peers stays affected until both ends are on 0.7.0.

Windows: opening the app can no longer leave a duplicate tray icon (or window).

Tray-agent and GUI uniqueness relied on GApplication, whose deduplication runs over GLib's autolaunched D-Bus session bus — and when that bus's published address goes stale, every launch silently becomes its own primary, so each "Open Nullgate" spawned another agent and another tray icon until the next logoff. Both roles now guard themselves with named kernel mutexes, and a second GUI launch signals a named event so the existing window comes forward.


Install: Windows — download the MSI matching your architecture. Linux/macOS — curl -fsSL https://raw.githubusercontent.com/steeb-k/nullgate/main/install.sh | sh. Android — the .apk asset (or via Obtainium).