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