SetNetworkAvailable read IsOnline before updating netState without any
locking, so concurrent availability flips could interleave: a false call
could observe a stale offline state, skip MarkNetworkChange, and land
after a racing true call, leaving the client offline with unswept
connections. The netState and recorder updates could also apply out of
order, letting the listener state disagree with netState. On Android the
initial availability push at service start races the ConnectivityManager
callbacks, and iOS feeds the same manager from NWPathMonitor.
Hold a manager mutex across the check, sweep mark, state update and
recorder update so transitions apply atomically and in order.
Losing the last network only flipped the availability state: the dead
management, signal and relay sockets stayed silently connected until their
own timeouts, so the client kept reporting Connected with no network at all.
Introduce client/netevents with a Manager that ties the availability state,
the connection sweeper and the status recorder together, and move the
netstate and netsweep packages under it (netsweep renamed to sweep).
SetNetworkAvailable(false) now also sweeps the registered connections so
their owners redial and the listener reaches the NoNetwork state.
The Android and iOS bindings own a Manager instance and inject it through
the constructors; consumers hold the concrete *Manager whose nil zero value
reports always-online and never sweeps, with interfaces kept only as
parameter contracts. The relay guard settle wait moved into the Manager as
WaitSettled, removing the netevents import from the relay package.