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