The send and recv arms shared one counter, and an ICMP error on a connected
socket is reported once and then cleared — so the steady state is an
alternation: the send succeeds and clears the counter, the next recv reports
the error and finds the counter at 1, and logs. Every error still wrote a
line, at the ~100/s the previous commit set out to stop, while the
persistent-failure and recovery branches were unreachable.
Use one LogThrottle per direction instead of a hand-rolled counter. That
removes the shared state the bug lived in, drops a third throttling mechanism
in favour of the one already added, and leaves the surrounding `if let Err`
untouched rather than reshaping it into a match.
Also fix test_udp_uat's socket-error arm, the untreated twin of the punch_udp
site: it had no backoff at all, so a persistent error re-armed recv
immediately and spun the loop at CPU speed, one warn line per iteration.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ
Debug output goes to the log file, so a site that fires per received message
or per retry lets someone else decide how much a machine writes to disk. The
WebRTC work added the first such sites.
- KCP io loop: absorbing ICMP errors as packet loss made a broken socket write
~100 lines a second for the 60s until the pong timeout reaps it. Log by run
instead: one line when a run starts, one per ~5s while it persists so a stuck
socket stays visible, and one on recovery with the total.
- punch_udp: the recv error retries every 10ms for up to MAX_TIME, so one line
per occurrence wrote thousands per punch. Log the first, report the count in
the timeout message.
- ICE candidate paths (client, mediator): the peer sets the candidate rate and
the rendezvous route carrying them needs no prior punch, so throttle to one
line a minute each with the suppressed count.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ
- treat ICMP-driven UDP socket errors (WSAECONNRESET 10054 on Windows,
ECONNREFUSED on Linux) as packet loss in punch_udp and the KCP pump
instead of tearing the session down; KCP retransmits through them and a
truly dead link is still reaped by the pong/app-level timeouts
- resolve STUN hostnames via tokio::net::lookup_host so DNS never blocks a
runtime worker; fix the inverted non-IPv4 error message
- add enable-kcp-congestion-control option (default on): switch the turbo
profile to nc=0 so brief loss on constrained links no longer spirals into
stalls; sender-side only, no wire negotiation
- pin kcp-sys to the rustdesk-patches branch: upstream main lost the
RustDesk patches on the EasyTier sync, and this branch also wires
set_kcp_config_factory into connection setup, making the option effective
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>