`requester_id = 11` was added and removed in the same rebase batch, never
reached main, and never reached hbbs — whose vendored copy of this file still
stops at field 9. So nothing has ever written or read tag 11, and reserving it
guards a wire format that does not exist.
It was also inconsistent with what this branch already does: `IceCandidate`
retyped tag 2 from `string to_id` to `bytes socket_addr` in place, which is only
sound because none of this proto has shipped. Same premise, so tag 11 is free.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`next()` read every non-FRAG_END header as "more fragments", so a peer whose
framing had diverged was only caught by the MAX_FRAME_LENGTH cap — and a
FRAG_MORE carrying no payload was never caught at all: it adds nothing to the
accumulator, so the cap never trips and the loop spins for as long as the peer
keeps writing, with no error and no teardown. Decide the header's meaning in one
match, so a future header kind cannot be handled in one place and missed in the
other. Neither case is reachable from send_bytes_inner, which emits FRAG_MORE
only for a full MAX_FRAGMENT_PAYLOAD chunk.
Release the accumulator on the error paths rather than truncating it: at the cap
that is ~1 GiB still referenced through the SESSIONS clone.
Doc corrections, all of them overclaims in the previous pass:
- the cancel-safety entry held only for the successful read path.
read_data_channel does await after dequeuing on its ErrShortBuffer and DCEP
branches, and next() awaits pc.close() on its error paths — where
RTCPeerConnection::close latches is_closed before its first await, so a
cancelled close silently turns every later close into a no-op and leaves the
pc in SESSIONS.
- recv_state: cancellation drops the guard mid-message, so it is the
single-reader assumption, not the mutex, that ultimately keeps two readers
from splicing into one accumulator.
- is_relayed: stream.rs promised None before pair selection while webrtc.rs
documented Some(true) under Relay policy; align both.
- get_local_endpoint: examples/webrtc.rs calls it too, not only the tests.
- PunchHole.reserved 11: named the wrong writer — PunchHole is written by the
rendezvous server, not by peers. Reserve the name as well as the tag.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Rotating on age alone let a single day's file grow without limit, so whoever
can drive a hot log site decided how much disk this uses and no amount of
per-site throttling could bound it. Add a size criterion, which covers every
call site at once — including ones no throttle was added to.
LogThrottle: recover the guard on a poisoned lock rather than returning None.
Poisoning only means another thread panicked while holding it; the guarded
data is two counters that are still usable, and going silent for the rest of
the process is worse than a stale count. AGENTS.md permits handling lock
poisoning directly, and it forbids swallowing the error.
Keep map_or over clippy's is_none_or: that was stabilized in Rust 1.82 and CI
pins 1.75.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ
Debug output is written to the log file, so a log site that fires per received
message lets whoever is sending decide how much a machine writes to disk.
Dropping the line instead would hide real faults, so collapse it: one line per
interval carrying the count of everything suppressed since the last one, with
the first occurrence after a quiet period always reported so an isolated fault
is not delayed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExUfAkYbq8UC9pQCiLy8TQ
- Cargo.toml: record why webrtc is pinned to 0.13 — >=0.14 pulls sdp 0.10 /
webrtc-util 0.12 using usize::is_multiple_of (needs rustc >=1.87), while
rustdesk CI builds with Rust 1.75 (sciter i128 ABI pin)
- module-level upgrade checklist in src/webrtc.rs listing the version-coupled
webrtc-rs internals this transport relies on (SCTP write backpressure,
64KB message cap, detach() semantics, handler-capture leak cycle,
Disconnected transience, stats-based is_relayed), all verified against
webrtc 0.13 / webrtc-data 0.11 / webrtc-sctp 0.12
- send_bytes: document the bounded-backpressure mechanism (128 KiB PendingQueue
semaphore + cwnd/rwnd cap) and that it is NOT cancel-safe
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 1-byte-header fragmentation past the 64KB SCTP cap; empty-message and clean-EOF handling
- is_relayed() via selected candidate-pair stats for the direct/relayed flag
- IdPk.dtls_fingerprint + rendezvous webrtc SDP/IceCandidate proto fields
- fix pc leaks: Weak capture breaks the state-handler Arc self-cycle; close pc on new() error paths
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- add hide-recording-button to local settings
- add windows-service-video-save-directory to service settings
Signed-off-by: 21pages <sunboeasy@gmail.com>
Add ControlledContext to rendezvous messages so the server can pass a controller-user audit ref to the controlled client.
The controlled client returns the ref when posting audit logs, allowing the server to associate those logs with the controller user.
Signed-off-by: 21pages <sunboeasy@gmail.com>