Merge pull request #426 from paullouisageneau/sctp-rto-rtx

Expose more SCTP settings and reduce min RTO
This commit is contained in:
Paul-Louis Ageneau
2021-05-20 14:38:56 +02:00
committed by GitHub
4 changed files with 59 additions and 16 deletions

View File

@ -54,6 +54,11 @@ struct SctpSettings {
optional<size_t> maxBurst; // in MTUs
optional<unsigned int> congestionControlModule; // 0: RFC2581, 1: HSTCP, 2: H-TCP, 3: RTCC
optional<std::chrono::milliseconds> delayedSackTime;
optional<std::chrono::milliseconds> minRetransmitTimeout;
optional<std::chrono::milliseconds> maxRetransmitTimeout;
optional<std::chrono::milliseconds> initialRetransmitTimeout;
optional<unsigned int> maxRetransmitAttempts;
optional<std::chrono::milliseconds> heartbeatInterval;
};
RTC_EXPORT void SetSctpSettings(SctpSettings s);

View File

@ -346,7 +346,12 @@ typedef struct {
int initialCongestionWindow; // in MTUs, <= 0 means optimized default
int maxBurst; // in MTUs, 0 means optimized default, < 0 means disabled
int congestionControlModule; // 0: RFC2581 (default), 1: HSTCP, 2: H-TCP, 3: RTCC
int delayedSackTimeMs; // in msecs, <= 0 means optimized default
int delayedSackTimeMs; // in msecs, 0 means optimized default, < 0 means disabled
int minRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
int maxRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
int initialRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
int maxRetransmitAttempts; // number of retransmissions, <= 0 means optimized default
int heartbeatIntervalMs; // in msecs, <= 0 means optimized default
} rtcSctpSettings;
// Note: SCTP settings apply to newly-created PeerConnections only

View File

@ -1139,6 +1139,23 @@ int rtcSetSctpSettings(const rtcSctpSettings *settings) {
if (settings->delayedSackTimeMs > 0)
s.delayedSackTime = std::chrono::milliseconds(settings->delayedSackTimeMs);
else if (settings->delayedSackTimeMs < 0)
s.delayedSackTime = std::chrono::milliseconds(0);
if (settings->minRetransmitTimeoutMs > 0)
s.minRetransmitTimeout = std::chrono::milliseconds(settings->minRetransmitTimeoutMs);
if (settings->maxRetransmitTimeoutMs > 0)
s.maxRetransmitTimeout = std::chrono::milliseconds(settings->maxRetransmitTimeoutMs);
if (settings->initialRetransmitTimeoutMs > 0)
s.initialRetransmitTimeout = std::chrono::milliseconds(settings->initialRetransmitTimeoutMs);
if (settings->maxRetransmitAttempts > 0)
s.maxRetransmitAttempts = settings->maxRetransmitAttempts;
if (settings->heartbeatIntervalMs > 0)
s.heartbeatInterval = std::chrono::milliseconds(settings->heartbeatIntervalMs);
SetSctpSettings(std::move(s));
return RTC_ERR_SUCCESS;

View File

@ -92,14 +92,6 @@ void SctpTransport::Init() {
usrsctp_init(0, &SctpTransport::WriteCallback, nullptr);
usrsctp_sysctl_set_sctp_pr_enable(1); // Enable Partial Reliability Extension (RFC 3758)
usrsctp_sysctl_set_sctp_ecn_enable(0); // Disable Explicit Congestion Notification
usrsctp_sysctl_set_sctp_init_rtx_max_default(5);
usrsctp_sysctl_set_sctp_path_rtx_max_default(5);
usrsctp_sysctl_set_sctp_assoc_rtx_max_default(5); // single path
usrsctp_sysctl_set_sctp_rto_min_default(1 * 1000); // ms
usrsctp_sysctl_set_sctp_rto_max_default(10 * 1000); // ms
usrsctp_sysctl_set_sctp_rto_initial_default(1 * 1000); // ms
usrsctp_sysctl_set_sctp_init_rto_max_default(10 * 1000); // ms
usrsctp_sysctl_set_sctp_heartbeat_interval_default(10 * 1000); // ms
}
void SctpTransport::SetSettings(const SctpSettings &s) {
@ -122,9 +114,33 @@ void SctpTransport::SetSettings(const SctpSettings &s) {
// See https://github.com/paullouisageneau/libdatachannel/issues/354
usrsctp_sysctl_set_sctp_default_cc_module(to_uint32(s.congestionControlModule.value_or(0)));
// Reduce SACK delay to 20ms by default
// Reduce SACK delay to 20ms by default (the recommended default value from RFC 4960 is 200ms)
usrsctp_sysctl_set_sctp_delayed_sack_time_default(
to_uint32(s.delayedSackTime.value_or(20ms).count()));
// RTO settings
// RFC 2988 recommends a 1s min RTO, which is very high, but TCP on Linux has a 200ms min RTO
usrsctp_sysctl_set_sctp_rto_min_default(
to_uint32(s.minRetransmitTimeout.value_or(200ms).count()));
// Set only 10s as max RTO instead of 60s for shorter connection timeout
usrsctp_sysctl_set_sctp_rto_max_default(
to_uint32(s.maxRetransmitTimeout.value_or(10000ms).count()));
usrsctp_sysctl_set_sctp_init_rto_max_default(
to_uint32(s.maxRetransmitTimeout.value_or(10000ms).count()));
// Still set 1s as initial RTO
usrsctp_sysctl_set_sctp_rto_initial_default(
to_uint32(s.initialRetransmitTimeout.value_or(1000ms).count()));
// RTX settings
// 5 retransmissions instead of 8 to shorten the backoff for shorter connection timeout
auto maxRtx = to_uint32(s.maxRetransmitAttempts.value_or(5));
usrsctp_sysctl_set_sctp_init_rtx_max_default(maxRtx);
usrsctp_sysctl_set_sctp_assoc_rtx_max_default(maxRtx);
usrsctp_sysctl_set_sctp_path_rtx_max_default(maxRtx); // single path
// Heartbeat interval
usrsctp_sysctl_set_sctp_heartbeat_interval_default(
to_uint32(s.heartbeatInterval.value_or(10000ms).count()));
}
void SctpTransport::Cleanup() {