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