tor-browser

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

SipccSdp.cpp (5148B)


      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 "sdp/SipccSdp.h"
      8 
      9 #include <cstdlib>
     10 
     11 #include "mozilla/Assertions.h"
     12 #include "mozilla/UniquePtr.h"
     13 #include "sdp/SdpParser.h"
     14 
     15 #ifdef CRLF
     16 #  undef CRLF
     17 #endif
     18 #define CRLF "\r\n"
     19 
     20 namespace mozilla {
     21 
     22 SipccSdp::SipccSdp(const SipccSdp& aOrig)
     23    : mOrigin(aOrig.mOrigin),
     24      mBandwidths(aOrig.mBandwidths),
     25      mAttributeList(aOrig.mAttributeList, nullptr) {
     26  for (const auto& msection : aOrig.mMediaSections) {
     27    mMediaSections.emplace_back(
     28        new SipccSdpMediaSection(*msection, &mAttributeList));
     29  }
     30 }
     31 
     32 Sdp* SipccSdp::Clone() const { return new SipccSdp(*this); }
     33 
     34 const SdpOrigin& SipccSdp::GetOrigin() const { return mOrigin; }
     35 
     36 uint32_t SipccSdp::GetBandwidth(const std::string& type) const {
     37  auto found = mBandwidths.find(type);
     38  if (found == mBandwidths.end()) {
     39    return 0;
     40  }
     41  return found->second;
     42 }
     43 
     44 const SdpMediaSection& SipccSdp::GetMediaSection(size_t level) const {
     45  if (level > mMediaSections.size()) {
     46    MOZ_CRASH();
     47  }
     48  return *mMediaSections[level];
     49 }
     50 
     51 SdpMediaSection& SipccSdp::GetMediaSection(size_t level) {
     52  if (level > mMediaSections.size()) {
     53    MOZ_CRASH();
     54  }
     55  return *mMediaSections[level];
     56 }
     57 
     58 SdpMediaSection& SipccSdp::AddMediaSection(SdpMediaSection::MediaType mediaType,
     59                                           SdpDirectionAttribute::Direction dir,
     60                                           uint16_t port,
     61                                           SdpMediaSection::Protocol protocol,
     62                                           sdp::AddrType addrType,
     63                                           const std::string& addr) {
     64  size_t level = mMediaSections.size();
     65  SipccSdpMediaSection* media =
     66      new SipccSdpMediaSection(level, &mAttributeList);
     67  media->mMediaType = mediaType;
     68  media->mPort = port;
     69  media->mPortCount = 0;
     70  media->mProtocol = protocol;
     71  media->mConnection = MakeUnique<SdpConnection>(addrType, addr);
     72  media->GetAttributeList().SetAttribute(new SdpDirectionAttribute(dir));
     73  mMediaSections.emplace_back(media);
     74  return *media;
     75 }
     76 
     77 bool SipccSdp::LoadOrigin(sdp_t* sdp, InternalResults& results) {
     78  std::string username = sdp_get_owner_username(sdp);
     79  uint64_t sessId = strtoull(sdp_get_owner_sessionid(sdp), nullptr, 10);
     80  uint64_t sessVer = strtoull(sdp_get_owner_version(sdp), nullptr, 10);
     81 
     82  sdp_nettype_e type = sdp_get_owner_network_type(sdp);
     83  if (type != SDP_NT_INTERNET) {
     84    results.AddParseError(2, "Unsupported network type");
     85    return false;
     86  }
     87 
     88  sdp::AddrType addrType;
     89  switch (sdp_get_owner_address_type(sdp)) {
     90    case SDP_AT_IP4:
     91      addrType = sdp::kIPv4;
     92      break;
     93    case SDP_AT_IP6:
     94      addrType = sdp::kIPv6;
     95      break;
     96    default:
     97      results.AddParseError(2, "Unsupported address type");
     98      return false;
     99  }
    100 
    101  std::string address = sdp_get_owner_address(sdp);
    102  mOrigin = SdpOrigin(username, sessId, sessVer, addrType, address);
    103  return true;
    104 }
    105 
    106 bool SipccSdp::Load(sdp_t* sdp, InternalResults& results) {
    107  // Believe it or not, SDP_SESSION_LEVEL is 0xFFFF
    108  if (!mAttributeList.Load(sdp, SDP_SESSION_LEVEL, results)) {
    109    return false;
    110  }
    111 
    112  if (!LoadOrigin(sdp, results)) {
    113    return false;
    114  }
    115 
    116  if (!mBandwidths.Load(sdp, SDP_SESSION_LEVEL, results)) {
    117    return false;
    118  }
    119 
    120  for (int i = 0; i < sdp_get_num_media_lines(sdp); ++i) {
    121    // note that we pass a "level" here that is one higher
    122    // sipcc counts media sections from 1, using 0xFFFF as the "session"
    123    UniquePtr<SipccSdpMediaSection> section(
    124        new SipccSdpMediaSection(i, &mAttributeList));
    125    if (!section->Load(sdp, i + 1, results)) {
    126      return false;
    127    }
    128    mMediaSections.push_back(std::move(section));
    129  }
    130  return true;
    131 }
    132 
    133 void SipccSdp::Serialize(std::ostream& os) const {
    134  os << "v=0" << CRLF << mOrigin << "s=-" << CRLF;
    135 
    136  // We don't support creating i=, u=, e=, p=
    137  // We don't generate c= at the session level (only in media)
    138 
    139  mBandwidths.Serialize(os);
    140  os << "t=0 0" << CRLF;
    141 
    142  // We don't support r= or z=
    143 
    144  // attributes
    145  os << mAttributeList;
    146 
    147  // media sections
    148  for (const auto& msection : mMediaSections) {
    149    os << *msection;
    150  }
    151 }
    152 
    153 bool SipccSdpBandwidths::Load(sdp_t* sdp, uint16_t level,
    154                              InternalResults& results) {
    155  size_t count = sdp_get_num_bw_lines(sdp, level);
    156  for (size_t i = 1; i <= count; ++i) {
    157    sdp_bw_modifier_e bwtype = sdp_get_bw_modifier(sdp, level, i);
    158    uint32_t bandwidth = sdp_get_bw_value(sdp, level, i);
    159    if (bwtype != SDP_BW_MODIFIER_UNSUPPORTED) {
    160      const char* typeName = sdp_get_bw_modifier_name(bwtype);
    161      (*this)[typeName] = bandwidth;
    162    }
    163  }
    164 
    165  return true;
    166 }
    167 
    168 void SipccSdpBandwidths::Serialize(std::ostream& os) const {
    169  for (auto i = begin(); i != end(); ++i) {
    170    os << "b=" << i->first << ":" << i->second << CRLF;
    171  }
    172 }
    173 
    174 }  // namespace mozilla