tor-browser

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

turn_utils.cc (4507B)


      1 /*
      2 *  Copyright (c) 2016 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 "media/base/turn_utils.h"
     12 
     13 #include <cstddef>
     14 #include <cstdint>
     15 
     16 #include "api/transport/stun.h"
     17 #include "rtc_base/byte_order.h"
     18 
     19 namespace webrtc {
     20 
     21 namespace {
     22 
     23 const size_t kTurnChannelHeaderLength = 4;
     24 
     25 bool IsTurnChannelData(const uint8_t* data, size_t length) {
     26  return length >= kTurnChannelHeaderLength && ((*data & 0xC0) == 0x40);
     27 }
     28 
     29 bool IsTurnSendIndicationPacket(const uint8_t* data, size_t length) {
     30  if (length < kStunHeaderSize) {
     31    return false;
     32  }
     33 
     34  uint16_t type = GetBE16(data);
     35  return (type == TURN_SEND_INDICATION);
     36 }
     37 
     38 }  // namespace
     39 
     40 bool UnwrapTurnPacket(const uint8_t* packet,
     41                      size_t packet_size,
     42                      size_t* content_position,
     43                      size_t* content_size) {
     44  if (IsTurnChannelData(packet, packet_size)) {
     45    // Turn Channel Message header format.
     46    //   0                   1                   2                   3
     47    //  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
     48    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     49    // |         Channel Number        |            Length             |
     50    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     51    // |                                                               |
     52    // /                       Application Data                        /
     53    // /                                                               /
     54    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     55    size_t length = GetBE16(&packet[2]);
     56    if (length + kTurnChannelHeaderLength > packet_size) {
     57      return false;
     58    }
     59 
     60    *content_position = kTurnChannelHeaderLength;
     61    *content_size = length;
     62    return true;
     63  }
     64 
     65  if (IsTurnSendIndicationPacket(packet, packet_size)) {
     66    // Validate STUN message length.
     67    const size_t stun_message_length = GetBE16(&packet[2]);
     68    if (stun_message_length + kStunHeaderSize != packet_size) {
     69      return false;
     70    }
     71 
     72    // First skip mandatory stun header which is of 20 bytes.
     73    size_t pos = kStunHeaderSize;
     74    // Loop through STUN attributes until we find STUN DATA attribute.
     75    while (pos < packet_size) {
     76      // Keep reading STUN attributes until we hit DATA attribute.
     77      // Attribute will be a TLV structure.
     78      // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     79      // |         Type                  |            Length             |
     80      // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     81      // |                         Value (variable)                ....
     82      // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     83      // The value in the length field MUST contain the length of the Value
     84      // part of the attribute, prior to padding, measured in bytes.  Since
     85      // STUN aligns attributes on 32-bit boundaries, attributes whose content
     86      // is not a multiple of 4 bytes are padded with 1, 2, or 3 bytes of
     87      // padding so that its value contains a multiple of 4 bytes.  The
     88      // padding bits are ignored, and may be any value.
     89      uint16_t attr_type, attr_length;
     90      const int kAttrHeaderLength = sizeof(attr_type) + sizeof(attr_length);
     91 
     92      if (packet_size < pos + kAttrHeaderLength) {
     93        return false;
     94      }
     95 
     96      // Getting attribute type and length.
     97      attr_type = GetBE16(&packet[pos]);
     98      attr_length = GetBE16(&packet[pos + sizeof(attr_type)]);
     99 
    100      pos += kAttrHeaderLength;  // Skip STUN_DATA_ATTR header.
    101 
    102      // Checking for bogus attribute length.
    103      if (pos + attr_length > packet_size) {
    104        return false;
    105      }
    106 
    107      if (attr_type == STUN_ATTR_DATA) {
    108        *content_position = pos;
    109        *content_size = attr_length;
    110        return true;
    111      }
    112 
    113      pos += attr_length;
    114      if ((attr_length % 4) != 0) {
    115        pos += (4 - (attr_length % 4));
    116      }
    117    }
    118 
    119    // There is no data attribute present in the message.
    120    return false;
    121  }
    122 
    123  // This is not a TURN packet.
    124  *content_position = 0;
    125  *content_size = packet_size;
    126  return true;
    127 }
    128 
    129 }  // namespace webrtc