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)) {