From 1800d9d71be4a8168bd2dd6cde23ca39946af17b Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 17 Aug 2020 11:30:28 +0800 Subject: [PATCH] RTC: Support empty RR, ignore it --- trunk/src/kernel/srs_kernel_error.hpp | 1 + trunk/src/kernel/srs_kernel_rtc_rtcp.cpp | 29 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index d4e1c9e3d..fb3a7f2b7 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -360,6 +360,7 @@ #define ERROR_RTC_NO_PUBLISHER 5029 #define ERROR_RTC_DUPLICATED_SSRC 5030 #define ERROR_RTC_NO_TRACK 5031 +#define ERROR_RTC_RTCP_EMPTY_RR 5032 /////////////////////////////////////////////////////// // GB28181 API error. diff --git a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp index 11b2b1806..d18d6186b 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtcp.cpp @@ -69,9 +69,10 @@ int SrsRtcpCommon::size() srs_error_t SrsRtcpCommon::decode_header(SrsBuffer *buffer) { - if(! buffer->require(sizeof(SrsRtcpHeader) + 4)) { + if (!buffer->require(sizeof(SrsRtcpHeader) + 4)) { return srs_error_new(ERROR_RTC_RTCP, "require %d", sizeof(SrsRtcpHeader) + 4); } + buffer->read_bytes((char*)(&header_), sizeof(SrsRtcpHeader)); header_.length = ntohs(header_.length); @@ -482,6 +483,7 @@ SrsRtcpRR::SrsRtcpRR(uint32_t sender_ssrc) header_.version = kRtcpVersion; header_.length = 7; ssrc_ = sender_ssrc; + memset(&rb_, 0, sizeof(SrsRtcpRB)); } SrsRtcpRR::~SrsRtcpRR() @@ -608,9 +610,15 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ return srs_error_wrap(err, "decode header"); } - if(header_.rc < 1) { - return err; + // @doc https://tools.ietf.org/html/rfc3550#section-6.4.2 + // An empty RR packet (RC = 0) MUST be put at the head of a compound + // RTCP packet when there is no data transmission or reception to + // report. e.g. {80 c9 00 01 00 00 00 01} + if(header_.rc == 0) { + return srs_error_new(ERROR_RTC_RTCP_EMPTY_RR, "rc=0"); } + + // TODO: FIXME: Security check for read. rb_.ssrc = buffer->read_4bytes(); rb_.fraction_lost = buffer->read_1bytes(); rb_.lost_packets = buffer->read_3bytes(); @@ -618,7 +626,8 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ rb_.jitter = buffer->read_4bytes(); rb_.lsr = buffer->read_4bytes(); rb_.dlsr = buffer->read_4bytes(); - + + // TODO: FIXME: Security check for read. if(header_.rc > 1) { char buf[1500]; buffer->read_bytes(buf, (header_.rc -1 ) * 24); @@ -1725,10 +1734,22 @@ srs_error_t SrsRtcpCompound::decode(SrsBuffer *buffer) } else { rtcp = new SrsRtcpCommon(); } + if(srs_success != (err = rtcp->decode(buffer))) { srs_freep(rtcp); + + // @doc https://tools.ietf.org/html/rfc3550#section-6.4.2 + // An empty RR packet (RC = 0) MUST be put at the head of a compound + // RTCP packet when there is no data transmission or reception to + // report. e.g. {80 c9 00 01 00 00 00 01} + if (ERROR_RTC_RTCP_EMPTY_RR == srs_error_code(err)) { + srs_freep(err); + continue; + } + return srs_error_wrap(err, "decode rtcp type=%u rc=%u", header->type, header->rc); } + rtcps_.push_back(rtcp); }