tor-browser

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

stun.h (27966B)


      1 /*
      2 *  Copyright 2004 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 #ifndef API_TRANSPORT_STUN_H_
     12 #define API_TRANSPORT_STUN_H_
     13 
     14 // This file contains classes for dealing with the STUN protocol, as specified
     15 // in RFC 5389, and its descendants.
     16 
     17 #include <cstddef>
     18 #include <cstdint>
     19 #include <functional>
     20 #include <memory>
     21 #include <optional>
     22 #include <string>
     23 #include <vector>
     24 
     25 #include "absl/strings/string_view.h"
     26 #include "api/array_view.h"
     27 #include "rtc_base/byte_buffer.h"
     28 #include "rtc_base/checks.h"
     29 #include "rtc_base/ip_address.h"
     30 #include "rtc_base/net_helpers.h"
     31 #include "rtc_base/socket_address.h"
     32 
     33 namespace webrtc {
     34 
     35 // These are the types of STUN messages defined in RFC 5389.
     36 enum StunMessageType : uint16_t {
     37  STUN_INVALID_MESSAGE_TYPE = 0x0000,
     38  STUN_BINDING_REQUEST = 0x0001,
     39  STUN_BINDING_INDICATION = 0x0011,
     40  STUN_BINDING_RESPONSE = 0x0101,
     41  STUN_BINDING_ERROR_RESPONSE = 0x0111,
     42 
     43  // Method 0x80, GOOG-PING is a variant of STUN BINDING
     44  // that is sent instead of a STUN BINDING if the binding
     45  // was identical to the one before.
     46  GOOG_PING_REQUEST = 0x200,
     47  GOOG_PING_RESPONSE = 0x300,
     48  GOOG_PING_ERROR_RESPONSE = 0x310,
     49 };
     50 
     51 // These are all known STUN attributes, defined in RFC 5389 and elsewhere.
     52 // Next to each is the name of the class (T is StunTAttribute) that implements
     53 // that type.
     54 // RETRANSMIT_COUNT is the number of outstanding pings without a response at
     55 // the time the packet is generated.
     56 enum StunAttributeType {
     57  STUN_ATTR_MAPPED_ADDRESS = 0x0001,      // Address
     58  STUN_ATTR_USERNAME = 0x0006,            // ByteString
     59  STUN_ATTR_MESSAGE_INTEGRITY = 0x0008,   // ByteString, 20 bytes
     60  STUN_ATTR_ERROR_CODE = 0x0009,          // ErrorCode
     61  STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a,  // UInt16List
     62  STUN_ATTR_REALM = 0x0014,               // ByteString
     63  STUN_ATTR_NONCE = 0x0015,               // ByteString
     64  STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020,  // XorAddress
     65  STUN_ATTR_SOFTWARE = 0x8022,            // ByteString
     66  STUN_ATTR_ALTERNATE_SERVER = 0x8023,    // Address
     67  STUN_ATTR_FINGERPRINT = 0x8028,         // UInt32
     68  STUN_ATTR_RETRANSMIT_COUNT = 0xFF00     // UInt32
     69 };
     70 
     71 // These are the types of the values associated with the attributes above.
     72 // This allows us to perform some basic validation when reading or adding
     73 // attributes. Note that these values are for our own use, and not defined in
     74 // RFC 5389.
     75 enum StunAttributeValueType {
     76  STUN_VALUE_UNKNOWN = 0,
     77  STUN_VALUE_ADDRESS = 1,
     78  STUN_VALUE_XOR_ADDRESS = 2,
     79  STUN_VALUE_UINT32 = 3,
     80  STUN_VALUE_UINT64 = 4,
     81  STUN_VALUE_BYTE_STRING = 5,
     82  STUN_VALUE_ERROR_CODE = 6,
     83  STUN_VALUE_UINT16_LIST = 7
     84 };
     85 
     86 // These are the types of STUN addresses defined in RFC 5389.
     87 enum StunAddressFamily {
     88  // NB: UNDEF is not part of the STUN spec.
     89  STUN_ADDRESS_UNDEF = 0,
     90  STUN_ADDRESS_IPV4 = 1,
     91  STUN_ADDRESS_IPV6 = 2
     92 };
     93 
     94 // These are the types of STUN error codes defined in RFC 5389.
     95 enum StunErrorCode {
     96  // Not an actual error from RFC 5389 and not emitted via icecandidateerror.
     97  STUN_ERROR_NOT_AN_ERROR = 0,
     98  STUN_ERROR_TRY_ALTERNATE = 300,
     99  STUN_ERROR_BAD_REQUEST = 400,
    100  STUN_ERROR_UNAUTHORIZED = 401,
    101  STUN_ERROR_UNKNOWN_ATTRIBUTE = 420,
    102  STUN_ERROR_STALE_NONCE = 438,
    103  STUN_ERROR_SERVER_ERROR = 500,
    104  STUN_ERROR_GLOBAL_FAILURE = 600,
    105  // https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnectioniceerrorevent-errorcode
    106  STUN_ERROR_SERVER_NOT_REACHABLE = 701,
    107 };
    108 
    109 // Strings for the error codes above.
    110 extern const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[];
    111 extern const char STUN_ERROR_REASON_BAD_REQUEST[];
    112 extern const char STUN_ERROR_REASON_UNAUTHORIZED[];
    113 extern const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[];
    114 extern const char STUN_ERROR_REASON_STALE_NONCE[];
    115 extern const char STUN_ERROR_REASON_SERVER_ERROR[];
    116 
    117 // The mask used to determine whether a STUN message is a request/response etc.
    118 const uint32_t kStunTypeMask = 0x0110;
    119 
    120 // STUN Attribute header length.
    121 const size_t kStunAttributeHeaderSize = 4;
    122 
    123 // Following values correspond to RFC5389.
    124 const size_t kStunHeaderSize = 20;
    125 const size_t kStunTransactionIdOffset = 8;
    126 const size_t kStunTransactionIdLength = 12;
    127 const uint32_t kStunMagicCookie = 0x2112A442;
    128 constexpr size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);
    129 
    130 // Following value corresponds to an earlier version of STUN from
    131 // RFC3489.
    132 const size_t kStunLegacyTransactionIdLength = 16;
    133 
    134 // STUN Message Integrity HMAC length.
    135 const size_t kStunMessageIntegritySize = 20;
    136 // Size of STUN_ATTR_MESSAGE_INTEGRITY_32
    137 const size_t kStunMessageIntegrity32Size = 4;
    138 
    139 class StunAddressAttribute;
    140 class StunAttribute;
    141 class StunByteStringAttribute;
    142 class StunErrorCodeAttribute;
    143 class StunUInt16ListAttribute;
    144 class StunUInt32Attribute;
    145 class StunUInt64Attribute;
    146 class StunXorAddressAttribute;
    147 
    148 // Records a complete STUN/TURN message.  Each message consists of a type and
    149 // any number of attributes.  Each attribute is parsed into an instance of an
    150 // appropriate class (see above).  The Get* methods will return instances of
    151 // that attribute class.
    152 class StunMessage {
    153 public:
    154  // Constructs a StunMessage with an invalid type and empty, legacy length
    155  // (16 bytes, RFC3489) transaction id.
    156  StunMessage();
    157 
    158  // Construct a `StunMessage` with a specific type and generate a new
    159  // 12 byte transaction id (RFC5389).
    160  explicit StunMessage(uint16_t type);
    161 
    162  StunMessage(uint16_t type, absl::string_view transaction_id);
    163 
    164  virtual ~StunMessage();
    165 
    166  // The verification status of the message. This is checked on parsing,
    167  // or set by AddMessageIntegrity.
    168  // These values are persisted to logs. Entries should not be renumbered and
    169  // numeric values should never be reused.
    170  enum class IntegrityStatus {
    171    kNotSet = 0,
    172    kNoIntegrity = 1,   // Message-integrity attribute missing
    173    kIntegrityOk = 2,   // Message-integrity checked OK
    174    kIntegrityBad = 3,  // Message-integrity verification failed
    175    kMaxValue = kIntegrityBad,
    176  };
    177 
    178  int type() const { return type_; }
    179  size_t length() const { return length_; }
    180  const std::string& transaction_id() const { return transaction_id_; }
    181  uint32_t reduced_transaction_id() const { return reduced_transaction_id_; }
    182 
    183  // Returns true if the message confirms to RFC3489 rather than
    184  // RFC5389. The main difference between the two versions of the STUN
    185  // protocol is the presence of the magic cookie and different length
    186  // of transaction ID. For outgoing packets the version of the protocol
    187  // is determined by the lengths of the transaction ID.
    188  bool IsLegacy() const;
    189 
    190  [[deprecated]] void SetType(int type) { type_ = static_cast<uint16_t>(type); }
    191  [[deprecated]] bool SetTransactionID(absl::string_view transaction_id) {
    192    if (!IsValidTransactionId(transaction_id))
    193      return false;
    194    SetTransactionIdForTesting(transaction_id);
    195    return true;
    196  }
    197 
    198  // Get a list of all of the attribute types in the "comprehension required"
    199  // range that were not recognized.
    200  std::vector<uint16_t> GetNonComprehendedAttributes() const;
    201 
    202  // Gets the desired attribute value, or NULL if no such attribute type exists.
    203  const StunAddressAttribute* GetAddress(int type) const;
    204  const StunUInt32Attribute* GetUInt32(int type) const;
    205  const StunUInt64Attribute* GetUInt64(int type) const;
    206  const StunByteStringAttribute* GetByteString(int type) const;
    207  const StunUInt16ListAttribute* GetUInt16List(int type) const;
    208 
    209  // Gets these specific attribute values.
    210  const StunErrorCodeAttribute* GetErrorCode() const;
    211  // Returns the code inside the error code attribute, if present, and
    212  // STUN_ERROR_GLOBAL_FAILURE otherwise.
    213  int GetErrorCodeValue() const;
    214  const StunUInt16ListAttribute* GetUnknownAttributes() const;
    215 
    216  // Takes ownership of the specified attribute and adds it to the message.
    217  void AddAttribute(std::unique_ptr<StunAttribute> attr);
    218 
    219  // Remove the last occurrence of an attribute.
    220  std::unique_ptr<StunAttribute> RemoveAttribute(int type);
    221 
    222  // Remote all attributes and releases them.
    223  void ClearAttributes();
    224 
    225  // Validates that a STUN message has a correct MESSAGE-INTEGRITY value.
    226  // This uses the buffered raw-format message stored by Read().
    227  IntegrityStatus ValidateMessageIntegrity(const std::string& password);
    228 
    229  // Revalidates the STUN message with (possibly) a new password.
    230  // Indicates that calling logic needs review - probably previous call
    231  // was checking with the wrong password.
    232  IntegrityStatus RevalidateMessageIntegrity(const std::string& password);
    233 
    234  // Returns the current integrity status of the message.
    235  IntegrityStatus integrity() const { return integrity_; }
    236 
    237  // Shortcut for checking if integrity is verified.
    238  bool IntegrityOk() const {
    239    return integrity_ == IntegrityStatus::kIntegrityOk;
    240  }
    241 
    242  // Returns the password attribute used to set or check the integrity.
    243  // Can only be called after adding or checking the integrity.
    244  std::string password() const {
    245    RTC_DCHECK(integrity_ != IntegrityStatus::kNotSet);
    246    return password_;
    247  }
    248 
    249  // Adds a MESSAGE-INTEGRITY attribute that is valid for the current message.
    250  bool AddMessageIntegrity(absl::string_view password);
    251 
    252  // Adds a STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32 attribute that is valid for the
    253  // current message.
    254  bool AddMessageIntegrity32(absl::string_view password);
    255 
    256  // Verify that a buffer has stun magic cookie and one of the specified
    257  // methods. Note that it does not check for the existance of FINGERPRINT.
    258  static bool IsStunMethod(ArrayView<int> methods,
    259                           const char* data,
    260                           size_t size);
    261 
    262  // Verifies that a given buffer is STUN by checking for a correct FINGERPRINT.
    263  static bool ValidateFingerprint(const char* data, size_t size);
    264 
    265  // Generates a new 12 byte (RFC5389) transaction id.
    266  static std::string GenerateTransactionId();
    267 
    268  // Adds a FINGERPRINT attribute that is valid for the current message.
    269  bool AddFingerprint();
    270 
    271  // Parses the STUN packet in the given buffer and records it here. The
    272  // return value indicates whether this was successful.
    273  bool Read(ByteBufferReader* buf);
    274 
    275  // Writes this object into a STUN packet. The return value indicates whether
    276  // this was successful.
    277  bool Write(ByteBufferWriter* buf) const;
    278 
    279  // Creates an empty message. Overridable by derived classes.
    280  virtual StunMessage* CreateNew() const;
    281 
    282  // Modify the stun magic cookie used for this STUN message.
    283  // This is used for testing.
    284  [[deprecated]] void SetStunMagicCookie(uint32_t val);
    285 
    286  // Change the internal transaction id. Used only for testing.
    287  void SetTransactionIdForTesting(absl::string_view transaction_id);
    288 
    289  // Contruct a copy of `this`.
    290  std::unique_ptr<StunMessage> Clone() const;
    291 
    292  // Check if the attributes of this StunMessage equals those of `other`
    293  // for all attributes that `attribute_type_mask` return true
    294  bool EqualAttributes(const StunMessage* other,
    295                       std::function<bool(int type)> attribute_type_mask) const;
    296 
    297  // Expose raw-buffer ValidateMessageIntegrity function for testing.
    298  static bool ValidateMessageIntegrityForTesting(const char* data,
    299                                                 size_t size,
    300                                                 const std::string& password);
    301  // Expose raw-buffer ValidateMessageIntegrity function for testing.
    302  static bool ValidateMessageIntegrity32ForTesting(const char* data,
    303                                                   size_t size,
    304                                                   const std::string& password);
    305 
    306 protected:
    307  // Verifies that the given attribute is allowed for this message.
    308  virtual StunAttributeValueType GetAttributeValueType(int type) const;
    309 
    310  std::vector<std::unique_ptr<StunAttribute>> attrs_;
    311 
    312 private:
    313  StunAttribute* CreateAttribute(int type, size_t length) /* const*/;
    314  const StunAttribute* GetAttribute(int type) const;
    315  static bool IsValidTransactionId(absl::string_view transaction_id);
    316  bool AddMessageIntegrityOfType(int mi_attr_type,
    317                                 size_t mi_attr_size,
    318                                 absl::string_view key);
    319  static bool ValidateMessageIntegrityOfType(int mi_attr_type,
    320                                             size_t mi_attr_size,
    321                                             const char* data,
    322                                             size_t size,
    323                                             const std::string& password);
    324 
    325  uint16_t type_ = STUN_INVALID_MESSAGE_TYPE;
    326  uint16_t length_ = 0;
    327  std::string transaction_id_;
    328  uint32_t reduced_transaction_id_ = 0;
    329  uint32_t stun_magic_cookie_ = kStunMagicCookie;
    330  // The original buffer for messages created by Read().
    331  std::string buffer_;
    332  IntegrityStatus integrity_ = IntegrityStatus::kNotSet;
    333  std::string password_;
    334 };
    335 
    336 // Base class for all STUN/TURN attributes.
    337 class StunAttribute {
    338 public:
    339  virtual ~StunAttribute() {}
    340 
    341  int type() const { return type_; }
    342  size_t length() const { return length_; }
    343 
    344  // Return the type of this attribute.
    345  virtual StunAttributeValueType value_type() const = 0;
    346 
    347  // Only XorAddressAttribute needs this so far.
    348  virtual void SetOwner(StunMessage* /* owner */) {}
    349 
    350  // Reads the body (not the type or length) for this type of attribute from
    351  // the given buffer.  Return value is true if successful.
    352  virtual bool Read(ByteBufferReader* buf) = 0;
    353 
    354  // Writes the body (not the type or length) to the given buffer.  Return
    355  // value is true if successful.
    356  virtual bool Write(ByteBufferWriter* buf) const = 0;
    357 
    358  // Creates an attribute object with the given type and smallest length.
    359  static StunAttribute* Create(StunAttributeValueType value_type,
    360                               uint16_t type,
    361                               uint16_t length,
    362                               StunMessage* owner);
    363  // TODO(?): Allow these create functions to take parameters, to reduce
    364  // the amount of work callers need to do to initialize attributes.
    365  static std::unique_ptr<StunAddressAttribute> CreateAddress(uint16_t type);
    366  static std::unique_ptr<StunXorAddressAttribute> CreateXorAddress(
    367      uint16_t type);
    368  static std::unique_ptr<StunUInt32Attribute> CreateUInt32(uint16_t type);
    369  static std::unique_ptr<StunUInt64Attribute> CreateUInt64(uint16_t type);
    370  static std::unique_ptr<StunByteStringAttribute> CreateByteString(
    371      uint16_t type);
    372  static std::unique_ptr<StunUInt16ListAttribute> CreateUInt16ListAttribute(
    373      uint16_t type);
    374  static std::unique_ptr<StunErrorCodeAttribute> CreateErrorCode();
    375  static std::unique_ptr<StunUInt16ListAttribute> CreateUnknownAttributes();
    376 
    377 protected:
    378  StunAttribute(uint16_t type, uint16_t length);
    379  void SetLength(uint16_t length) { length_ = length; }
    380  void WritePadding(ByteBufferWriter* buf) const;
    381  void ConsumePadding(ByteBufferReader* buf) const;
    382 
    383 private:
    384  uint16_t type_;
    385  uint16_t length_;
    386 };
    387 
    388 // Implements STUN attributes that record an Internet address.
    389 class StunAddressAttribute : public StunAttribute {
    390 public:
    391  static const uint16_t SIZE_UNDEF = 0;
    392  static const uint16_t SIZE_IP4 = 8;
    393  static const uint16_t SIZE_IP6 = 20;
    394  StunAddressAttribute(uint16_t type, const SocketAddress& addr);
    395  StunAddressAttribute(uint16_t type, uint16_t length);
    396 
    397  StunAttributeValueType value_type() const override;
    398 
    399  StunAddressFamily family() const {
    400    switch (address_.ipaddr().family()) {
    401      case AF_INET:
    402        return STUN_ADDRESS_IPV4;
    403      case AF_INET6:
    404        return STUN_ADDRESS_IPV6;
    405    }
    406    return STUN_ADDRESS_UNDEF;
    407  }
    408 
    409  const SocketAddress& GetAddress() const { return address_; }
    410  const IPAddress& ipaddr() const { return address_.ipaddr(); }
    411  uint16_t port() const { return address_.port(); }
    412 
    413  void SetAddress(const SocketAddress& addr) {
    414    address_ = addr;
    415    EnsureAddressLength();
    416  }
    417  void SetIP(const IPAddress& ip) {
    418    address_.SetIP(ip);
    419    EnsureAddressLength();
    420  }
    421  void SetPort(uint16_t port) { address_.SetPort(port); }
    422 
    423  bool Read(ByteBufferReader* buf) override;
    424  bool Write(ByteBufferWriter* buf) const override;
    425 
    426 private:
    427  void EnsureAddressLength() {
    428    switch (family()) {
    429      case STUN_ADDRESS_IPV4: {
    430        SetLength(SIZE_IP4);
    431        break;
    432      }
    433      case STUN_ADDRESS_IPV6: {
    434        SetLength(SIZE_IP6);
    435        break;
    436      }
    437      default: {
    438        SetLength(SIZE_UNDEF);
    439        break;
    440      }
    441    }
    442  }
    443  SocketAddress address_;
    444 };
    445 
    446 // Implements STUN attributes that record an Internet address. When encoded
    447 // in a STUN message, the address contained in this attribute is XORed with the
    448 // transaction ID of the message.
    449 class StunXorAddressAttribute : public StunAddressAttribute {
    450 public:
    451  StunXorAddressAttribute(uint16_t type, const SocketAddress& addr);
    452  StunXorAddressAttribute(uint16_t type, uint16_t length, StunMessage* owner);
    453 
    454  StunAttributeValueType value_type() const override;
    455  void SetOwner(StunMessage* owner) override;
    456  bool Read(ByteBufferReader* buf) override;
    457  bool Write(ByteBufferWriter* buf) const override;
    458 
    459 private:
    460  IPAddress GetXoredIP() const;
    461  StunMessage* owner_;
    462 };
    463 
    464 // Implements STUN attributes that record a 32-bit integer.
    465 class StunUInt32Attribute : public StunAttribute {
    466 public:
    467  static const uint16_t SIZE = 4;
    468  StunUInt32Attribute(uint16_t type, uint32_t value);
    469  explicit StunUInt32Attribute(uint16_t type);
    470 
    471  StunAttributeValueType value_type() const override;
    472 
    473  uint32_t value() const { return bits_; }
    474  void SetValue(uint32_t bits) { bits_ = bits; }
    475 
    476  bool GetBit(size_t index) const;
    477  void SetBit(size_t index, bool value);
    478 
    479  bool Read(ByteBufferReader* buf) override;
    480  bool Write(ByteBufferWriter* buf) const override;
    481 
    482 private:
    483  uint32_t bits_;
    484 };
    485 
    486 class StunUInt64Attribute : public StunAttribute {
    487 public:
    488  static const uint16_t SIZE = 8;
    489  StunUInt64Attribute(uint16_t type, uint64_t value);
    490  explicit StunUInt64Attribute(uint16_t type);
    491 
    492  StunAttributeValueType value_type() const override;
    493 
    494  uint64_t value() const { return bits_; }
    495  void SetValue(uint64_t bits) { bits_ = bits; }
    496 
    497  bool Read(ByteBufferReader* buf) override;
    498  bool Write(ByteBufferWriter* buf) const override;
    499 
    500 private:
    501  uint64_t bits_;
    502 };
    503 
    504 // Implements STUN attributes that record an arbitrary byte string.
    505 class StunByteStringAttribute : public StunAttribute {
    506 public:
    507  explicit StunByteStringAttribute(uint16_t type);
    508  StunByteStringAttribute(uint16_t type, absl::string_view str);
    509  StunByteStringAttribute(uint16_t type, const void* bytes, size_t length);
    510  StunByteStringAttribute(uint16_t type, const std::vector<uint32_t>& values);
    511  StunByteStringAttribute(uint16_t type, uint16_t length);
    512  ~StunByteStringAttribute() override;
    513 
    514  StunAttributeValueType value_type() const override;
    515 
    516  [[deprecated("Use array_view")]] const char* bytes() const {
    517    return reinterpret_cast<const char*>(bytes_);
    518  }
    519  // Returns the attribute value as a string.
    520  // Use this for attributes that are text or text-compatible.
    521  absl::string_view string_view() const {
    522    return absl::string_view(reinterpret_cast<const char*>(bytes_), length());
    523  }
    524  // Returns the attribute value as an uint8_t view.
    525  // Use this function for values that are not text.
    526  ArrayView<uint8_t> array_view() const {
    527    return MakeArrayView(bytes_, length());
    528  }
    529 
    530  [[deprecated]] std::string GetString() const {
    531    return std::string(reinterpret_cast<const char*>(bytes_), length());
    532  }
    533 
    534  std::optional<std::vector<uint32_t>> GetUInt32Vector() const;
    535 
    536  void CopyBytes(const void* bytes, size_t length);
    537  void CopyBytes(absl::string_view bytes);
    538 
    539  uint8_t GetByte(size_t index) const;
    540  void SetByte(size_t index, uint8_t value);
    541 
    542  bool Read(ByteBufferReader* buf) override;
    543  bool Write(ByteBufferWriter* buf) const override;
    544 
    545 private:
    546  void SetBytes(uint8_t* bytes, size_t length);
    547 
    548  uint8_t* bytes_;
    549 };
    550 
    551 // Implements STUN attributes that record an error code.
    552 class StunErrorCodeAttribute : public StunAttribute {
    553 public:
    554  static const uint16_t MIN_SIZE;
    555  StunErrorCodeAttribute(uint16_t type, int code, const std::string& reason);
    556  StunErrorCodeAttribute(uint16_t type, uint16_t length);
    557  ~StunErrorCodeAttribute() override;
    558 
    559  StunAttributeValueType value_type() const override;
    560 
    561  // The combined error and class, e.g. 0x400.
    562  int code() const;
    563  void SetCode(int code);
    564 
    565  // The individual error components.
    566  int eclass() const { return class_; }
    567  int number() const { return number_; }
    568  const std::string& reason() const { return reason_; }
    569  void SetClass(uint8_t eclass) { class_ = eclass; }
    570  void SetNumber(uint8_t number) { number_ = number; }
    571  void SetReason(const std::string& reason);
    572 
    573  bool Read(ByteBufferReader* buf) override;
    574  bool Write(ByteBufferWriter* buf) const override;
    575 
    576 private:
    577  uint8_t class_;
    578  uint8_t number_;
    579  std::string reason_;
    580 };
    581 
    582 // Implements STUN attributes that record a list of attribute names.
    583 class StunUInt16ListAttribute : public StunAttribute {
    584 public:
    585  StunUInt16ListAttribute(uint16_t type, uint16_t length);
    586  ~StunUInt16ListAttribute() override;
    587 
    588  StunAttributeValueType value_type() const override;
    589 
    590  size_t Size() const;
    591  uint16_t GetType(int index) const;
    592  void SetType(int index, uint16_t value);
    593  void AddType(uint16_t value);
    594  void AddTypeAtIndex(uint16_t index, uint16_t value);
    595 
    596  bool Read(ByteBufferReader* buf) override;
    597  bool Write(ByteBufferWriter* buf) const override;
    598 
    599 private:
    600  std::vector<uint16_t>* attr_types_;
    601 };
    602 
    603 // Return a string e.g "STUN BINDING request".
    604 std::string StunMethodToString(int msg_type);
    605 
    606 // Returns the (successful) response type for the given request type.
    607 // Returns -1 if `request_type` is not a valid request type.
    608 int GetStunSuccessResponseType(int request_type);
    609 
    610 // Returns the error response type for the given request type.
    611 // Returns -1 if `request_type` is not a valid request type.
    612 int GetStunErrorResponseType(int request_type);
    613 
    614 // Returns whether a given message is a request type.
    615 bool IsStunRequestType(int msg_type);
    616 
    617 // Returns whether a given message is an indication type.
    618 bool IsStunIndicationType(int msg_type);
    619 
    620 // Returns whether a given response is a success type.
    621 bool IsStunSuccessResponseType(int msg_type);
    622 
    623 // Returns whether a given response is an error type.
    624 bool IsStunErrorResponseType(int msg_type);
    625 
    626 // Computes the STUN long-term credential hash.
    627 bool ComputeStunCredentialHash(const std::string& username,
    628                               const std::string& realm,
    629                               const std::string& password,
    630                               std::string* hash);
    631 
    632 // Make a copy af `attribute` and return a new StunAttribute.
    633 //   This is useful if you don't care about what kind of attribute you
    634 //   are handling.
    635 //
    636 // The implementation copies by calling Write() followed by Read().
    637 //
    638 // If `tmp_buffer` is supplied this buffer will be used, otherwise
    639 // a buffer will created in the method.
    640 std::unique_ptr<StunAttribute> CopyStunAttribute(
    641    const StunAttribute& attribute,
    642    ByteBufferWriter* tmp_buffer_ptr = 0);
    643 
    644 // Defined in TURN RFC 5766.
    645 enum TurnMessageType : uint16_t {
    646  STUN_ALLOCATE_REQUEST = 0x0003,
    647  STUN_ALLOCATE_RESPONSE = 0x0103,
    648  STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
    649  TURN_REFRESH_REQUEST = 0x0004,
    650  TURN_REFRESH_RESPONSE = 0x0104,
    651  TURN_REFRESH_ERROR_RESPONSE = 0x0114,
    652  TURN_SEND_INDICATION = 0x0016,
    653  TURN_DATA_INDICATION = 0x0017,
    654  TURN_CREATE_PERMISSION_REQUEST = 0x0008,
    655  TURN_CREATE_PERMISSION_RESPONSE = 0x0108,
    656  TURN_CREATE_PERMISSION_ERROR_RESPONSE = 0x0118,
    657  TURN_CHANNEL_BIND_REQUEST = 0x0009,
    658  TURN_CHANNEL_BIND_RESPONSE = 0x0109,
    659  TURN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119,
    660 };
    661 
    662 enum TurnAttributeType {
    663  STUN_ATTR_CHANNEL_NUMBER = 0x000C,       // UInt32
    664  STUN_ATTR_LIFETIME = 0x000d,             // UInt32
    665  STUN_ATTR_XOR_PEER_ADDRESS = 0x0012,     // XorAddress
    666  STUN_ATTR_DATA = 0x0013,                 // ByteString
    667  STUN_ATTR_XOR_RELAYED_ADDRESS = 0x0016,  // XorAddress
    668  STUN_ATTR_EVEN_PORT = 0x0018,            // ByteString, 1 byte.
    669  STUN_ATTR_REQUESTED_TRANSPORT = 0x0019,  // UInt32
    670  STUN_ATTR_DONT_FRAGMENT = 0x001A,        // No content, Length = 0
    671  STUN_ATTR_RESERVATION_TOKEN = 0x0022,    // ByteString, 8 bytes.
    672 };
    673 
    674 // RFC 5766-defined errors.
    675 enum TurnErrorType {
    676  STUN_ERROR_FORBIDDEN = 403,
    677  STUN_ERROR_ALLOCATION_MISMATCH = 437,
    678  STUN_ERROR_WRONG_CREDENTIALS = 441,
    679  STUN_ERROR_UNSUPPORTED_PROTOCOL = 442
    680 };
    681 
    682 [[deprecated("Use STUN_ERROR_SERVER_NOT_REACHABLE")]] extern const int
    683    SERVER_NOT_REACHABLE_ERROR;
    684 
    685 extern const char STUN_ERROR_REASON_FORBIDDEN[];
    686 extern const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[];
    687 extern const char STUN_ERROR_REASON_WRONG_CREDENTIALS[];
    688 extern const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[];
    689 class TurnMessage : public StunMessage {
    690 public:
    691  using StunMessage::StunMessage;
    692 
    693 protected:
    694  StunAttributeValueType GetAttributeValueType(int type) const override;
    695  StunMessage* CreateNew() const override;
    696 };
    697 
    698 enum IceAttributeType {
    699  // RFC 5245 ICE STUN attributes.
    700  STUN_ATTR_PRIORITY = 0x0024,         // UInt32
    701  STUN_ATTR_USE_CANDIDATE = 0x0025,    // No content, Length = 0
    702  STUN_ATTR_ICE_CONTROLLED = 0x8029,   // UInt64
    703  STUN_ATTR_ICE_CONTROLLING = 0x802A,  // UInt64
    704  // The following attributes are in the comprehension-optional range
    705  // (0xC000-0xFFFF) and are not registered with IANA. These STUN attributes are
    706  // intended for ICE and should NOT be used in generic use cases of STUN
    707  // messages.
    708  //
    709  // Note that the value 0xC001 has already been assigned by IANA to
    710  // ENF-FLOW-DESCRIPTION
    711  // (https://www.iana.org/assignments/stun-parameters/stun-parameters.xml).
    712  STUN_ATTR_NOMINATION = 0xC001,  // UInt32
    713  // UInt32. The higher 16 bits are the network ID. The lower 16 bits are the
    714  // network cost.
    715  STUN_ATTR_GOOG_NETWORK_INFO = 0xC057,
    716  // Experimental: Transaction ID of the last connectivity check received.
    717  STUN_ATTR_GOOG_LAST_ICE_CHECK_RECEIVED = 0xC058,
    718  // Uint16List. Miscellaneous attributes for future extension.
    719  STUN_ATTR_GOOG_MISC_INFO = 0xC059,
    720  // Obsolete.
    721  STUN_ATTR_GOOG_OBSOLETE_1 = 0xC05A,
    722  STUN_ATTR_GOOG_CONNECTION_ID = 0xC05B,   // Not yet implemented.
    723  STUN_ATTR_GOOG_DELTA = 0xC05C,           // Not yet implemented.
    724  STUN_ATTR_GOOG_DELTA_ACK = 0xC05D,       // Not yet implemented.
    725  STUN_ATTR_GOOG_DELTA_SYNC_REQ = 0xC05E,  // Not yet implemented.
    726  // MESSAGE-INTEGRITY truncated to 32-bit.
    727  STUN_ATTR_GOOG_MESSAGE_INTEGRITY_32 = 0xC060,
    728  // Experimental: piggybacking the DTLS handshake in STUN.
    729  STUN_ATTR_META_DTLS_IN_STUN = 0xC070,
    730  STUN_ATTR_META_DTLS_IN_STUN_ACK = 0xC071,
    731 };
    732 
    733 // When adding new attributes to STUN_ATTR_GOOG_MISC_INFO
    734 // (which is a list of uint16_t), append the indices of these attributes below
    735 // and do NOT change the existing indices. The indices of attributes must be
    736 // consistent with those used in ConnectionRequest::Prepare when forming a STUN
    737 // message for the ICE connectivity check, and they are used when parsing a
    738 // received STUN message.
    739 enum class IceGoogMiscInfoBindingRequestAttributeIndex {
    740  SUPPORT_GOOG_PING_VERSION = 0,
    741 };
    742 
    743 enum class IceGoogMiscInfoBindingResponseAttributeIndex {
    744  SUPPORT_GOOG_PING_VERSION = 0,
    745 };
    746 
    747 // RFC 5245-defined errors.
    748 enum IceErrorCode {
    749  STUN_ERROR_ROLE_CONFLICT = 487,
    750 };
    751 extern const char STUN_ERROR_REASON_ROLE_CONFLICT[];
    752 
    753 // A RFC 5245 ICE STUN message.
    754 class IceMessage : public StunMessage {
    755 public:
    756  using StunMessage::StunMessage;
    757 
    758 protected:
    759  StunAttributeValueType GetAttributeValueType(int type) const override;
    760  StunMessage* CreateNew() const override;
    761 };
    762 
    763 }  //  namespace webrtc
    764 
    765 
    766 #endif  // API_TRANSPORT_STUN_H_