sctp: dcsctp: Manage lifecycle explicitly
Prior to this commit, the SCTP association could terminate due to too
many retransmission attempts when there is a long duration of packet
loss. The RTCPeerConnection wouldn't terminate, and when the network
later recovers (possibly using a different ICE candidate), it would be a
RTCPeerConnection with media, but without DataChannels.
This commit will make the dcSCTP library never abort by itself when
there are too many retransmissions. It will also put a cap on the retry
duration so that it will do a retry every three seconds (or lower).
Bug: webrtc:13129
Change-Id: I08162ea20d6a60aa0eae2717966d9a2ddba8fc22
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/232540
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35061}
diff --git a/media/sctp/dcsctp_transport.cc b/media/sctp/dcsctp_transport.cc
index 49cb4ef..b6038b2 100644
--- a/media/sctp/dcsctp_transport.cc
+++ b/media/sctp/dcsctp_transport.cc
@@ -37,6 +37,13 @@
namespace {
using ::dcsctp::SendPacketStatus;
+// When there is packet loss for a long time, the SCTP retry timers will use
+// exponential backoff, which can grow to very long durations and when the
+// connection recovers, it may take a long time to reach the new backoff
+// duration. By limiting it to a reasonable limit, the time to recover reduces.
+constexpr dcsctp::DurationMs kMaxTimerBackoffDuration =
+ dcsctp::DurationMs(3000);
+
enum class WebrtcPPID : dcsctp::PPID::UnderlyingType {
// https://www.rfc-editor.org/rfc/rfc8832.html#section-8.1
kDCEP = 50,
@@ -156,6 +163,10 @@
options.local_port = local_sctp_port;
options.remote_port = remote_sctp_port;
options.max_message_size = max_message_size;
+ options.max_timer_backoff_duration = kMaxTimerBackoffDuration;
+ // Don't close the connection automatically on too many retransmissions.
+ options.max_retransmissions = absl::nullopt;
+ options.max_init_retransmits = absl::nullopt;
std::unique_ptr<dcsctp::PacketObserver> packet_observer;
if (RTC_LOG_CHECK_LEVEL(LS_VERBOSE)) {