• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 WEBRTC_P2P_BASE_STUN_H_
12  #define WEBRTC_P2P_BASE_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 <string>
18  #include <vector>
19  
20  #include "webrtc/base/basictypes.h"
21  #include "webrtc/base/bytebuffer.h"
22  #include "webrtc/base/socketaddress.h"
23  
24  namespace cricket {
25  
26  // These are the types of STUN messages defined in RFC 5389.
27  enum StunMessageType {
28    STUN_BINDING_REQUEST                  = 0x0001,
29    STUN_BINDING_INDICATION               = 0x0011,
30    STUN_BINDING_RESPONSE                 = 0x0101,
31    STUN_BINDING_ERROR_RESPONSE           = 0x0111,
32  };
33  
34  // These are all known STUN attributes, defined in RFC 5389 and elsewhere.
35  // Next to each is the name of the class (T is StunTAttribute) that implements
36  // that type.
37  // RETRANSMIT_COUNT is the number of outstanding pings without a response at
38  // the time the packet is generated.
39  enum StunAttributeType {
40    STUN_ATTR_MAPPED_ADDRESS              = 0x0001,  // Address
41    STUN_ATTR_USERNAME                    = 0x0006,  // ByteString
42    STUN_ATTR_MESSAGE_INTEGRITY           = 0x0008,  // ByteString, 20 bytes
43    STUN_ATTR_ERROR_CODE                  = 0x0009,  // ErrorCode
44    STUN_ATTR_UNKNOWN_ATTRIBUTES          = 0x000a,  // UInt16List
45    STUN_ATTR_REALM                       = 0x0014,  // ByteString
46    STUN_ATTR_NONCE                       = 0x0015,  // ByteString
47    STUN_ATTR_XOR_MAPPED_ADDRESS          = 0x0020,  // XorAddress
48    STUN_ATTR_SOFTWARE                    = 0x8022,  // ByteString
49    STUN_ATTR_ALTERNATE_SERVER            = 0x8023,  // Address
50    STUN_ATTR_FINGERPRINT                 = 0x8028,  // UInt32
51    STUN_ATTR_ORIGIN                      = 0x802F,  // ByteString
52    STUN_ATTR_RETRANSMIT_COUNT            = 0xFF00   // UInt32
53  };
54  
55  // These are the types of the values associated with the attributes above.
56  // This allows us to perform some basic validation when reading or adding
57  // attributes. Note that these values are for our own use, and not defined in
58  // RFC 5389.
59  enum StunAttributeValueType {
60    STUN_VALUE_UNKNOWN                    = 0,
61    STUN_VALUE_ADDRESS                    = 1,
62    STUN_VALUE_XOR_ADDRESS                = 2,
63    STUN_VALUE_UINT32                     = 3,
64    STUN_VALUE_UINT64                     = 4,
65    STUN_VALUE_BYTE_STRING                = 5,
66    STUN_VALUE_ERROR_CODE                 = 6,
67    STUN_VALUE_UINT16_LIST                = 7
68  };
69  
70  // These are the types of STUN addresses defined in RFC 5389.
71  enum StunAddressFamily {
72    // NB: UNDEF is not part of the STUN spec.
73    STUN_ADDRESS_UNDEF                    = 0,
74    STUN_ADDRESS_IPV4                     = 1,
75    STUN_ADDRESS_IPV6                     = 2
76  };
77  
78  // These are the types of STUN error codes defined in RFC 5389.
79  enum StunErrorCode {
80    STUN_ERROR_TRY_ALTERNATE              = 300,
81    STUN_ERROR_BAD_REQUEST                = 400,
82    STUN_ERROR_UNAUTHORIZED               = 401,
83    STUN_ERROR_UNKNOWN_ATTRIBUTE          = 420,
84    STUN_ERROR_STALE_CREDENTIALS          = 430,  // GICE only
85    STUN_ERROR_STALE_NONCE                = 438,
86    STUN_ERROR_SERVER_ERROR               = 500,
87    STUN_ERROR_GLOBAL_FAILURE             = 600
88  };
89  
90  // Strings for the error codes above.
91  extern const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[];
92  extern const char STUN_ERROR_REASON_BAD_REQUEST[];
93  extern const char STUN_ERROR_REASON_UNAUTHORIZED[];
94  extern const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[];
95  extern const char STUN_ERROR_REASON_STALE_CREDENTIALS[];
96  extern const char STUN_ERROR_REASON_STALE_NONCE[];
97  extern const char STUN_ERROR_REASON_SERVER_ERROR[];
98  
99  // The mask used to determine whether a STUN message is a request/response etc.
100  const uint32_t kStunTypeMask = 0x0110;
101  
102  // STUN Attribute header length.
103  const size_t kStunAttributeHeaderSize = 4;
104  
105  // Following values correspond to RFC5389.
106  const size_t kStunHeaderSize = 20;
107  const size_t kStunTransactionIdOffset = 8;
108  const size_t kStunTransactionIdLength = 12;
109  const uint32_t kStunMagicCookie = 0x2112A442;
110  const size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);
111  
112  // Following value corresponds to an earlier version of STUN from
113  // RFC3489.
114  const size_t kStunLegacyTransactionIdLength = 16;
115  
116  // STUN Message Integrity HMAC length.
117  const size_t kStunMessageIntegritySize = 20;
118  
119  class StunAttribute;
120  class StunAddressAttribute;
121  class StunXorAddressAttribute;
122  class StunUInt32Attribute;
123  class StunUInt64Attribute;
124  class StunByteStringAttribute;
125  class StunErrorCodeAttribute;
126  class StunUInt16ListAttribute;
127  
128  // Records a complete STUN/TURN message.  Each message consists of a type and
129  // any number of attributes.  Each attribute is parsed into an instance of an
130  // appropriate class (see above).  The Get* methods will return instances of
131  // that attribute class.
132  class StunMessage {
133   public:
134    StunMessage();
135    virtual ~StunMessage();
136  
type()137    int type() const { return type_; }
length()138    size_t length() const { return length_; }
transaction_id()139    const std::string& transaction_id() const { return transaction_id_; }
140  
141    // Returns true if the message confirms to RFC3489 rather than
142    // RFC5389. The main difference between two version of the STUN
143    // protocol is the presence of the magic cookie and different length
144    // of transaction ID. For outgoing packets version of the protocol
145    // is determined by the lengths of the transaction ID.
146    bool IsLegacy() const;
147  
SetType(int type)148    void SetType(int type) { type_ = static_cast<uint16_t>(type); }
149    bool SetTransactionID(const std::string& str);
150  
151    // Gets the desired attribute value, or NULL if no such attribute type exists.
152    const StunAddressAttribute* GetAddress(int type) const;
153    const StunUInt32Attribute* GetUInt32(int type) const;
154    const StunUInt64Attribute* GetUInt64(int type) const;
155    const StunByteStringAttribute* GetByteString(int type) const;
156  
157    // Gets these specific attribute values.
158    const StunErrorCodeAttribute* GetErrorCode() const;
159    const StunUInt16ListAttribute* GetUnknownAttributes() const;
160  
161    // Takes ownership of the specified attribute, verifies it is of the correct
162    // type, and adds it to the message. The return value indicates whether this
163    // was successful.
164    bool AddAttribute(StunAttribute* attr);
165  
166    // Validates that a raw STUN message has a correct MESSAGE-INTEGRITY value.
167    // This can't currently be done on a StunMessage, since it is affected by
168    // padding data (which we discard when reading a StunMessage).
169    static bool ValidateMessageIntegrity(const char* data, size_t size,
170                                         const std::string& password);
171    // Adds a MESSAGE-INTEGRITY attribute that is valid for the current message.
172    bool AddMessageIntegrity(const std::string& password);
173    bool AddMessageIntegrity(const char* key, size_t keylen);
174  
175    // Verifies that a given buffer is STUN by checking for a correct FINGERPRINT.
176    static bool ValidateFingerprint(const char* data, size_t size);
177  
178    // Adds a FINGERPRINT attribute that is valid for the current message.
179    bool AddFingerprint();
180  
181    // Parses the STUN packet in the given buffer and records it here. The
182    // return value indicates whether this was successful.
183    bool Read(rtc::ByteBuffer* buf);
184  
185    // Writes this object into a STUN packet. The return value indicates whether
186    // this was successful.
187    bool Write(rtc::ByteBuffer* buf) const;
188  
189    // Creates an empty message. Overridable by derived classes.
CreateNew()190    virtual StunMessage* CreateNew() const { return new StunMessage(); }
191  
192   protected:
193    // Verifies that the given attribute is allowed for this message.
194    virtual StunAttributeValueType GetAttributeValueType(int type) const;
195  
196   private:
197    StunAttribute* CreateAttribute(int type, size_t length) /* const*/;
198    const StunAttribute* GetAttribute(int type) const;
199    static bool IsValidTransactionId(const std::string& transaction_id);
200  
201    uint16_t type_;
202    uint16_t length_;
203    std::string transaction_id_;
204    std::vector<StunAttribute*>* attrs_;
205  };
206  
207  // Base class for all STUN/TURN attributes.
208  class StunAttribute {
209   public:
~StunAttribute()210    virtual ~StunAttribute() {
211    }
212  
type()213    int type() const { return type_; }
length()214    size_t length() const { return length_; }
215  
216    // Return the type of this attribute.
217    virtual StunAttributeValueType value_type() const = 0;
218  
219    // Only XorAddressAttribute needs this so far.
SetOwner(StunMessage * owner)220    virtual void SetOwner(StunMessage* owner) {}
221  
222    // Reads the body (not the type or length) for this type of attribute from
223    // the given buffer.  Return value is true if successful.
224    virtual bool Read(rtc::ByteBuffer* buf) = 0;
225  
226    // Writes the body (not the type or length) to the given buffer.  Return
227    // value is true if successful.
228    virtual bool Write(rtc::ByteBuffer* buf) const = 0;
229  
230    // Creates an attribute object with the given type and smallest length.
231    static StunAttribute* Create(StunAttributeValueType value_type,
232                                 uint16_t type,
233                                 uint16_t length,
234                                 StunMessage* owner);
235    // TODO: Allow these create functions to take parameters, to reduce
236    // the amount of work callers need to do to initialize attributes.
237    static StunAddressAttribute* CreateAddress(uint16_t type);
238    static StunXorAddressAttribute* CreateXorAddress(uint16_t type);
239    static StunUInt32Attribute* CreateUInt32(uint16_t type);
240    static StunUInt64Attribute* CreateUInt64(uint16_t type);
241    static StunByteStringAttribute* CreateByteString(uint16_t type);
242    static StunErrorCodeAttribute* CreateErrorCode();
243    static StunUInt16ListAttribute* CreateUnknownAttributes();
244  
245   protected:
246    StunAttribute(uint16_t type, uint16_t length);
SetLength(uint16_t length)247    void SetLength(uint16_t length) { length_ = length; }
248    void WritePadding(rtc::ByteBuffer* buf) const;
249    void ConsumePadding(rtc::ByteBuffer* buf) const;
250  
251   private:
252    uint16_t type_;
253    uint16_t length_;
254  };
255  
256  // Implements STUN attributes that record an Internet address.
257  class StunAddressAttribute : public StunAttribute {
258   public:
259    static const uint16_t SIZE_UNDEF = 0;
260    static const uint16_t SIZE_IP4 = 8;
261    static const uint16_t SIZE_IP6 = 20;
262    StunAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
263    StunAddressAttribute(uint16_t type, uint16_t length);
264  
value_type()265    virtual StunAttributeValueType value_type() const {
266      return STUN_VALUE_ADDRESS;
267    }
268  
family()269    StunAddressFamily family() const {
270      switch (address_.ipaddr().family()) {
271        case AF_INET:
272          return STUN_ADDRESS_IPV4;
273        case AF_INET6:
274          return STUN_ADDRESS_IPV6;
275      }
276      return STUN_ADDRESS_UNDEF;
277    }
278  
GetAddress()279    const rtc::SocketAddress& GetAddress() const { return address_; }
ipaddr()280    const rtc::IPAddress& ipaddr() const { return address_.ipaddr(); }
port()281    uint16_t port() const { return address_.port(); }
282  
SetAddress(const rtc::SocketAddress & addr)283    void SetAddress(const rtc::SocketAddress& addr) {
284      address_ = addr;
285      EnsureAddressLength();
286    }
SetIP(const rtc::IPAddress & ip)287    void SetIP(const rtc::IPAddress& ip) {
288      address_.SetIP(ip);
289      EnsureAddressLength();
290    }
SetPort(uint16_t port)291    void SetPort(uint16_t port) { address_.SetPort(port); }
292  
293    virtual bool Read(rtc::ByteBuffer* buf);
294    virtual bool Write(rtc::ByteBuffer* buf) const;
295  
296   private:
EnsureAddressLength()297    void EnsureAddressLength() {
298      switch (family()) {
299        case STUN_ADDRESS_IPV4: {
300          SetLength(SIZE_IP4);
301          break;
302        }
303        case STUN_ADDRESS_IPV6: {
304          SetLength(SIZE_IP6);
305          break;
306        }
307        default: {
308          SetLength(SIZE_UNDEF);
309          break;
310        }
311      }
312    }
313    rtc::SocketAddress address_;
314  };
315  
316  // Implements STUN attributes that record an Internet address. When encoded
317  // in a STUN message, the address contained in this attribute is XORed with the
318  // transaction ID of the message.
319  class StunXorAddressAttribute : public StunAddressAttribute {
320   public:
321    StunXorAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
322    StunXorAddressAttribute(uint16_t type, uint16_t length, StunMessage* owner);
323  
value_type()324    virtual StunAttributeValueType value_type() const {
325      return STUN_VALUE_XOR_ADDRESS;
326    }
SetOwner(StunMessage * owner)327    virtual void SetOwner(StunMessage* owner) {
328      owner_ = owner;
329    }
330    virtual bool Read(rtc::ByteBuffer* buf);
331    virtual bool Write(rtc::ByteBuffer* buf) const;
332  
333   private:
334    rtc::IPAddress GetXoredIP() const;
335    StunMessage* owner_;
336  };
337  
338  // Implements STUN attributes that record a 32-bit integer.
339  class StunUInt32Attribute : public StunAttribute {
340   public:
341    static const uint16_t SIZE = 4;
342    StunUInt32Attribute(uint16_t type, uint32_t value);
343    explicit StunUInt32Attribute(uint16_t type);
344  
value_type()345    virtual StunAttributeValueType value_type() const {
346      return STUN_VALUE_UINT32;
347    }
348  
value()349    uint32_t value() const { return bits_; }
SetValue(uint32_t bits)350    void SetValue(uint32_t bits) { bits_ = bits; }
351  
352    bool GetBit(size_t index) const;
353    void SetBit(size_t index, bool value);
354  
355    virtual bool Read(rtc::ByteBuffer* buf);
356    virtual bool Write(rtc::ByteBuffer* buf) const;
357  
358   private:
359    uint32_t bits_;
360  };
361  
362  class StunUInt64Attribute : public StunAttribute {
363   public:
364    static const uint16_t SIZE = 8;
365    StunUInt64Attribute(uint16_t type, uint64_t value);
366    explicit StunUInt64Attribute(uint16_t type);
367  
value_type()368    virtual StunAttributeValueType value_type() const {
369      return STUN_VALUE_UINT64;
370    }
371  
value()372    uint64_t value() const { return bits_; }
SetValue(uint64_t bits)373    void SetValue(uint64_t bits) { bits_ = bits; }
374  
375    virtual bool Read(rtc::ByteBuffer* buf);
376    virtual bool Write(rtc::ByteBuffer* buf) const;
377  
378   private:
379    uint64_t bits_;
380  };
381  
382  // Implements STUN attributes that record an arbitrary byte string.
383  class StunByteStringAttribute : public StunAttribute {
384   public:
385    explicit StunByteStringAttribute(uint16_t type);
386    StunByteStringAttribute(uint16_t type, const std::string& str);
387    StunByteStringAttribute(uint16_t type, const void* bytes, size_t length);
388    StunByteStringAttribute(uint16_t type, uint16_t length);
389    ~StunByteStringAttribute();
390  
value_type()391    virtual StunAttributeValueType value_type() const {
392      return STUN_VALUE_BYTE_STRING;
393    }
394  
bytes()395    const char* bytes() const { return bytes_; }
GetString()396    std::string GetString() const { return std::string(bytes_, length()); }
397  
398    void CopyBytes(const char* bytes);  // uses strlen
399    void CopyBytes(const void* bytes, size_t length);
400  
401    uint8_t GetByte(size_t index) const;
402    void SetByte(size_t index, uint8_t value);
403  
404    virtual bool Read(rtc::ByteBuffer* buf);
405    virtual bool Write(rtc::ByteBuffer* buf) const;
406  
407   private:
408    void SetBytes(char* bytes, size_t length);
409  
410    char* bytes_;
411  };
412  
413  // Implements STUN attributes that record an error code.
414  class StunErrorCodeAttribute : public StunAttribute {
415   public:
416    static const uint16_t MIN_SIZE = 4;
417    StunErrorCodeAttribute(uint16_t type, int code, const std::string& reason);
418    StunErrorCodeAttribute(uint16_t type, uint16_t length);
419    ~StunErrorCodeAttribute();
420  
value_type()421    virtual StunAttributeValueType value_type() const {
422      return STUN_VALUE_ERROR_CODE;
423    }
424  
425    // The combined error and class, e.g. 0x400.
426    int code() const;
427    void SetCode(int code);
428  
429    // The individual error components.
eclass()430    int eclass() const { return class_; }
number()431    int number() const { return number_; }
reason()432    const std::string& reason() const { return reason_; }
SetClass(uint8_t eclass)433    void SetClass(uint8_t eclass) { class_ = eclass; }
SetNumber(uint8_t number)434    void SetNumber(uint8_t number) { number_ = number; }
435    void SetReason(const std::string& reason);
436  
437    bool Read(rtc::ByteBuffer* buf);
438    bool Write(rtc::ByteBuffer* buf) const;
439  
440   private:
441    uint8_t class_;
442    uint8_t number_;
443    std::string reason_;
444  };
445  
446  // Implements STUN attributes that record a list of attribute names.
447  class StunUInt16ListAttribute : public StunAttribute {
448   public:
449    StunUInt16ListAttribute(uint16_t type, uint16_t length);
450    ~StunUInt16ListAttribute();
451  
value_type()452    virtual StunAttributeValueType value_type() const {
453      return STUN_VALUE_UINT16_LIST;
454    }
455  
456    size_t Size() const;
457    uint16_t GetType(int index) const;
458    void SetType(int index, uint16_t value);
459    void AddType(uint16_t value);
460  
461    bool Read(rtc::ByteBuffer* buf);
462    bool Write(rtc::ByteBuffer* buf) const;
463  
464   private:
465    std::vector<uint16_t>* attr_types_;
466  };
467  
468  // Returns the (successful) response type for the given request type.
469  // Returns -1 if |request_type| is not a valid request type.
470  int GetStunSuccessResponseType(int request_type);
471  
472  // Returns the error response type for the given request type.
473  // Returns -1 if |request_type| is not a valid request type.
474  int GetStunErrorResponseType(int request_type);
475  
476  // Returns whether a given message is a request type.
477  bool IsStunRequestType(int msg_type);
478  
479  // Returns whether a given message is an indication type.
480  bool IsStunIndicationType(int msg_type);
481  
482  // Returns whether a given response is a success type.
483  bool IsStunSuccessResponseType(int msg_type);
484  
485  // Returns whether a given response is an error type.
486  bool IsStunErrorResponseType(int msg_type);
487  
488  // Computes the STUN long-term credential hash.
489  bool ComputeStunCredentialHash(const std::string& username,
490      const std::string& realm, const std::string& password, std::string* hash);
491  
492  // TODO: Move the TURN/ICE stuff below out to separate files.
493  extern const char TURN_MAGIC_COOKIE_VALUE[4];
494  
495  // "GTURN" STUN methods.
496  // TODO: Rename these methods to GTURN_ to make it clear they aren't
497  // part of standard STUN/TURN.
498  enum RelayMessageType {
499    // For now, using the same defs from TurnMessageType below.
500    // STUN_ALLOCATE_REQUEST              = 0x0003,
501    // STUN_ALLOCATE_RESPONSE             = 0x0103,
502    // STUN_ALLOCATE_ERROR_RESPONSE       = 0x0113,
503    STUN_SEND_REQUEST                     = 0x0004,
504    STUN_SEND_RESPONSE                    = 0x0104,
505    STUN_SEND_ERROR_RESPONSE              = 0x0114,
506    STUN_DATA_INDICATION                  = 0x0115,
507  };
508  
509  // "GTURN"-specific STUN attributes.
510  // TODO: Rename these attributes to GTURN_ to avoid conflicts.
511  enum RelayAttributeType {
512    STUN_ATTR_LIFETIME                    = 0x000d,  // UInt32
513    STUN_ATTR_MAGIC_COOKIE                = 0x000f,  // ByteString, 4 bytes
514    STUN_ATTR_BANDWIDTH                   = 0x0010,  // UInt32
515    STUN_ATTR_DESTINATION_ADDRESS         = 0x0011,  // Address
516    STUN_ATTR_SOURCE_ADDRESS2             = 0x0012,  // Address
517    STUN_ATTR_DATA                        = 0x0013,  // ByteString
518    STUN_ATTR_OPTIONS                     = 0x8001,  // UInt32
519  };
520  
521  // A "GTURN" STUN message.
522  class RelayMessage : public StunMessage {
523   protected:
GetAttributeValueType(int type)524    virtual StunAttributeValueType GetAttributeValueType(int type) const {
525      switch (type) {
526        case STUN_ATTR_LIFETIME:            return STUN_VALUE_UINT32;
527        case STUN_ATTR_MAGIC_COOKIE:        return STUN_VALUE_BYTE_STRING;
528        case STUN_ATTR_BANDWIDTH:           return STUN_VALUE_UINT32;
529        case STUN_ATTR_DESTINATION_ADDRESS: return STUN_VALUE_ADDRESS;
530        case STUN_ATTR_SOURCE_ADDRESS2:     return STUN_VALUE_ADDRESS;
531        case STUN_ATTR_DATA:                return STUN_VALUE_BYTE_STRING;
532        case STUN_ATTR_OPTIONS:             return STUN_VALUE_UINT32;
533        default: return StunMessage::GetAttributeValueType(type);
534      }
535    }
CreateNew()536    virtual StunMessage* CreateNew() const { return new RelayMessage(); }
537  };
538  
539  // Defined in TURN RFC 5766.
540  enum TurnMessageType {
541    STUN_ALLOCATE_REQUEST                 = 0x0003,
542    STUN_ALLOCATE_RESPONSE                = 0x0103,
543    STUN_ALLOCATE_ERROR_RESPONSE          = 0x0113,
544    TURN_REFRESH_REQUEST                  = 0x0004,
545    TURN_REFRESH_RESPONSE                 = 0x0104,
546    TURN_REFRESH_ERROR_RESPONSE           = 0x0114,
547    TURN_SEND_INDICATION                  = 0x0016,
548    TURN_DATA_INDICATION                  = 0x0017,
549    TURN_CREATE_PERMISSION_REQUEST        = 0x0008,
550    TURN_CREATE_PERMISSION_RESPONSE       = 0x0108,
551    TURN_CREATE_PERMISSION_ERROR_RESPONSE = 0x0118,
552    TURN_CHANNEL_BIND_REQUEST             = 0x0009,
553    TURN_CHANNEL_BIND_RESPONSE            = 0x0109,
554    TURN_CHANNEL_BIND_ERROR_RESPONSE      = 0x0119,
555  };
556  
557  enum TurnAttributeType {
558    STUN_ATTR_CHANNEL_NUMBER              = 0x000C,  // UInt32
559    STUN_ATTR_TURN_LIFETIME               = 0x000d,  // UInt32
560    STUN_ATTR_XOR_PEER_ADDRESS            = 0x0012,  // XorAddress
561    // TODO(mallinath) - Uncomment after RelayAttributes are renamed.
562    // STUN_ATTR_DATA                     = 0x0013,  // ByteString
563    STUN_ATTR_XOR_RELAYED_ADDRESS         = 0x0016,  // XorAddress
564    STUN_ATTR_EVEN_PORT                   = 0x0018,  // ByteString, 1 byte.
565    STUN_ATTR_REQUESTED_TRANSPORT         = 0x0019,  // UInt32
566    STUN_ATTR_DONT_FRAGMENT               = 0x001A,  // No content, Length = 0
567    STUN_ATTR_RESERVATION_TOKEN           = 0x0022,  // ByteString, 8 bytes.
568    // TODO(mallinath) - Rename STUN_ATTR_TURN_LIFETIME to STUN_ATTR_LIFETIME and
569    // STUN_ATTR_TURN_DATA to STUN_ATTR_DATA. Also rename RelayMessage attributes
570    // by appending G to attribute name.
571  };
572  
573  // RFC 5766-defined errors.
574  enum TurnErrorType {
575    STUN_ERROR_FORBIDDEN                  = 403,
576    STUN_ERROR_ALLOCATION_MISMATCH        = 437,
577    STUN_ERROR_WRONG_CREDENTIALS          = 441,
578    STUN_ERROR_UNSUPPORTED_PROTOCOL       = 442
579  };
580  extern const char STUN_ERROR_REASON_FORBIDDEN[];
581  extern const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[];
582  extern const char STUN_ERROR_REASON_WRONG_CREDENTIALS[];
583  extern const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[];
584  class TurnMessage : public StunMessage {
585   protected:
GetAttributeValueType(int type)586    virtual StunAttributeValueType GetAttributeValueType(int type) const {
587      switch (type) {
588        case STUN_ATTR_CHANNEL_NUMBER:      return STUN_VALUE_UINT32;
589        case STUN_ATTR_TURN_LIFETIME:       return STUN_VALUE_UINT32;
590        case STUN_ATTR_XOR_PEER_ADDRESS:    return STUN_VALUE_XOR_ADDRESS;
591        case STUN_ATTR_DATA:                return STUN_VALUE_BYTE_STRING;
592        case STUN_ATTR_XOR_RELAYED_ADDRESS: return STUN_VALUE_XOR_ADDRESS;
593        case STUN_ATTR_EVEN_PORT:           return STUN_VALUE_BYTE_STRING;
594        case STUN_ATTR_REQUESTED_TRANSPORT: return STUN_VALUE_UINT32;
595        case STUN_ATTR_DONT_FRAGMENT:       return STUN_VALUE_BYTE_STRING;
596        case STUN_ATTR_RESERVATION_TOKEN:   return STUN_VALUE_BYTE_STRING;
597        default: return StunMessage::GetAttributeValueType(type);
598      }
599    }
CreateNew()600    virtual StunMessage* CreateNew() const { return new TurnMessage(); }
601  };
602  
603  // RFC 5245 ICE STUN attributes.
604  enum IceAttributeType {
605    STUN_ATTR_PRIORITY                    = 0x0024,  // UInt32
606    STUN_ATTR_USE_CANDIDATE               = 0x0025,  // No content, Length = 0
607    STUN_ATTR_ICE_CONTROLLED              = 0x8029,  // UInt64
608    STUN_ATTR_ICE_CONTROLLING             = 0x802A   // UInt64
609  };
610  
611  // RFC 5245-defined errors.
612  enum IceErrorCode {
613    STUN_ERROR_ROLE_CONFLICT              = 487,
614  };
615  extern const char STUN_ERROR_REASON_ROLE_CONFLICT[];
616  
617  // A RFC 5245 ICE STUN message.
618  class IceMessage : public StunMessage {
619   protected:
GetAttributeValueType(int type)620    virtual StunAttributeValueType GetAttributeValueType(int type) const {
621      switch (type) {
622        case STUN_ATTR_PRIORITY:        return STUN_VALUE_UINT32;
623        case STUN_ATTR_USE_CANDIDATE:   return STUN_VALUE_BYTE_STRING;
624        case STUN_ATTR_ICE_CONTROLLED:  return STUN_VALUE_UINT64;
625        case STUN_ATTR_ICE_CONTROLLING: return STUN_VALUE_UINT64;
626        default: return StunMessage::GetAttributeValueType(type);
627      }
628    }
CreateNew()629    virtual StunMessage* CreateNew() const { return new IceMessage(); }
630  };
631  
632  }  // namespace cricket
633  
634  #endif  // WEBRTC_P2P_BASE_STUN_H_
635