Fixed the distribution of RTCP packets regarding RTCP and RTCPFB packets

This commit is contained in:
Staz M
2020-11-01 03:01:24 -05:00
parent 3e70af915f
commit c0756aaa05
3 changed files with 85 additions and 19 deletions

View File

@ -171,6 +171,9 @@ public:
inline uint8_t reportCount() const { return _first & 0x0F; }
inline uint8_t payloadType() const { return _payloadType; }
inline uint16_t length() const { return ntohs(_length); }
inline size_t lengthInBytes() const {
return (1+length())*4;
}
inline void setPayloadType(uint8_t type) { _payloadType = type; }
inline void setReportCount(uint8_t count) { _first = (_first & 0b11100000u) | (count & 0b00011111u); }

View File

@ -124,7 +124,7 @@ bool DtlsSrtpTransport::sendMedia(message_ptr message) {
} else {
if (srtp_err_status_t err = srtp_protect(mSrtpOut, message->data(), &size)) {
if (err == srtp_err_status_replay_fail)
throw std::runtime_error("SRTP packet is a replay");
throw std::runtime_error("Outgoing SRTP packet is a replay");
else if (err == srtp_err_status_no_ctx) {
auto ssrc = ((RTP*) message->data())->ssrc();
PLOG_INFO << "Adding SSRC to RTP: " << ssrc;

View File

@ -549,31 +549,94 @@ void PeerConnection::forwardMedia(message_ptr message) {
if (!message)
return;
unsigned int ssrc = message->stream;
std::optional<string> mid = getMidFromSSRC(ssrc);
// Browsers like to compound their packets with a random SSRC.
// we have to do this monstrosity to distribute the report blocks
if (!mid && message->type == Message::Control) {
RTCP_RR* sr = (RTCP_RR*) message->data();
if (sr->isReceiverReport() ||sr->isSenderReport()) {
std::optional<string> mid;
if (message->type == Message::Control) {
unsigned int offset = 0;
std::vector<SSRC> ssrcsFound;
bool hasFound = false;
for (int i = 0; i < sr->header.reportCount(); i++) {
auto block = sr->getReportBlock(i);
auto ssrc = block->getSSRC();
auto mid = getMidFromSSRC(ssrc);
if (mid.has_value()) {
while ((sizeof(rtc::RTCP_HEADER) + offset) < message->size()) {
auto header = (rtc::RTCP_HEADER *) (message->data() + offset);
if (header->lengthInBytes() > message->size() - offset) {
PLOG_WARNING << "Packet was truncated";
break;
} else {
if (header->payloadType() == 205 || header->payloadType() == 206) {
auto rtcpfb = (RTCP_FB_HEADER*) header;
auto ssrc = rtcpfb->getPacketSenderSSRC();
mid = getMidFromSSRC(ssrc);
if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
hasFound = true;
std::shared_lock lock(mTracksMutex); // read-only
if (auto it = mTracks.find(*mid); it != mTracks.end())
if (auto track = it->second.lock())
if (auto it = mTracks.find(*mid); it != mTracks.end()) {
if (auto track = it->second.lock()) {
track->incoming(message);
break;
}
}
ssrcsFound.emplace_back(ssrc);
}
ssrc = rtcpfb->getMediaSourceSSRC();
mid = getMidFromSSRC(ssrc);
if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
hasFound = true;
std::shared_lock lock(mTracksMutex); // read-only
if (auto it = mTracks.find(*mid); it != mTracks.end()) {
if (auto track = it->second.lock()) {
track->incoming(message);
break;
}
}
ssrcsFound.emplace_back(ssrc);
}
}else if (header->payloadType() == 200 || header->payloadType() == 201) {
auto rtcpsr = (RTCP_SR*) header;
auto ssrc = rtcpsr->senderSSRC();
mid = getMidFromSSRC(ssrc);
if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
hasFound = true;
std::shared_lock lock(mTracksMutex); // read-only
if (auto it = mTracks.find(*mid); it != mTracks.end()) {
if (auto track = it->second.lock()) {
track->incoming(message);
break;
}
}
ssrcsFound.emplace_back(ssrc);
}
for (int i = 0; i < rtcpsr->header.reportCount(); i++) {
auto block = rtcpsr->getReportBlock(i);
ssrc = block->getSSRC();
mid = getMidFromSSRC(ssrc);
if (mid.has_value() && std::find(ssrcsFound.begin(), ssrcsFound.end(), ssrc) == ssrcsFound.end()) {
hasFound = true;
std::shared_lock lock(mTracksMutex); // read-only
if (auto it = mTracks.find(*mid); it != mTracks.end()) {
if (auto track = it->second.lock()) {
track->incoming(message);
break;
}
}
ssrcsFound.emplace_back(ssrc);
}
}
}else {
PLOG_WARNING << "Unknown packet type: " << header->payloadType();
}
}
offset += header->lengthInBytes();
}
if (hasFound)
return;
}
}
unsigned int ssrc = message->stream;
mid = getMidFromSSRC(ssrc);
if (!mid) {
/* TODO