tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

bye.cc (4779B)


      1 /*
      2 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
     12 
     13 #include <cstdint>
     14 #include <cstring>
     15 #include <string>
     16 #include <utility>
     17 #include <vector>
     18 
     19 #include "absl/strings/string_view.h"
     20 #include "modules/rtp_rtcp/source/byte_io.h"
     21 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
     22 #include "rtc_base/checks.h"
     23 #include "rtc_base/logging.h"
     24 
     25 namespace webrtc {
     26 namespace rtcp {
     27 // Bye packet (BYE) (RFC 3550).
     28 //
     29 //        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
     30 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     31 //       |V=2|P|    SC   |   PT=BYE=203  |             length            |
     32 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     33 //       |                           SSRC/CSRC                           |
     34 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     35 //       :                              ...                              :
     36 //       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
     37 // (opt) |     length    |               reason for leaving            ...
     38 //       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     39 Bye::Bye() = default;
     40 
     41 Bye::~Bye() = default;
     42 
     43 bool Bye::Parse(const CommonHeader& packet) {
     44  RTC_DCHECK_EQ(packet.type(), kPacketType);
     45 
     46  const uint8_t src_count = packet.count();
     47  // Validate packet.
     48  if (packet.payload_size_bytes() < 4u * src_count) {
     49    RTC_LOG(LS_WARNING)
     50        << "Packet is too small to contain CSRCs it promise to have.";
     51    return false;
     52  }
     53  const uint8_t* const payload = packet.payload();
     54  bool has_reason = packet.payload_size_bytes() > 4u * src_count;
     55  uint8_t reason_length = 0;
     56  if (has_reason) {
     57    reason_length = payload[4u * src_count];
     58    if (packet.payload_size_bytes() - 4u * src_count < 1u + reason_length) {
     59      RTC_LOG(LS_WARNING) << "Invalid reason length: " << reason_length;
     60      return false;
     61    }
     62  }
     63  // Once sure packet is valid, copy values.
     64  if (src_count == 0) {  // A count value of zero is valid, but useless.
     65    SetSenderSsrc(0);
     66    csrcs_.clear();
     67  } else {
     68    SetSenderSsrc(ByteReader<uint32_t>::ReadBigEndian(payload));
     69    csrcs_.resize(src_count - 1);
     70    for (size_t i = 1; i < src_count; ++i)
     71      csrcs_[i - 1] = ByteReader<uint32_t>::ReadBigEndian(&payload[4 * i]);
     72  }
     73 
     74  if (has_reason) {
     75    reason_.assign(reinterpret_cast<const char*>(&payload[4u * src_count + 1]),
     76                   reason_length);
     77  } else {
     78    reason_.clear();
     79  }
     80 
     81  return true;
     82 }
     83 
     84 bool Bye::Create(uint8_t* packet,
     85                 size_t* index,
     86                 size_t max_length,
     87                 PacketReadyCallback callback) const {
     88  while (*index + BlockLength() > max_length) {
     89    if (!OnBufferFull(packet, index, callback))
     90      return false;
     91  }
     92  const size_t index_end = *index + BlockLength();
     93 
     94  CreateHeader(1 + csrcs_.size(), kPacketType, HeaderLength(), packet, index);
     95  // Store srcs of the leaving clients.
     96  ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], sender_ssrc());
     97  *index += sizeof(uint32_t);
     98  for (uint32_t csrc : csrcs_) {
     99    ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], csrc);
    100    *index += sizeof(uint32_t);
    101  }
    102  // Store the reason to leave.
    103  if (!reason_.empty()) {
    104    uint8_t reason_length = static_cast<uint8_t>(reason_.size());
    105    packet[(*index)++] = reason_length;
    106    memcpy(&packet[*index], reason_.data(), reason_length);
    107    *index += reason_length;
    108    // Add padding bytes if needed.
    109    size_t bytes_to_pad = index_end - *index;
    110    RTC_DCHECK_LE(bytes_to_pad, 3);
    111    if (bytes_to_pad > 0) {
    112      memset(&packet[*index], 0, bytes_to_pad);
    113      *index += bytes_to_pad;
    114    }
    115  }
    116  RTC_DCHECK_EQ(index_end, *index);
    117  return true;
    118 }
    119 
    120 bool Bye::SetCsrcs(std::vector<uint32_t> csrcs) {
    121  if (csrcs.size() > kMaxNumberOfCsrcs) {
    122    RTC_LOG(LS_WARNING) << "Too many CSRCs for Bye packet.";
    123    return false;
    124  }
    125  csrcs_ = std::move(csrcs);
    126  return true;
    127 }
    128 
    129 void Bye::SetReason(absl::string_view reason) {
    130  RTC_DCHECK_LE(reason.size(), 0xffu);
    131  reason_ = std::string(reason);
    132 }
    133 
    134 size_t Bye::BlockLength() const {
    135  size_t src_count = (1 + csrcs_.size());
    136  size_t reason_size_in_32bits = reason_.empty() ? 0 : (reason_.size() / 4 + 1);
    137  return kHeaderLength + 4 * (src_count + reason_size_in_32bits);
    138 }
    139 
    140 }  // namespace rtcp
    141 }  // namespace webrtc