Exposed SCTP RTO and RTX settings

This commit is contained in:
Paul-Louis Ageneau
2021-05-20 14:06:44 +02:00
parent e91880141a
commit a9ca8b687b
4 changed files with 53 additions and 16 deletions

View File

@ -54,6 +54,11 @@ struct SctpSettings {
optional<size_t> maxBurst; // in MTUs optional<size_t> maxBurst; // in MTUs
optional<unsigned int> congestionControlModule; // 0: RFC2581, 1: HSTCP, 2: H-TCP, 3: RTCC optional<unsigned int> congestionControlModule; // 0: RFC2581, 1: HSTCP, 2: H-TCP, 3: RTCC
optional<std::chrono::milliseconds> delayedSackTime; 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); RTC_EXPORT void SetSctpSettings(SctpSettings s);

View File

@ -340,13 +340,18 @@ RTC_EXPORT void rtcCleanup(void);
// SCTP global settings // SCTP global settings
typedef struct { typedef struct {
int recvBufferSize; // in bytes, <= 0 means optimized default int recvBufferSize; // in bytes, <= 0 means optimized default
int sendBufferSize; // in bytes, <= 0 means optimized default int sendBufferSize; // in bytes, <= 0 means optimized default
int maxChunksOnQueue; // in chunks, <= 0 means optimized default int maxChunksOnQueue; // in chunks, <= 0 means optimized default
int initialCongestionWindow; // in MTUs, <= 0 means optimized default int initialCongestionWindow; // in MTUs, <= 0 means optimized default
int maxBurst; // in MTUs, 0 means optimized default, < 0 means disabled int maxBurst; // in MTUs, 0 means optimized default, < 0 means disabled
int congestionControlModule; // 0: RFC2581 (default), 1: HSTCP, 2: H-TCP, 3: RTCC 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
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; } rtcSctpSettings;
// Note: SCTP settings apply to newly-created PeerConnections only // Note: SCTP settings apply to newly-created PeerConnections only

View File

@ -1140,6 +1140,21 @@ int rtcSetSctpSettings(const rtcSctpSettings *settings) {
if (settings->delayedSackTimeMs > 0) if (settings->delayedSackTimeMs > 0)
s.delayedSackTime = std::chrono::milliseconds(settings->delayedSackTimeMs); s.delayedSackTime = std::chrono::milliseconds(settings->delayedSackTimeMs);
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)); SetSctpSettings(std::move(s));
return RTC_ERR_SUCCESS; return RTC_ERR_SUCCESS;
}); });

View File

@ -92,14 +92,6 @@ void SctpTransport::Init() {
usrsctp_init(0, &SctpTransport::WriteCallback, nullptr); usrsctp_init(0, &SctpTransport::WriteCallback, nullptr);
usrsctp_sysctl_set_sctp_pr_enable(1); // Enable Partial Reliability Extension (RFC 3758) 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_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) { void SctpTransport::SetSettings(const SctpSettings &s) {
@ -122,9 +114,29 @@ void SctpTransport::SetSettings(const SctpSettings &s) {
// See https://github.com/paullouisageneau/libdatachannel/issues/354 // See https://github.com/paullouisageneau/libdatachannel/issues/354
usrsctp_sysctl_set_sctp_default_cc_module(to_uint32(s.congestionControlModule.value_or(0))); 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( usrsctp_sysctl_set_sctp_delayed_sack_time_default(
to_uint32(s.delayedSackTime.value_or(20ms).count())); to_uint32(s.delayedSackTime.value_or(20ms).count()));
// RTO
usrsctp_sysctl_set_sctp_rto_min_default(
to_uint32(s.minRetransmitTimeout.value_or(1000ms).count()));
usrsctp_sysctl_set_sctp_rto_max_default(
to_uint32(s.maxRetransmitTimeout.value_or(10000ms).count()));
usrsctp_sysctl_set_sctp_rto_initial_default(
to_uint32(s.initialRetransmitTimeout.value_or(1000ms).count()));
usrsctp_sysctl_set_sctp_init_rto_max_default(
to_uint32(s.maxRetransmitTimeout.value_or(10000ms).count()));
// RTX
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() { void SctpTransport::Cleanup() {