Files
netbird/client/internal
Zoltán Papp 48a1782b8b [client] Serialize iOS tunnel reconfiguration callbacks with a shared notifier
On iOS the tunnel reconfiguration (setTunnelNetworkSettings) was driven
from three independent Go paths without serialization: route prefix
updates via the route notifier's own delivery loop, interface IP/IPv6
set synchronously from the engine start goroutine, and DNS config
applied from the DNS apply chain through a separate Swift object. The
three sources mutated the shared Swift settings-manager state
concurrently and triggered overlapping updateTunnel() calls, losing or
half-applying route and DNS settings.

Introduce client/internal/tunnelnotifier: a single notifier that
implements both listener.NetworkChangeListener and dns.IosDnsManager,
queues all four callbacks (OnNetworkChanged, SetInterfaceIP,
SetInterfaceIPv6, ApplyDns) in one FIFO and delivers them one-by-one
from a single goroutine, so calls into Swift never overlap and arrive
in order. RunOniOS wraps the two Swift objects into the notifier and
closes it after the run loop exits.

The route notifier keeps its prefix dedup but delegates delivery to the
shared notifier instead of maintaining its own queue and loop; the
dedup check and the enqueue stay under one mutex so queue order matches
state-update order. Setting the interface IP becomes asynchronous,
which is safe: on iOS wgInterface.Create() only uses the TunFd, and the
FIFO preserves the IP -> routes/DNS relative order.

The package is build-tag free so the unit tests run on any platform
under -race. Android is unaffected: it receives all settings atomically
in one configureInterface call and serializes TUN rebuilds on a single
handler thread.
2026-07-23 15:14:00 +02:00
..