docs/vpnhotspotd/README.md
vpnhotspotd is the root-side daemon used by VPNHotspot intended for all long-running background root-side work, including but not limited to routing state, DNS proxying, neighbour monitoring, and IPv6 NAT mode.
The split is designed this way since root-side JVM daemon is much more expensive and should be avoided as much as possible.
These docs describe the daemon's internal ownership model and cleanup invariants.
IPC documentations not included and should refer to mobile/src/main/proto/daemon.proto.
control.rs owns the
daemon control loop, active calls, event-style (kotlin Flow) calls that
remain active for sessions or monitors, session slots, neighbour monitor
slot, and process-wide shared runtimes.session.rs
composes one session for one downstream interface from DNS, optional NAT66,
and routing runtimes.routing.rs and
routing/ own
reversible route, rule, address, firewall, forwarding, and static-address
mutations.nat66/ owns the IPv6
NAT proxy runtimes and helper protocol state.dns.rs owns the daemon
DNS listeners and Android resolver handoff.traffic.rs owns
daemon traffic-counter reads and the daemon-to-Kotlin counter reporting
boundary.netlink.rs owns the
shared rtnetlink connection, notifications, and single-consumer event slots.neighbour.rs
converts netlink neighbour and bridge topology state into daemon events.ipsec.rs owns the
optional Android 12+ IPsec forwarding-policy probe and emits session events
for the Kotlin routing owner to perform the hidden Netd write only when
needed.report.rs and
shared/protocol.rs
build structured daemon reports.The Kotlin side of the same subsystem lives under
mobile/src/main/java/be/mygod/vpnhotspot/root/daemon/.
Kotlin starts the binary, frames control messages, owns call IDs, and turns
daemon reports into app-visible exceptions or nonfatal warnings.
lifecycle.md: daemon startup, control-loop ownership, call
lifetime, session lifetime, cancellation, and shutdown.routing.md: desired routing state, reversible mutations,
Clean behavior, and system mutation ownership.nat66.md: IPv6 NAT runtime boundaries for TCP, UDP, ICMPv6,
router advertisements, marks, and cleanup.dns.md: DNS listener ownership, resolver handoff, config snapshot
semantics, and nonblocking assumptions.traffic.md: MAC-facing traffic accounting, blocking scope,
counter sources, recorder chain boundaries, and persistence mapping.errors.md: terminal errors, nonfatal reports, context/detail
requirements, and background-task failure policy.invariants.md: cross-module ownership, interception,
cleanup, configuration, error, and platform-assumption rules.Keep these docs in sync with daemon behavior. A change to
mobile/src/main/rust/vpnhotspotd, mobile/src/main/proto/daemon.proto, or
the Kotlin daemon controller should update docs/vpnhotspotd when it changes
internal ownership, lifecycle, cleanup, NAT66, DNS, routing, neighbour
monitoring, or error-reporting semantics.
Do not summarize away external side effects. If a change adds, removes, or changes any mutation to kernel, netfilter, netd, resolver, socket, file descriptor, process, or Android system state, the relevant doc must name:
For routing changes, routing.md is a mutation catalog. Every
route, policy rule, address, iptables/ip6tables rule or chain, ndc request,
and Clean mutation must be listed there.
If a daemon-adjacent change does not affect those documented contracts, say so
in the change description or final response. Do not duplicate the protobuf
schema here; update daemon.proto comments if the wire-level contract itself
needs documentation.
Platform and compatibility assumptions that affect the public app contract stay
in the root README.md, especially the Other and
System/root command assumptions sections. These daemon docs may link to those
assumptions, but should not create a second compatibility index.