From 283488d78959ba211df71480cbe3734212209179 Mon Sep 17 00:00:00 2001 From: melpon Date: Tue, 24 Oct 2023 15:44:11 +0900 Subject: [PATCH 1/2] Implements SCTP zero checksum --- include/rtc/configuration.hpp | 3 +++ src/impl/sctptransport.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/rtc/configuration.hpp b/include/rtc/configuration.hpp index feb34abbe..8ad694aa8 100644 --- a/include/rtc/configuration.hpp +++ b/include/rtc/configuration.hpp @@ -86,6 +86,9 @@ struct RTC_CPP_EXPORT Configuration { // Local maximum message size for Data Channels optional maxMessageSize; + + // SCTP settings + bool sctpZeroChecksum = false; }; } // namespace rtc diff --git a/src/impl/sctptransport.cpp b/src/impl/sctptransport.cpp index de3865d2b..ae9bc1d46 100644 --- a/src/impl/sctptransport.cpp +++ b/src/impl/sctptransport.cpp @@ -284,6 +284,16 @@ SctpTransport::SctpTransport(shared_ptr lower, const Configuration &c throw std::runtime_error("Could not disable SCTP fragmented interleave, errno=" + std::to_string(errno)); + // When using SCTP over DTLS, the data integrity is ensured by DTLS, so there's no need to + // additionally compute CRC32c. + // See https://datatracker.ietf.org/doc/html/draft-ietf-tsvwg-sctp-zero-checksum + if (config.sctpZeroChecksum) { + int on = 1; + if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_ACCEPT_ZERO_CHECKSUM, &on, sizeof(on))) + throw std::runtime_error("Could set socket option SCTP_ACCEPT_ZERO_CHECKSUM, errno=" + + std::to_string(errno)); + } + int rcvBuf = 0; socklen_t rcvBufLen = sizeof(rcvBuf); if (usrsctp_getsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &rcvBuf, &rcvBufLen)) From b450b7680c5e616177839972bbb1cbcbbf7eedfd Mon Sep 17 00:00:00 2001 From: melpon Date: Thu, 26 Oct 2023 02:54:00 +0900 Subject: [PATCH 2/2] Disable crc32 offloading and remove zero checksum option. --- include/rtc/configuration.hpp | 3 --- src/impl/sctptransport.cpp | 22 ++++++---------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/include/rtc/configuration.hpp b/include/rtc/configuration.hpp index 8ad694aa8..feb34abbe 100644 --- a/include/rtc/configuration.hpp +++ b/include/rtc/configuration.hpp @@ -86,9 +86,6 @@ struct RTC_CPP_EXPORT Configuration { // Local maximum message size for Data Channels optional maxMessageSize; - - // SCTP settings - bool sctpZeroChecksum = false; }; } // namespace rtc diff --git a/src/impl/sctptransport.cpp b/src/impl/sctptransport.cpp index ae9bc1d46..83704e986 100644 --- a/src/impl/sctptransport.cpp +++ b/src/impl/sctptransport.cpp @@ -102,7 +102,6 @@ SctpTransport::InstancesSet *SctpTransport::Instances = new InstancesSet; void SctpTransport::Init() { usrsctp_init(0, SctpTransport::WriteCallback, SctpTransport::DebugCallback); - usrsctp_enable_crc32c_offload(); // We'll compute CRC32 only for outgoing packets usrsctp_sysctl_set_sctp_pr_enable(1); // Enable Partial Reliability Extension (RFC 3758) usrsctp_sysctl_set_sctp_ecn_enable(0); // Disable Explicit Congestion Notification #ifdef SCTP_DEBUG @@ -284,15 +283,13 @@ SctpTransport::SctpTransport(shared_ptr lower, const Configuration &c throw std::runtime_error("Could not disable SCTP fragmented interleave, errno=" + std::to_string(errno)); - // When using SCTP over DTLS, the data integrity is ensured by DTLS, so there's no need to - // additionally compute CRC32c. + // When using SCTP over DTLS, the data integrity is ensured by DTLS. Therefore, there's no need + // to check CRC32c additionally when receiving. // See https://datatracker.ietf.org/doc/html/draft-ietf-tsvwg-sctp-zero-checksum - if (config.sctpZeroChecksum) { - int on = 1; - if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_ACCEPT_ZERO_CHECKSUM, &on, sizeof(on))) - throw std::runtime_error("Could set socket option SCTP_ACCEPT_ZERO_CHECKSUM, errno=" + - std::to_string(errno)); - } + int edmid = SCTP_EDMID_LOWER_LAYER_DTLS; + if (usrsctp_setsockopt(mSock, IPPROTO_SCTP, SCTP_ACCEPT_ZERO_CHECKSUM, &edmid, sizeof(edmid))) + throw std::runtime_error("Could set socket option SCTP_ACCEPT_ZERO_CHECKSUM, errno=" + + std::to_string(errno)); int rcvBuf = 0; socklen_t rcvBufLen = sizeof(rcvBuf); @@ -970,13 +967,6 @@ void SctpTransport::UpcallCallback(struct socket *, void *arg, int /* flags */) int SctpTransport::WriteCallback(void *ptr, void *data, size_t len, uint8_t tos, uint8_t set_df) { auto *transport = static_cast(ptr); - // Set the CRC32 ourselves as we have enabled CRC32 offloading - if (len >= 12) { - uint32_t *checksum = reinterpret_cast(data) + 2; - *checksum = 0; - *checksum = usrsctp_crc32c(data, len); - } - // Workaround for sctplab/usrsctp#405: Send callback is invoked on already closed socket // https://github.com/sctplab/usrsctp/issues/405 if (auto locked = Instances->lock(transport))