| Index: webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
|
| index 4e37cf3716d916c7ecb1bfd6185b1790dfa15f5f..47a63315acb39ed1122af69ace7c41fe34788d03 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtcp_utility.cc
|
| @@ -14,6 +14,10 @@
|
| #include <math.h> // ceil
|
| #include <string.h> // memcpy
|
|
|
| +#include "webrtc/base/checks.h"
|
| +#include "webrtc/base/logging.h"
|
| +#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
| +
|
| namespace webrtc {
|
|
|
| namespace RTCPUtility {
|
| @@ -155,43 +159,40 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
|
| {
|
| for (;;)
|
| {
|
| - RTCPCommonHeader header;
|
| -
|
| - const bool success = RTCPParseCommonHeader(_ptrRTCPData,
|
| - _ptrRTCPDataEnd,
|
| - header);
|
| + RtcpCommonHeader header;
|
| + if (_ptrRTCPDataEnd <= _ptrRTCPData)
|
| + return;
|
|
|
| - if (!success)
|
| - {
|
| + if (!RtcpParseCommonHeader(_ptrRTCPData, _ptrRTCPDataEnd - _ptrRTCPData,
|
| + &header)) {
|
| return;
|
| }
|
| - _ptrRTCPBlockEnd = _ptrRTCPData + header.LengthInOctets;
|
| + _ptrRTCPBlockEnd = _ptrRTCPData + header.BlockSize();
|
| if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd)
|
| {
|
| // Bad block!
|
| return;
|
| }
|
|
|
| - switch (header.PT)
|
| - {
|
| + switch (header.packet_type) {
|
| case PT_SR:
|
| {
|
| // number of Report blocks
|
| - _numberOfBlocks = header.IC;
|
| + _numberOfBlocks = header.count_or_format;
|
| ParseSR();
|
| return;
|
| }
|
| case PT_RR:
|
| {
|
| // number of Report blocks
|
| - _numberOfBlocks = header.IC;
|
| + _numberOfBlocks = header.count_or_format;
|
| ParseRR();
|
| return;
|
| }
|
| case PT_SDES:
|
| {
|
| // number of SDES blocks
|
| - _numberOfBlocks = header.IC;
|
| + _numberOfBlocks = header.count_or_format;
|
| const bool ok = ParseSDES();
|
| if (!ok)
|
| {
|
| @@ -202,7 +203,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
|
| }
|
| case PT_BYE:
|
| {
|
| - _numberOfBlocks = header.IC;
|
| + _numberOfBlocks = header.count_or_format;
|
| const bool ok = ParseBYE();
|
| if (!ok)
|
| {
|
| @@ -214,7 +215,7 @@ RTCPUtility::RTCPParserV2::IterateTopLevel()
|
| case PT_IJ:
|
| {
|
| // number of Report blocks
|
| - _numberOfBlocks = header.IC;
|
| + _numberOfBlocks = header.count_or_format;
|
| ParseIJ();
|
| return;
|
| }
|
| @@ -410,20 +411,16 @@ RTCPUtility::RTCPParserV2::IterateAppItem()
|
| void
|
| RTCPUtility::RTCPParserV2::Validate()
|
| {
|
| - if (_ptrRTCPData == NULL)
|
| - {
|
| - return; // NOT VALID
|
| - }
|
| + if (_ptrRTCPData == nullptr)
|
| + return; // NOT VALID
|
|
|
| - RTCPCommonHeader header;
|
| - const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin,
|
| - _ptrRTCPDataEnd,
|
| - header);
|
| + RtcpCommonHeader header;
|
| + if (_ptrRTCPDataEnd <= _ptrRTCPDataBegin)
|
| + return; // NOT VALID
|
|
|
| - if (!success)
|
| - {
|
| - return; // NOT VALID!
|
| - }
|
| + if (!RtcpParseCommonHeader(_ptrRTCPDataBegin,
|
| + _ptrRTCPDataEnd - _ptrRTCPDataBegin, &header))
|
| + return; // NOT VALID!
|
|
|
| // * if (!reducedSize) : first packet must be RR or SR.
|
| //
|
| @@ -437,8 +434,7 @@ RTCPUtility::RTCPParserV2::Validate()
|
|
|
| if (!_RTCPReducedSizeEnable)
|
| {
|
| - if ((header.PT != PT_SR) && (header.PT != PT_RR))
|
| - {
|
| + if ((header.packet_type != PT_SR) && (header.packet_type != PT_RR)) {
|
| return; // NOT VALID
|
| }
|
| }
|
| @@ -458,48 +454,74 @@ RTCPUtility::RTCPParserV2::EndCurrentBlock()
|
| _ptrRTCPData = _ptrRTCPBlockEnd;
|
| }
|
|
|
| -bool
|
| -RTCPUtility::RTCPParseCommonHeader( const uint8_t* ptrDataBegin,
|
| - const uint8_t* ptrDataEnd,
|
| - RTCPCommonHeader& parsedHeader)
|
| -{
|
| - if (!ptrDataBegin || !ptrDataEnd)
|
| - {
|
| - return false;
|
| - }
|
| -
|
| - // 0 1 2 3
|
| - // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
| - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| - // |V=2|P| IC | PT | length |
|
| - // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| - //
|
| - // Common header for all RTCP packets, 4 octets.
|
| +// 0 1 2 3
|
| +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
| +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| +// |V=2|P| IC | PT | length |
|
| +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
| +//
|
| +// Common header for all RTCP packets, 4 octets.
|
| +
|
| +bool RTCPUtility::RtcpParseCommonHeader(const uint8_t* packet,
|
| + size_t size_bytes,
|
| + RtcpCommonHeader* parsed_header) {
|
| + DCHECK(parsed_header != nullptr);
|
| + if (size_bytes < RtcpCommonHeader::kHeaderSizeBytes) {
|
| + LOG(LS_WARNING) << "Too little data (" << size_bytes << " byte"
|
| + << (size_bytes != 1 ? "s" : "")
|
| + << ") remaining in buffer to parse RTCP header (4 bytes).";
|
| + return false;
|
| + }
|
|
|
| - if ((ptrDataEnd - ptrDataBegin) < 4)
|
| - {
|
| - return false;
|
| - }
|
| + const uint8_t kRtcpVersion = 2;
|
| + uint8_t version = packet[0] >> 6;
|
| + if (version != kRtcpVersion) {
|
| + LOG(LS_WARNING) << "Invalid RTCP header: Version must be "
|
| + << static_cast<int>(kRtcpVersion) << " but was "
|
| + << static_cast<int>(version);
|
| + return false;
|
| + }
|
|
|
| - parsedHeader.V = ptrDataBegin[0] >> 6;
|
| - parsedHeader.P = ((ptrDataBegin[0] & 0x20) == 0) ? false : true;
|
| - parsedHeader.IC = ptrDataBegin[0] & 0x1f;
|
| - parsedHeader.PT = ptrDataBegin[1];
|
| + bool has_padding = (packet[0] & 0x20) != 0;
|
| + uint8_t format = packet[0] & 0x1F;
|
| + uint8_t packet_type = packet[1];
|
| + size_t packet_size_words =
|
| + ByteReader<uint16_t>::ReadBigEndian(&packet[2]) + 1;
|
|
|
| - parsedHeader.LengthInOctets = (ptrDataBegin[2] << 8) + ptrDataBegin[3] + 1;
|
| - parsedHeader.LengthInOctets *= 4;
|
| + if (size_bytes < packet_size_words * 4) {
|
| + LOG(LS_WARNING) << "Buffer too small (" << size_bytes
|
| + << " bytes) to fit an RtcpPacket of " << packet_size_words
|
| + << " 32bit words.";
|
| + return false;
|
| + }
|
|
|
| - if(parsedHeader.LengthInOctets == 0)
|
| - {
|
| - return false;
|
| + size_t payload_size = packet_size_words * 4;
|
| + size_t padding_bytes = 0;
|
| + if (has_padding) {
|
| + if (payload_size <= RtcpCommonHeader::kHeaderSizeBytes) {
|
| + LOG(LS_WARNING) << "Invalid RTCP header: Padding bit set but 0 payload "
|
| + "size specified.";
|
| + return false;
|
| }
|
| - // Check if RTP version field == 2
|
| - if (parsedHeader.V != 2)
|
| - {
|
| - return false;
|
| +
|
| + padding_bytes = packet[payload_size - 1];
|
| + if (RtcpCommonHeader::kHeaderSizeBytes + padding_bytes > payload_size) {
|
| + LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes ("
|
| + << padding_bytes << ") for a packet size of "
|
| + << payload_size << "bytes.";
|
| + return false;
|
| }
|
| + payload_size -= padding_bytes;
|
| + }
|
| + payload_size -= RtcpCommonHeader::kHeaderSizeBytes;
|
|
|
| - return true;
|
| + parsed_header->version = kRtcpVersion;
|
| + parsed_header->count_or_format = format;
|
| + parsed_header->packet_type = packet_type;
|
| + parsed_header->payload_size_bytes = payload_size;
|
| + parsed_header->padding_bytes = padding_bytes;
|
| +
|
| + return true;
|
| }
|
|
|
| bool
|
| @@ -1137,10 +1159,9 @@ bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType(
|
| return false;
|
| }
|
|
|
| -bool
|
| -RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
|
| -{
|
| - assert((header.PT == PT_RTPFB) || (header.PT == PT_PSFB)); // Parser logic check
|
| +bool RTCPUtility::RTCPParserV2::ParseFBCommon(const RtcpCommonHeader& header) {
|
| + assert((header.packet_type == PT_RTPFB) ||
|
| + (header.packet_type == PT_PSFB)); // Parser logic check
|
|
|
| const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
|
|
|
| @@ -1162,12 +1183,10 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
|
| mediaSSRC += *_ptrRTCPData++ << 8;
|
| mediaSSRC += *_ptrRTCPData++;
|
|
|
| - if (header.PT == PT_RTPFB)
|
| - {
|
| + if (header.packet_type == PT_RTPFB) {
|
| // Transport layer feedback
|
|
|
| - switch (header.IC)
|
| - {
|
| + switch (header.count_or_format) {
|
| case 1:
|
| {
|
| // NACK
|
| @@ -1222,12 +1241,9 @@ RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
|
| }
|
| EndCurrentBlock();
|
| return false;
|
| - }
|
| - else if (header.PT == PT_PSFB)
|
| - {
|
| + } else if (header.packet_type == PT_PSFB) {
|
| // Payload specific feedback
|
| - switch (header.IC)
|
| - {
|
| + switch (header.count_or_format) {
|
| case 1:
|
| // PLI
|
| _packetType = RTCPPacketTypes::kPsfbPli;
|
| @@ -1579,9 +1595,7 @@ RTCPUtility::RTCPParserV2::ParseFIRItem()
|
| return true;
|
| }
|
|
|
| -bool
|
| -RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
|
| -{
|
| +bool RTCPUtility::RTCPParserV2::ParseAPP(const RtcpCommonHeader& header) {
|
| ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
|
|
|
| if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet
|
| @@ -1606,7 +1620,7 @@ RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
|
|
|
| _packetType = RTCPPacketTypes::kApp;
|
|
|
| - _packet.APP.SubType = header.IC;
|
| + _packet.APP.SubType = header.count_or_format;
|
| _packet.APP.Name = name;
|
|
|
| _state = ParseState::State_AppItem;
|
| @@ -1651,37 +1665,31 @@ RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData,
|
| RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
|
| }
|
|
|
| -const RTCPUtility::RTCPCommonHeader*
|
| -RTCPUtility::RTCPPacketIterator::Begin()
|
| -{
|
| +const RTCPUtility::RtcpCommonHeader* RTCPUtility::RTCPPacketIterator::Begin() {
|
| _ptrBlock = _ptrBegin;
|
|
|
| return Iterate();
|
| }
|
|
|
| -const RTCPUtility::RTCPCommonHeader*
|
| -RTCPUtility::RTCPPacketIterator::Iterate()
|
| -{
|
| - const bool success = RTCPParseCommonHeader(_ptrBlock, _ptrEnd, _header);
|
| - if (!success)
|
| - {
|
| - _ptrBlock = NULL;
|
| - return NULL;
|
| - }
|
| - _ptrBlock += _header.LengthInOctets;
|
| +const RTCPUtility::RtcpCommonHeader*
|
| +RTCPUtility::RTCPPacketIterator::Iterate() {
|
| + if ((_ptrEnd <= _ptrBlock) ||
|
| + !RtcpParseCommonHeader(_ptrBlock, _ptrEnd - _ptrBlock, &_header)) {
|
| + _ptrBlock = nullptr;
|
| + return nullptr;
|
| + }
|
| + _ptrBlock += _header.BlockSize();
|
|
|
| - if (_ptrBlock > _ptrEnd)
|
| - {
|
| - _ptrBlock = NULL;
|
| - return NULL;
|
| - }
|
| + if (_ptrBlock > _ptrEnd) {
|
| + _ptrBlock = nullptr;
|
| + return nullptr;
|
| + }
|
|
|
| - return &_header;
|
| + return &_header;
|
| }
|
|
|
| -const RTCPUtility::RTCPCommonHeader*
|
| -RTCPUtility::RTCPPacketIterator::Current()
|
| -{
|
| +const RTCPUtility::RtcpCommonHeader*
|
| +RTCPUtility::RTCPPacketIterator::Current() {
|
| if (!_ptrBlock)
|
| {
|
| return NULL;
|
|
|