tor-browser

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

mediapacket.cpp (3681B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mediapacket.h"
      8 
      9 #include <cstring>
     10 
     11 #include "ipc/IPCMessageUtils.h"
     12 
     13 namespace mozilla {
     14 
     15 void MediaPacket::Copy(const uint8_t* data, size_t len, size_t capacity) {
     16  if (capacity < len) {
     17    capacity = len;
     18  }
     19  data_.reset(new uint8_t[capacity]);
     20  len_ = len;
     21  capacity_ = capacity;
     22  memcpy(data_.get(), data, len);
     23 }
     24 
     25 MediaPacket::MediaPacket(const MediaPacket& orig)
     26    : sdp_level_(orig.sdp_level_), type_(orig.type_) {
     27  Copy(orig.data_.get(), orig.len_, orig.capacity_);
     28 }
     29 
     30 MediaPacket MediaPacket::Clone() const { return MediaPacket(*this); }
     31 
     32 void MediaPacket::Serialize(IPC::MessageWriter* aWriter) const {
     33  aWriter->WriteUInt32(len_);
     34  aWriter->WriteUInt32(capacity_);
     35  if (len_) {
     36    aWriter->WriteBytes(data_.get(), len_);
     37  }
     38  aWriter->WriteUInt32(encrypted_len_);
     39  if (encrypted_len_) {
     40    aWriter->WriteBytes(encrypted_data_.get(), encrypted_len_);
     41  }
     42  aWriter->WriteInt32(sdp_level_.isSome() ? *sdp_level_ : -1);
     43  aWriter->WriteInt32(type_);
     44 }
     45 
     46 bool MediaPacket::Deserialize(IPC::MessageReader* aReader) {
     47  Reset();
     48  uint32_t len;
     49  if (!aReader->ReadUInt32(&len)) {
     50    return false;
     51  }
     52  uint32_t capacity;
     53  if (!aReader->ReadUInt32(&capacity)) {
     54    return false;
     55  }
     56  if (len) {
     57    MOZ_RELEASE_ASSERT(capacity >= len);
     58    UniquePtr<uint8_t[]> data(new uint8_t[capacity]);
     59    if (!aReader->ReadBytesInto(data.get(), len)) {
     60      return false;
     61    }
     62    data_ = std::move(data);
     63    len_ = len;
     64    capacity_ = capacity;
     65  }
     66 
     67  if (!aReader->ReadUInt32(&len)) {
     68    return false;
     69  }
     70  if (len) {
     71    UniquePtr<uint8_t[]> data(new uint8_t[len]);
     72    if (!aReader->ReadBytesInto(data.get(), len)) {
     73      return false;
     74    }
     75    encrypted_data_ = std::move(data);
     76    encrypted_len_ = len;
     77  }
     78 
     79  int32_t sdp_level;
     80  if (!aReader->ReadInt32(&sdp_level)) {
     81    return false;
     82  }
     83 
     84  if (sdp_level >= 0) {
     85    sdp_level_ = Some(sdp_level);
     86  }
     87 
     88  int32_t type;
     89  if (!aReader->ReadInt32(&type)) {
     90    return false;
     91  }
     92  type_ = static_cast<Type>(type);
     93  return true;
     94 }
     95 
     96 static bool IsRtp(const uint8_t* data, size_t len) {
     97  if (len < 2) return false;
     98 
     99  // Check if this is a RTCP packet. Logic based on the types listed in
    100  // media/webrtc/trunk/src/modules/rtp_rtcp/source/rtp_utility.cc
    101 
    102  // Anything outside this range is RTP.
    103  if ((data[1] < 192) || (data[1] > 207)) return true;
    104 
    105  if (data[1] == 192)  // FIR
    106    return false;
    107 
    108  if (data[1] == 193)  // NACK, but could also be RTP. This makes us sad
    109    return true;       // but it's how webrtc.org behaves.
    110 
    111  if (data[1] == 194) return true;
    112 
    113  if (data[1] == 195)  // IJ.
    114    return false;
    115 
    116  if ((data[1] > 195) && (data[1] < 200))  // the > 195 is redundant
    117    return true;
    118 
    119  if ((data[1] >= 200) && (data[1] <= 207))  // SR, RR, SDES, BYE,
    120    return false;                            // APP, RTPFB, PSFB, XR
    121 
    122  MOZ_ASSERT(false);  // Not reached, belt and suspenders.
    123  return true;
    124 }
    125 
    126 void MediaPacket::Categorize() {
    127  SetType(MediaPacket::UNCLASSIFIED);
    128 
    129  if (!data_ || len_ < 4) {
    130    return;
    131  }
    132 
    133  if (data_[0] >= 20 && data_[0] <= 63) {
    134    // DTLS per RFC 7983
    135    SetType(MediaPacket::DTLS);
    136  } else if (data_[0] > 127 && data_[0] < 192) {
    137    // RTP/RTCP per RFC 7983
    138    if (IsRtp(data_.get(), len_)) {
    139      SetType(MediaPacket::SRTP);
    140    } else {
    141      SetType(MediaPacket::SRTCP);
    142    }
    143  }
    144 }
    145 }  // namespace mozilla