netstate

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MPL-2.0 Imports: 15 Imported by: 0

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

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

func (m *Manager) ClientRoutesActive() bool

ClientRoutesActive reports whether gateway client routes are currently installed.

func (*Manager) ControlFunc

func (m *Manager) ControlFunc() func(network, address string, c syscall.RawConn) error

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

func (m *Manager) DisableClientRoutes() error

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

func (m *Manager) DisableServerNAT() error

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

func (m *Manager) EnableClientRoutes(tunIfName string) error

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

func (m *Manager) EnableServerNAT(awlSubnet, tunIfName string) error

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

func (m *Manager) ServerNATActive() bool

ServerNATActive reports whether the exit-node NAT is currently configured.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context) error

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.)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL