diff --git a/worker/include/RTC/PipeConsumer.hpp b/worker/include/RTC/PipeConsumer.hpp index 39066f4140..5a3e646467 100644 --- a/worker/include/RTC/PipeConsumer.hpp +++ b/worker/include/RTC/PipeConsumer.hpp @@ -73,7 +73,8 @@ namespace RTC absl::flat_hash_map mapSsrcRtpStream; bool keyFrameSupported{ false }; absl::flat_hash_map mapRtpStreamSyncRequired; - absl::flat_hash_map> mapRtpStreamRtpSeqManager; + absl::flat_hash_map>> + mapRtpStreamRtpSeqManager; }; } // namespace RTC diff --git a/worker/include/RTC/SimulcastConsumer.hpp b/worker/include/RTC/SimulcastConsumer.hpp index fcce57adb4..70c328971c 100644 --- a/worker/include/RTC/SimulcastConsumer.hpp +++ b/worker/include/RTC/SimulcastConsumer.hpp @@ -115,7 +115,7 @@ namespace RTC bool syncRequired{ false }; int16_t spatialLayerToSync{ -1 }; bool lastSentPacketHasMarker{ false }; - RTC::SeqManager rtpSeqManager; + std::unique_ptr> rtpSeqManager; int16_t preferredSpatialLayer{ -1 }; int16_t preferredTemporalLayer{ -1 }; int16_t provisionalTargetSpatialLayer{ -1 }; diff --git a/worker/include/RTC/SvcConsumer.hpp b/worker/include/RTC/SvcConsumer.hpp index c61220293f..cb860709d6 100644 --- a/worker/include/RTC/SvcConsumer.hpp +++ b/worker/include/RTC/SvcConsumer.hpp @@ -100,7 +100,7 @@ namespace RTC std::vector rtpStreams; RTC::RtpStreamRecv* producerRtpStream{ nullptr }; bool syncRequired{ false }; - RTC::SeqManager rtpSeqManager; + std::unique_ptr> rtpSeqManager; int16_t preferredSpatialLayer{ -1 }; int16_t preferredTemporalLayer{ -1 }; int16_t provisionalTargetSpatialLayer{ -1 }; diff --git a/worker/src/RTC/PipeConsumer.cpp b/worker/src/RTC/PipeConsumer.cpp index cde4fbfc76..fa25ef885b 100644 --- a/worker/src/RTC/PipeConsumer.cpp +++ b/worker/src/RTC/PipeConsumer.cpp @@ -4,6 +4,7 @@ #include "RTC/PipeConsumer.hpp" #include "Logger.hpp" #include "MediaSoupErrors.hpp" +#include "Utils.hpp" #include "RTC/Codecs/Tools.hpp" namespace RTC @@ -264,7 +265,7 @@ namespace RTC // Packets with only padding are not forwarded. if (packet->GetPayloadLength() == 0) { - rtpSeqManager.Drop(packet->GetSequenceNumber()); + rtpSeqManager->Drop(packet->GetSequenceNumber()); #ifdef MS_RTC_LOGGER_RTP packet->logger.Dropped(RtcLogger::RtpPacket::DropReason::EMPTY_PAYLOAD); @@ -284,7 +285,7 @@ namespace RTC MS_DEBUG_TAG(rtp, "sync key frame received"); } - rtpSeqManager.Sync(packet->GetSequenceNumber() - 1); + rtpSeqManager->Sync(packet->GetSequenceNumber() - 1); syncRequired = false; } @@ -292,7 +293,7 @@ namespace RTC // Update RTP seq number and timestamp. uint16_t seq; - rtpSeqManager.Input(packet->GetSequenceNumber(), seq); + rtpSeqManager->Input(packet->GetSequenceNumber(), seq); // Save original packet fields. auto origSsrc = packet->GetSsrc(); @@ -680,7 +681,15 @@ namespace RTC this->mapMappedSsrcSsrc[consumableEncoding.ssrc] = encoding.ssrc; this->mapSsrcRtpStream[encoding.ssrc] = rtpStream; this->mapRtpStreamSyncRequired[rtpStream] = false; - this->mapRtpStreamRtpSeqManager[rtpStream]; + + // Let's chosee an initial output seq number between 1000 and 32768 to avoid + // libsrtp bug: + // https://github.com/versatica/mediasoup/issues/1437 + const uint16_t initialOutputSeq = + Utils::Crypto::GetRandomUInt(1000u, std::numeric_limits::max() / 2); + + this->mapRtpStreamRtpSeqManager[rtpStream].reset( + new RTC::SeqManager(initialOutputSeq)); } } diff --git a/worker/src/RTC/SimulcastConsumer.cpp b/worker/src/RTC/SimulcastConsumer.cpp index bc54bf3424..fcd60c1c5f 100644 --- a/worker/src/RTC/SimulcastConsumer.cpp +++ b/worker/src/RTC/SimulcastConsumer.cpp @@ -5,6 +5,7 @@ #include "DepLibUV.hpp" #include "Logger.hpp" #include "MediaSoupErrors.hpp" +#include "Utils.hpp" #include "RTC/Codecs/Tools.hpp" namespace RTC @@ -98,6 +99,14 @@ namespace RTC "%s codec not supported for simulcast", mediaCodec->mimeType.ToString().c_str()); } + // Let's chosee an initial output seq number between 1000 and 32768 to avoid + // libsrtp bug: + // https://github.com/versatica/mediasoup/issues/1437 + const uint16_t initialOutputSeq = + Utils::Crypto::GetRandomUInt(1000u, std::numeric_limits::max() / 2); + + this->rtpSeqManager.reset(new RTC::SeqManager(initialOutputSeq)); + RTC::Codecs::EncodingContext::Params params; params.spatialLayers = encoding.spatialLayers; @@ -802,7 +811,7 @@ namespace RTC // not have payload other than padding, then drop it. if (spatialLayer == this->currentSpatialLayer && packet->GetPayloadLength() == 0) { - this->rtpSeqManager.Drop(packet->GetSequenceNumber()); + this->rtpSeqManager->Drop(packet->GetSequenceNumber()); #ifdef MS_RTC_LOGGER_RTP packet->logger.Dropped(RtcLogger::RtpPacket::DropReason::EMPTY_PAYLOAD); @@ -951,7 +960,7 @@ namespace RTC // 'packet->GetSequenceNumber() -2' may increase SeqManager::base and // increase the output sequence number. // https://github.com/versatica/mediasoup/issues/408 - this->rtpSeqManager.Sync(packet->GetSequenceNumber() - (this->lastSentPacketHasMarker ? 1 : 2)); + this->rtpSeqManager->Sync(packet->GetSequenceNumber() - (this->lastSentPacketHasMarker ? 1 : 2)); this->encodingContext->SyncRequired(); @@ -1013,7 +1022,7 @@ namespace RTC // Rewrite payload if needed. Drop packet if necessary. if (!packet->ProcessPayload(this->encodingContext.get(), marker)) { - this->rtpSeqManager.Drop(packet->GetSequenceNumber()); + this->rtpSeqManager->Drop(packet->GetSequenceNumber()); #ifdef MS_RTC_LOGGER_RTP packet->logger.Dropped(RtcLogger::RtpPacket::DropReason::DROPPED_BY_CODEC); @@ -1032,7 +1041,7 @@ namespace RTC uint16_t seq; const uint32_t timestamp = packet->GetTimestamp() - this->tsOffset; - this->rtpSeqManager.Input(packet->GetSequenceNumber(), seq); + this->rtpSeqManager->Input(packet->GetSequenceNumber(), seq); // Save original packet fields. auto origSsrc = packet->GetSsrc(); @@ -1066,7 +1075,7 @@ namespace RTC // Process the packet. if (this->rtpStream->ReceivePacket(packet, sharedPacket)) { - if (this->rtpSeqManager.GetMaxOutput() == packet->GetSequenceNumber()) + if (this->rtpSeqManager->GetMaxOutput() == packet->GetSequenceNumber()) { this->lastSentPacketHasMarker = packet->HasMarker(); } diff --git a/worker/src/RTC/SvcConsumer.cpp b/worker/src/RTC/SvcConsumer.cpp index a2337b4f81..d5fb24d750 100644 --- a/worker/src/RTC/SvcConsumer.cpp +++ b/worker/src/RTC/SvcConsumer.cpp @@ -5,6 +5,7 @@ #include "DepLibUV.hpp" #include "Logger.hpp" #include "MediaSoupErrors.hpp" +#include "Utils.hpp" #include "RTC/Codecs/Tools.hpp" namespace RTC @@ -79,6 +80,14 @@ namespace RTC MS_THROW_TYPE_ERROR("%s codec not supported for svc", mediaCodec->mimeType.ToString().c_str()); } + // Let's chosee an initial output seq number between 1000 and 32768 to avoid + // libsrtp bug: + // https://github.com/versatica/mediasoup/issues/1437 + const uint16_t initialOutputSeq = + Utils::Crypto::GetRandomUInt(1000u, std::numeric_limits::max() / 2); + + this->rtpSeqManager.reset(new RTC::SeqManager(initialOutputSeq)); + RTC::Codecs::EncodingContext::Params params; params.spatialLayers = encoding.spatialLayers; @@ -681,7 +690,7 @@ namespace RTC // Packets with only padding are not forwarded. if (packet->GetPayloadLength() == 0) { - this->rtpSeqManager.Drop(packet->GetSequenceNumber()); + this->rtpSeqManager->Drop(packet->GetSequenceNumber()); #ifdef MS_RTC_LOGGER_RTP packet->logger.Dropped(RtcLogger::RtpPacket::DropReason::EMPTY_PAYLOAD); @@ -701,7 +710,7 @@ namespace RTC MS_DEBUG_TAG(rtp, "sync key frame received"); } - this->rtpSeqManager.Sync(packet->GetSequenceNumber() - 1); + this->rtpSeqManager->Sync(packet->GetSequenceNumber() - 1); this->encodingContext->SyncRequired(); this->syncRequired = false; @@ -715,7 +724,7 @@ namespace RTC if (!packet->ProcessPayload(this->encodingContext.get(), marker)) { - this->rtpSeqManager.Drop(packet->GetSequenceNumber()); + this->rtpSeqManager->Drop(packet->GetSequenceNumber()); #ifdef MS_RTC_LOGGER_RTP packet->logger.Dropped(RtcLogger::RtpPacket::DropReason::DROPPED_BY_CODEC); @@ -738,7 +747,7 @@ namespace RTC // Update RTP seq number and timestamp based on NTP offset. uint16_t seq; - this->rtpSeqManager.Input(packet->GetSequenceNumber(), seq); + this->rtpSeqManager->Input(packet->GetSequenceNumber(), seq); // Save original packet fields. auto origSsrc = packet->GetSsrc();