User-reported after the waiting-screen fix: "the animation keeps hanging."
Cause: RelayDialTcp used a BLOCKING connect() -- against a down/unreachable
operator each attempt froze the window thread for the OS SYN-retry window
(seconds), so the spinner ran only during the 2s sleep between attempts.
RelayDialTcp now connects NON-blocking and select()s in 100ms slices,
pumping the message loop + repainting the waiting screen every slice (both
in-flight and between retry attempts). The success path already returned a
non-blocking socket (FIONBIO), so caller semantics are unchanged; the other
dial sites (console dial, game-socket dial) inherit the smooth behavior.
Verified: 4 window captures at 400ms intervals during a dead-host dial all
differ in the spinner region (uniform diff energy == continuous animation)
and IsHungAppWindow reads false on every sample.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>