When the portable Monitor creates a winMon via newOSMon, we register
address and route change callbacks with Windows. Once a callback is hit,
it starts a goroutine that attempts to send the event into messagec and returns.
The newly started goroutine then blocks until it can send to the channel.
However, if the monitor is never started and winMon.Receive is never called,
the goroutines remain indefinitely blocked, leading to goroutine leaks and
significant memory consumption in the tailscaled service process on Windows.
Unlike the tailscaled subprocess, the service process creates but never starts
a Monitor.
This PR adds a check within the callbacks to confirm the monitor's active status,
and exits immediately if the monitor hasn't started.
Updates #9864
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this commit, we have updated the build process for our Windows DLLs
to link statically with libgcc, ensuring our Windows DLLs are self-contained.
Updates #10617
Signed-off-by: Nick Khyl <nickk@tailscale.com>