Documentation
¶
Overview ¶
Package netstate owns the platform-specific OS network state behind AWL's VPN gateway feature:
- Socket marking: keeps libp2p and SOCKS5 exit-node traffic out of the VPN tunnel so gateway mode cannot loop it back into itself. Linux: SO_MARK + ip-rule policy routing. Android: VpnService.protect() callback supplied by the host app. Windows: IP_UNICAST_IF binding to the physical uplink NIC. Other platforms: no-op.
- Client-side gateway routes: the TUN default route plus the IPv6 fail-closed fence.
- Server-side exit-node NAT: forwarding, address translation and the LAN/CGNAT isolation filter.
- Uplink detection (Windows): picking the physical interface carrying the best default route, shared by socket marking and server NAT.
All of it is owned by a single Manager instance. Manager is a per-platform type: each GOOS slice (manager_linux.go, manager_windows.go, manager_android.go, manager_other.go) declares its own struct with the same method set, so the shared state behind marking, routes and NAT lives under one lock per platform. The cross-platform contract is the method set itself, enforced by the compiler through the consumer-declared interfaces (awl.NetManager is the full union; service.NetManager and service.SocketMarker are subsets).
The Application creates the Manager (NewManager, or NewAndroidManager on Android), starts it once per process and feeds its ControlFunc to the libp2p host config; the gateway service applies and reverts the client routes / server NAT through it at runtime.
Index ¶
- type Manager
- func (m *Manager) ClientRoutesActive() bool
- func (m *Manager) ControlFunc() func(network, address string, c syscall.RawConn) error
- func (m *Manager) DisableClientRoutes() error
- func (m *Manager) DisableServerNAT() error
- func (m *Manager) EnableClientRoutes(tunIfName string) error
- func (m *Manager) EnableServerNAT(awlSubnet, tunIfName string) error
- func (m *Manager) ServerNATActive() bool
- func (m *Manager) Start(ctx context.Context) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the Linux OS network state behind AWL's VPN gateway feature: the always-on socket marking (SO_MARK, applied via ControlFunc), the runtime state of gateway mode — the client routes and the server NAT — and the route-change monitor (started by Start, alive for the whole process) that keeps the client routes' exemption table in sync with the live host defaults.
Enable/Disable methods are idempotent and safe for concurrent use. The internal mutex only guards the Manager's own state; the orchestration above (service.VPNGateway) still serialises whole enable/disable transactions — config, tunnel binding, DNS and the calls here — under its own lock. The monitor's reconcile takes the same mutex, which is what makes it exclusive with Enable/Disable transitions.
func NewManager ¶
func NewManager() *Manager
NewManager returns the Manager for Linux. Setting SO_MARK requires CAP_NET_ADMIN, which AWL already needs for TUN setup, so no extra capability is required.
func (*Manager) ClientRoutesActive ¶
ClientRoutesActive reports whether gateway client routes are currently installed.
func (*Manager) ControlFunc ¶
ControlFunc returns a function compatible with net.Dialer.Control and the QUIC ListenUDP override, marking each new socket with SO_MARK so its traffic bypasses the VPN tunnel via the fwmark ip rule.
func (*Manager) DisableClientRoutes ¶
DisableClientRoutes removes the gateway client routes. Idempotent; a no-op when they are not installed. The state is dropped even if the OS teardown reports errors (partial leftovers are recovered by the stale-cleanup on the next enable), so a failure here never wedges the gateway in half-enabled.
func (*Manager) DisableServerNAT ¶
DisableServerNAT reverses EnableServerNAT. Idempotent; a no-op when NAT is not configured. Like DisableClientRoutes, the state is dropped even on teardown errors.
func (*Manager) EnableClientRoutes ¶
EnableClientRoutes installs the gateway client routes on the TUN (the default-route capture plus the IPv6 fail-closed fence). Idempotent: a second call while routes are installed is a no-op.
func (*Manager) EnableServerNAT ¶
EnableServerNAT configures the exit-node data path for the awl subnet (ip_forward + iptables chain + MASQUERADE). Idempotent: a second call while NAT is configured is a no-op.
func (*Manager) ServerNATActive ¶
ServerNATActive reports whether the exit-node NAT is currently configured.
func (*Manager) Start ¶
Start launches the route-change monitor goroutine, which keeps the tableID exemption copies in sync with the live host default(s) for the whole process lifetime (see runRouteMonitor); it exits when ctx is cancelled. Socket marking itself needs no lifecycle here: SO_MARK is interpreted by the kernel per packet, so unlike Windows there is no per-socket state to keep in sync with the network.
Always returns nil: the monitor is best-effort staleness tracking — the gateway works without it — so a subscribe failure is retried in the background forever rather than surfaced. (Contrast with Windows, where Start fails Init on a callback-registration error: there the notifications drive socket marking itself, which never recovers without them.)