diff --git a/src/impl/sctptransport.cpp b/src/impl/sctptransport.cpp index d0057046d..0946d2542 100644 --- a/src/impl/sctptransport.cpp +++ b/src/impl/sctptransport.cpp @@ -88,6 +88,9 @@ void SctpTransport::Init() { usrsctp_init(0, SctpTransport::WriteCallback, SctpTransport::DebugCallback); usrsctp_sysctl_set_sctp_pr_enable(1); // Enable Partial Reliability Extension (RFC 3758) usrsctp_sysctl_set_sctp_ecn_enable(0); // Disable Explicit Congestion Notification +#ifndef SCTP_ACCEPT_ZERO_CHECKSUM + usrsctp_enable_crc32c_offload(); // We'll compute CRC32 only for outgoing packets +#endif #ifdef SCTP_DEBUG usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL); #endif @@ -267,13 +270,15 @@ 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. Therefore, there's no need - // to check CRC32c additionally when receiving. - // See https://datatracker.ietf.org/doc/html/draft-ietf-tsvwg-sctp-zero-checksum +#ifdef SCTP_ACCEPT_ZERO_CHECKSUM // not available in usrsctp v0.9.5.0 + // 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 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)); +#endif int rcvBuf = 0; socklen_t rcvBufLen = sizeof(rcvBuf); @@ -964,6 +969,15 @@ 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); +#ifndef SCTP_ACCEPT_ZERO_CHECKSUM + // 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); + } +#endif + // 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))