From 810b7aef76a45fec78811170ec91b8ef1227b1f2 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Wed, 2 Sep 2026 11:26:07 +0800 Subject: [PATCH] webrtc: send over SCTP without a congestion window, as KCP does The same link that streams over KCP crawls over WebRTC. webrtc-sctp runs RFC 4960's AIMD: a fast retransmit halves cwnd, a T3 drops it to one MTU, and slow start only rebuilds it while data is queued behind it. Where the loss is random rather than congestion - a lossy long-haul link - the rate settles at the Mathis ceiling MSS/(RTT*sqrt(p)) however idle the link is: about 1.3 Mbps at 70ms RTT and 1% loss, 0.6 Mbps at 5%, while 1080p wants 2-5 Mbps. KCP's turbo profile (nc=1) has no congestion window at all. The fork now carries a switch that bypasses the two places gating sends on cwnd, and hbb_common turns it on for every peer connection unless `allow-webrtc-congestion-control` is set - the same opt-in KCP has in `allow-kcp-congestion-control`, for the reason at `get_kcp_cc_enabled`. Sender-side only; a browser or an older build on the other end interoperates. Measured over a simulated link (35ms one-way, random loss both ways, 12 KB frames at 30fps, 300 frames): at 1% loss the window stretches 9.9s of video to 20.7s with a mean latency of 5.5s; without it the stream stays realtime at a mean of 113ms. At 3%: 47s and 15s against 10.2s and 290ms. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns --- Cargo.lock | 4 ++-- Cargo.toml | 7 ++++--- libs/hbb_common | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc780fd72..40e4e6a7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9707,7 +9707,7 @@ dependencies = [ [[package]] name = "webrtc-sctp" version = "0.12.0" -source = "git+https://github.com/rustdesk-org/webrtc?rev=0a84ba37fbca940b82f230fb469d1b3a3172abf6#0a84ba37fbca940b82f230fb469d1b3a3172abf6" +source = "git+https://github.com/rustdesk-org/webrtc?rev=65fbe090326bf3abe8480d159b6bb07b5f509c22#65fbe090326bf3abe8480d159b6bb07b5f509c22" dependencies = [ "arc-swap", "async-trait", @@ -9747,7 +9747,7 @@ dependencies = [ [[package]] name = "webrtc-util" version = "0.11.0" -source = "git+https://github.com/rustdesk-org/webrtc?rev=0a84ba37fbca940b82f230fb469d1b3a3172abf6#0a84ba37fbca940b82f230fb469d1b3a3172abf6" +source = "git+https://github.com/rustdesk-org/webrtc?rev=65fbe090326bf3abe8480d159b6bb07b5f509c22#65fbe090326bf3abe8480d159b6bb07b5f509c22" dependencies = [ "async-trait", "bitflags 1.3.2", diff --git a/Cargo.toml b/Cargo.toml index 5bfc27293..5dbaffb23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -220,10 +220,11 @@ libxdo-sys = { path = "libs/libxdo-sys-stub" } # one comes out byte-swapped, fails to bind, and ICE gathers no IPv6 host candidate on Windows. # webrtc-sctp: RFC 4960's 1s RTO floor makes a single loss cost 1-3s on a link whose RTT is 24-64ms, # and fast retransmit cannot cover a request/response exchange; INITIAL_MTU 1228 also fragments on -# IPv6. The fork commit carries the arithmetic. +# IPv6; and its AIMD pins a lossy long-haul link to MSS/(RTT*sqrt(p)), so a switch sends without +# a congestion window, as KCP does - on by default, `allow-webrtc-congestion-control` opts back in. # Pinned by rev, not branch: a fork branch can be rewritten out from under the lockfile. -webrtc-util = { git = "https://github.com/rustdesk-org/webrtc", rev = "0a84ba37fbca940b82f230fb469d1b3a3172abf6" } -webrtc-sctp = { git = "https://github.com/rustdesk-org/webrtc", rev = "0a84ba37fbca940b82f230fb469d1b3a3172abf6" } +webrtc-util = { git = "https://github.com/rustdesk-org/webrtc", rev = "65fbe090326bf3abe8480d159b6bb07b5f509c22" } +webrtc-sctp = { git = "https://github.com/rustdesk-org/webrtc", rev = "65fbe090326bf3abe8480d159b6bb07b5f509c22" } [package.metadata.winres] LegalCopyright = "Copyright © 2026 Purslane Tech Pte. Ltd. All rights reserved." diff --git a/libs/hbb_common b/libs/hbb_common index 31d378907..846daf86f 160000 --- a/libs/hbb_common +++ b/libs/hbb_common @@ -1 +1 @@ -Subproject commit 31d3789079cfc382d81ee611fe114579de90d3aa +Subproject commit 846daf86f0e77bc8a0cc323b5bab2267431f8d04