feat: WebRTC data-plane framing, DTLS binding, and pc-leak fixes

- 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>
This commit is contained in:
rustdesk
2026-07-22 11:17:30 +08:00
parent 1998a198ec
commit f98f3e8732
5 changed files with 494 additions and 85 deletions
+4 -2
View File
@@ -4,6 +4,8 @@ use tokio_util::codec::{Decoder, Encoder};
// Bound speculative allocation from untrusted frame headers.
const MAX_PREALLOCATED_PAYLOAD_LEN: usize = 256 * 1024;
/// Largest payload representable by the four-byte RustDesk frame header.
pub const MAX_FRAME_LENGTH: usize = 0x3FFF_FFFF;
#[derive(Debug, Clone, Copy)]
pub struct BytesCodec {
@@ -132,7 +134,7 @@ impl Encoder<Bytes> for BytesCodec {
let h = (data.len() << 2) as u32 | 0x2;
buf.put_u16_le((h & 0xFFFF) as u16);
buf.put_u8((h >> 16) as u8);
} else if data.len() <= 0x3FFFFFFF {
} else if data.len() <= MAX_FRAME_LENGTH {
buf.put_u32_le((data.len() << 2) as u32 | 0x3);
} else {
return Err(io::Error::new(io::ErrorKind::InvalidInput, "Overflow"));
@@ -290,7 +292,7 @@ mod tests {
fn decode_large_frame_header_caps_preallocation() {
let mut codec = BytesCodec::new();
let mut buf = BytesMut::new();
let n = 0x3FFFFFFFusize;
let n = MAX_FRAME_LENGTH;
const MAX_REASONABLE_CAPACITY: usize = MAX_PREALLOCATED_PAYLOAD_LEN * 4;
buf.put_u32_le((n << 2) as u32 | 0x3);