blob: 33410b5bae51bc4ee61da3d202e668257b33dd96 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef P2P_BASE_STUN_H_
12#define P2P_BASE_STUN_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
14// This file contains classes for dealing with the STUN protocol, as specified
15// in RFC 5389, and its descendants.
16
Yves Gerey3e707812018-11-28 16:47:49 +010017#include <stddef.h>
18#include <stdint.h>
Steve Anton6c38cc72017-11-29 10:25:58 -080019#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020#include <string>
21#include <vector>
22
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/byte_buffer.h"
24#include "rtc_base/ip_address.h"
25#include "rtc_base/socket_address.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000026
27namespace cricket {
28
29// These are the types of STUN messages defined in RFC 5389.
30enum StunMessageType {
Yves Gerey665174f2018-06-19 15:03:05 +020031 STUN_BINDING_REQUEST = 0x0001,
32 STUN_BINDING_INDICATION = 0x0011,
33 STUN_BINDING_RESPONSE = 0x0101,
34 STUN_BINDING_ERROR_RESPONSE = 0x0111,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000035};
36
37// These are all known STUN attributes, defined in RFC 5389 and elsewhere.
38// Next to each is the name of the class (T is StunTAttribute) that implements
39// that type.
40// RETRANSMIT_COUNT is the number of outstanding pings without a response at
41// the time the packet is generated.
42enum StunAttributeType {
Yves Gerey665174f2018-06-19 15:03:05 +020043 STUN_ATTR_MAPPED_ADDRESS = 0x0001, // Address
44 STUN_ATTR_USERNAME = 0x0006, // ByteString
45 STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, // ByteString, 20 bytes
46 STUN_ATTR_ERROR_CODE = 0x0009, // ErrorCode
47 STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, // UInt16List
48 STUN_ATTR_REALM = 0x0014, // ByteString
49 STUN_ATTR_NONCE = 0x0015, // ByteString
50 STUN_ATTR_XOR_MAPPED_ADDRESS = 0x0020, // XorAddress
51 STUN_ATTR_SOFTWARE = 0x8022, // ByteString
52 STUN_ATTR_ALTERNATE_SERVER = 0x8023, // Address
53 STUN_ATTR_FINGERPRINT = 0x8028, // UInt32
54 STUN_ATTR_ORIGIN = 0x802F, // ByteString
55 STUN_ATTR_RETRANSMIT_COUNT = 0xFF00 // UInt32
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056};
57
58// These are the types of the values associated with the attributes above.
59// This allows us to perform some basic validation when reading or adding
60// attributes. Note that these values are for our own use, and not defined in
61// RFC 5389.
62enum StunAttributeValueType {
Yves Gerey665174f2018-06-19 15:03:05 +020063 STUN_VALUE_UNKNOWN = 0,
64 STUN_VALUE_ADDRESS = 1,
65 STUN_VALUE_XOR_ADDRESS = 2,
66 STUN_VALUE_UINT32 = 3,
67 STUN_VALUE_UINT64 = 4,
68 STUN_VALUE_BYTE_STRING = 5,
69 STUN_VALUE_ERROR_CODE = 6,
70 STUN_VALUE_UINT16_LIST = 7
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071};
72
73// These are the types of STUN addresses defined in RFC 5389.
74enum StunAddressFamily {
75 // NB: UNDEF is not part of the STUN spec.
Yves Gerey665174f2018-06-19 15:03:05 +020076 STUN_ADDRESS_UNDEF = 0,
77 STUN_ADDRESS_IPV4 = 1,
78 STUN_ADDRESS_IPV6 = 2
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000079};
80
81// These are the types of STUN error codes defined in RFC 5389.
82enum StunErrorCode {
Yves Gerey665174f2018-06-19 15:03:05 +020083 STUN_ERROR_TRY_ALTERNATE = 300,
84 STUN_ERROR_BAD_REQUEST = 400,
85 STUN_ERROR_UNAUTHORIZED = 401,
86 STUN_ERROR_UNKNOWN_ATTRIBUTE = 420,
87 STUN_ERROR_STALE_CREDENTIALS = 430, // GICE only
88 STUN_ERROR_STALE_NONCE = 438,
89 STUN_ERROR_SERVER_ERROR = 500,
90 STUN_ERROR_GLOBAL_FAILURE = 600
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000091};
92
93// Strings for the error codes above.
94extern const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[];
95extern const char STUN_ERROR_REASON_BAD_REQUEST[];
96extern const char STUN_ERROR_REASON_UNAUTHORIZED[];
97extern const char STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE[];
98extern const char STUN_ERROR_REASON_STALE_CREDENTIALS[];
99extern const char STUN_ERROR_REASON_STALE_NONCE[];
100extern const char STUN_ERROR_REASON_SERVER_ERROR[];
101
102// The mask used to determine whether a STUN message is a request/response etc.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200103const uint32_t kStunTypeMask = 0x0110;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000104
105// STUN Attribute header length.
106const size_t kStunAttributeHeaderSize = 4;
107
108// Following values correspond to RFC5389.
109const size_t kStunHeaderSize = 20;
110const size_t kStunTransactionIdOffset = 8;
111const size_t kStunTransactionIdLength = 12;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200112const uint32_t kStunMagicCookie = 0x2112A442;
Andrew Royes154d8392019-03-14 10:38:31 -0700113constexpr size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000114
115// Following value corresponds to an earlier version of STUN from
116// RFC3489.
117const size_t kStunLegacyTransactionIdLength = 16;
118
119// STUN Message Integrity HMAC length.
120const size_t kStunMessageIntegritySize = 20;
121
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000122class StunAddressAttribute;
Yves Gerey3e707812018-11-28 16:47:49 +0100123class StunAttribute;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000124class StunByteStringAttribute;
125class StunErrorCodeAttribute;
Yves Gerey3e707812018-11-28 16:47:49 +0100126
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000127class StunUInt16ListAttribute;
Yves Gerey3e707812018-11-28 16:47:49 +0100128class StunUInt32Attribute;
129class StunUInt64Attribute;
130class StunXorAddressAttribute;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000131
132// Records a complete STUN/TURN message. Each message consists of a type and
133// any number of attributes. Each attribute is parsed into an instance of an
134// appropriate class (see above). The Get* methods will return instances of
135// that attribute class.
136class StunMessage {
137 public:
138 StunMessage();
Steve Antonca7d54e2017-10-25 14:42:51 -0700139 virtual ~StunMessage();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000140
141 int type() const { return type_; }
142 size_t length() const { return length_; }
143 const std::string& transaction_id() const { return transaction_id_; }
Zach Stein92c42892018-11-28 11:38:52 -0800144 uint32_t reduced_transaction_id() const { return reduced_transaction_id_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000145
146 // Returns true if the message confirms to RFC3489 rather than
147 // RFC5389. The main difference between two version of the STUN
148 // protocol is the presence of the magic cookie and different length
149 // of transaction ID. For outgoing packets version of the protocol
150 // is determined by the lengths of the transaction ID.
151 bool IsLegacy() const;
152
Peter Boström0c4e06b2015-10-07 12:23:21 +0200153 void SetType(int type) { type_ = static_cast<uint16_t>(type); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 bool SetTransactionID(const std::string& str);
155
156 // Gets the desired attribute value, or NULL if no such attribute type exists.
157 const StunAddressAttribute* GetAddress(int type) const;
158 const StunUInt32Attribute* GetUInt32(int type) const;
159 const StunUInt64Attribute* GetUInt64(int type) const;
160 const StunByteStringAttribute* GetByteString(int type) const;
161
162 // Gets these specific attribute values.
163 const StunErrorCodeAttribute* GetErrorCode() const;
deadbeef996fc6b2017-04-26 09:21:22 -0700164 // Returns the code inside the error code attribute, if present, and
165 // STUN_ERROR_GLOBAL_FAILURE otherwise.
166 int GetErrorCodeValue() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000167 const StunUInt16ListAttribute* GetUnknownAttributes() const;
168
nissecc99bc22017-02-02 01:31:30 -0800169 // Takes ownership of the specified attribute and adds it to the message.
zsteinf42cc9d2017-03-27 16:17:19 -0700170 void AddAttribute(std::unique_ptr<StunAttribute> attr);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000171
Jonas Oreland202994c2017-12-18 12:10:43 +0100172 // Remove the last occurrence of an attribute.
173 std::unique_ptr<StunAttribute> RemoveAttribute(int type);
174
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000175 // Validates that a raw STUN message has a correct MESSAGE-INTEGRITY value.
176 // This can't currently be done on a StunMessage, since it is affected by
177 // padding data (which we discard when reading a StunMessage).
Yves Gerey665174f2018-06-19 15:03:05 +0200178 static bool ValidateMessageIntegrity(const char* data,
179 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000180 const std::string& password);
181 // Adds a MESSAGE-INTEGRITY attribute that is valid for the current message.
182 bool AddMessageIntegrity(const std::string& password);
183 bool AddMessageIntegrity(const char* key, size_t keylen);
184
185 // Verifies that a given buffer is STUN by checking for a correct FINGERPRINT.
186 static bool ValidateFingerprint(const char* data, size_t size);
187
188 // Adds a FINGERPRINT attribute that is valid for the current message.
189 bool AddFingerprint();
190
191 // Parses the STUN packet in the given buffer and records it here. The
192 // return value indicates whether this was successful.
jbauchf1f87202016-03-30 06:43:37 -0700193 bool Read(rtc::ByteBufferReader* buf);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194
195 // Writes this object into a STUN packet. The return value indicates whether
196 // this was successful.
jbauchf1f87202016-03-30 06:43:37 -0700197 bool Write(rtc::ByteBufferWriter* buf) const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000198
199 // Creates an empty message. Overridable by derived classes.
Steve Antonca7d54e2017-10-25 14:42:51 -0700200 virtual StunMessage* CreateNew() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000201
Jonas Oreland7ca63112018-02-27 08:45:13 +0100202 // Modify the stun magic cookie used for this STUN message.
203 // This is used for testing.
204 void SetStunMagicCookie(uint32_t val);
205
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206 protected:
207 // Verifies that the given attribute is allowed for this message.
208 virtual StunAttributeValueType GetAttributeValueType(int type) const;
209
210 private:
211 StunAttribute* CreateAttribute(int type, size_t length) /* const*/;
212 const StunAttribute* GetAttribute(int type) const;
213 static bool IsValidTransactionId(const std::string& transaction_id);
214
Peter Boström0c4e06b2015-10-07 12:23:21 +0200215 uint16_t type_;
216 uint16_t length_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217 std::string transaction_id_;
Zach Stein92c42892018-11-28 11:38:52 -0800218 uint32_t reduced_transaction_id_;
zsteinad94c4c2017-03-06 13:36:05 -0800219 std::vector<std::unique_ptr<StunAttribute>> attrs_;
Jonas Oreland7ca63112018-02-27 08:45:13 +0100220 uint32_t stun_magic_cookie_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000221};
222
223// Base class for all STUN/TURN attributes.
224class StunAttribute {
225 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200226 virtual ~StunAttribute() {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227
228 int type() const { return type_; }
229 size_t length() const { return length_; }
230
231 // Return the type of this attribute.
232 virtual StunAttributeValueType value_type() const = 0;
233
234 // Only XorAddressAttribute needs this so far.
235 virtual void SetOwner(StunMessage* owner) {}
236
237 // Reads the body (not the type or length) for this type of attribute from
238 // the given buffer. Return value is true if successful.
jbauchf1f87202016-03-30 06:43:37 -0700239 virtual bool Read(rtc::ByteBufferReader* buf) = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000240
241 // Writes the body (not the type or length) to the given buffer. Return
242 // value is true if successful.
jbauchf1f87202016-03-30 06:43:37 -0700243 virtual bool Write(rtc::ByteBufferWriter* buf) const = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000244
245 // Creates an attribute object with the given type and smallest length.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200246 static StunAttribute* Create(StunAttributeValueType value_type,
247 uint16_t type,
248 uint16_t length,
249 StunMessage* owner);
Steve Anton6c38cc72017-11-29 10:25:58 -0800250 // TODO(?): Allow these create functions to take parameters, to reduce
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000251 // the amount of work callers need to do to initialize attributes.
zsteinf42cc9d2017-03-27 16:17:19 -0700252 static std::unique_ptr<StunAddressAttribute> CreateAddress(uint16_t type);
253 static std::unique_ptr<StunXorAddressAttribute> CreateXorAddress(
254 uint16_t type);
255 static std::unique_ptr<StunUInt32Attribute> CreateUInt32(uint16_t type);
256 static std::unique_ptr<StunUInt64Attribute> CreateUInt64(uint16_t type);
257 static std::unique_ptr<StunByteStringAttribute> CreateByteString(
258 uint16_t type);
259 static std::unique_ptr<StunErrorCodeAttribute> CreateErrorCode();
260 static std::unique_ptr<StunUInt16ListAttribute> CreateUnknownAttributes();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000261
262 protected:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200263 StunAttribute(uint16_t type, uint16_t length);
264 void SetLength(uint16_t length) { length_ = length; }
jbauchf1f87202016-03-30 06:43:37 -0700265 void WritePadding(rtc::ByteBufferWriter* buf) const;
266 void ConsumePadding(rtc::ByteBufferReader* buf) const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000267
268 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200269 uint16_t type_;
270 uint16_t length_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000271};
272
273// Implements STUN attributes that record an Internet address.
274class StunAddressAttribute : public StunAttribute {
275 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200276 static const uint16_t SIZE_UNDEF = 0;
277 static const uint16_t SIZE_IP4 = 8;
278 static const uint16_t SIZE_IP6 = 20;
279 StunAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
280 StunAddressAttribute(uint16_t type, uint16_t length);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000281
Steve Antonca7d54e2017-10-25 14:42:51 -0700282 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000283
284 StunAddressFamily family() const {
285 switch (address_.ipaddr().family()) {
286 case AF_INET:
287 return STUN_ADDRESS_IPV4;
288 case AF_INET6:
289 return STUN_ADDRESS_IPV6;
290 }
291 return STUN_ADDRESS_UNDEF;
292 }
293
294 const rtc::SocketAddress& GetAddress() const { return address_; }
295 const rtc::IPAddress& ipaddr() const { return address_.ipaddr(); }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200296 uint16_t port() const { return address_.port(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000297
298 void SetAddress(const rtc::SocketAddress& addr) {
299 address_ = addr;
300 EnsureAddressLength();
301 }
302 void SetIP(const rtc::IPAddress& ip) {
303 address_.SetIP(ip);
304 EnsureAddressLength();
305 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200306 void SetPort(uint16_t port) { address_.SetPort(port); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000307
Steve Antonca7d54e2017-10-25 14:42:51 -0700308 bool Read(rtc::ByteBufferReader* buf) override;
309 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000310
311 private:
312 void EnsureAddressLength() {
313 switch (family()) {
314 case STUN_ADDRESS_IPV4: {
315 SetLength(SIZE_IP4);
316 break;
317 }
318 case STUN_ADDRESS_IPV6: {
319 SetLength(SIZE_IP6);
320 break;
321 }
322 default: {
323 SetLength(SIZE_UNDEF);
324 break;
325 }
326 }
327 }
328 rtc::SocketAddress address_;
329};
330
331// Implements STUN attributes that record an Internet address. When encoded
332// in a STUN message, the address contained in this attribute is XORed with the
333// transaction ID of the message.
334class StunXorAddressAttribute : public StunAddressAttribute {
335 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200336 StunXorAddressAttribute(uint16_t type, const rtc::SocketAddress& addr);
337 StunXorAddressAttribute(uint16_t type, uint16_t length, StunMessage* owner);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000338
Steve Antonca7d54e2017-10-25 14:42:51 -0700339 StunAttributeValueType value_type() const override;
340 void SetOwner(StunMessage* owner) override;
341 bool Read(rtc::ByteBufferReader* buf) override;
342 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000343
344 private:
345 rtc::IPAddress GetXoredIP() const;
346 StunMessage* owner_;
347};
348
349// Implements STUN attributes that record a 32-bit integer.
350class StunUInt32Attribute : public StunAttribute {
351 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200352 static const uint16_t SIZE = 4;
353 StunUInt32Attribute(uint16_t type, uint32_t value);
354 explicit StunUInt32Attribute(uint16_t type);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000355
Steve Antonca7d54e2017-10-25 14:42:51 -0700356 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000357
Peter Boström0c4e06b2015-10-07 12:23:21 +0200358 uint32_t value() const { return bits_; }
359 void SetValue(uint32_t bits) { bits_ = bits; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000360
361 bool GetBit(size_t index) const;
362 void SetBit(size_t index, bool value);
363
Steve Antonca7d54e2017-10-25 14:42:51 -0700364 bool Read(rtc::ByteBufferReader* buf) override;
365 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000366
367 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200368 uint32_t bits_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000369};
370
371class StunUInt64Attribute : public StunAttribute {
372 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200373 static const uint16_t SIZE = 8;
374 StunUInt64Attribute(uint16_t type, uint64_t value);
375 explicit StunUInt64Attribute(uint16_t type);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000376
Steve Antonca7d54e2017-10-25 14:42:51 -0700377 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000378
Peter Boström0c4e06b2015-10-07 12:23:21 +0200379 uint64_t value() const { return bits_; }
380 void SetValue(uint64_t bits) { bits_ = bits; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000381
Steve Antonca7d54e2017-10-25 14:42:51 -0700382 bool Read(rtc::ByteBufferReader* buf) override;
383 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000384
385 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200386 uint64_t bits_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000387};
388
389// Implements STUN attributes that record an arbitrary byte string.
390class StunByteStringAttribute : public StunAttribute {
391 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200392 explicit StunByteStringAttribute(uint16_t type);
393 StunByteStringAttribute(uint16_t type, const std::string& str);
394 StunByteStringAttribute(uint16_t type, const void* bytes, size_t length);
395 StunByteStringAttribute(uint16_t type, uint16_t length);
Steve Antonca7d54e2017-10-25 14:42:51 -0700396 ~StunByteStringAttribute() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000397
Steve Antonca7d54e2017-10-25 14:42:51 -0700398 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000399
400 const char* bytes() const { return bytes_; }
401 std::string GetString() const { return std::string(bytes_, length()); }
402
403 void CopyBytes(const char* bytes); // uses strlen
404 void CopyBytes(const void* bytes, size_t length);
405
Peter Boström0c4e06b2015-10-07 12:23:21 +0200406 uint8_t GetByte(size_t index) const;
407 void SetByte(size_t index, uint8_t value);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000408
Steve Antonca7d54e2017-10-25 14:42:51 -0700409 bool Read(rtc::ByteBufferReader* buf) override;
410 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000411
412 private:
413 void SetBytes(char* bytes, size_t length);
414
415 char* bytes_;
416};
417
418// Implements STUN attributes that record an error code.
419class StunErrorCodeAttribute : public StunAttribute {
420 public:
zsteinf42cc9d2017-03-27 16:17:19 -0700421 static const uint16_t MIN_SIZE;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200422 StunErrorCodeAttribute(uint16_t type, int code, const std::string& reason);
423 StunErrorCodeAttribute(uint16_t type, uint16_t length);
Steve Antonca7d54e2017-10-25 14:42:51 -0700424 ~StunErrorCodeAttribute() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000425
Steve Antonca7d54e2017-10-25 14:42:51 -0700426 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000427
428 // The combined error and class, e.g. 0x400.
429 int code() const;
430 void SetCode(int code);
431
432 // The individual error components.
433 int eclass() const { return class_; }
434 int number() const { return number_; }
435 const std::string& reason() const { return reason_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200436 void SetClass(uint8_t eclass) { class_ = eclass; }
437 void SetNumber(uint8_t number) { number_ = number; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000438 void SetReason(const std::string& reason);
439
Steve Antonca7d54e2017-10-25 14:42:51 -0700440 bool Read(rtc::ByteBufferReader* buf) override;
441 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000442
443 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200444 uint8_t class_;
445 uint8_t number_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000446 std::string reason_;
447};
448
449// Implements STUN attributes that record a list of attribute names.
450class StunUInt16ListAttribute : public StunAttribute {
451 public:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200452 StunUInt16ListAttribute(uint16_t type, uint16_t length);
Steve Antonca7d54e2017-10-25 14:42:51 -0700453 ~StunUInt16ListAttribute() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000454
Steve Antonca7d54e2017-10-25 14:42:51 -0700455 StunAttributeValueType value_type() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000456
457 size_t Size() const;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200458 uint16_t GetType(int index) const;
459 void SetType(int index, uint16_t value);
460 void AddType(uint16_t value);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000461
Steve Antonca7d54e2017-10-25 14:42:51 -0700462 bool Read(rtc::ByteBufferReader* buf) override;
463 bool Write(rtc::ByteBufferWriter* buf) const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000464
465 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200466 std::vector<uint16_t>* attr_types_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000467};
468
469// Returns the (successful) response type for the given request type.
470// Returns -1 if |request_type| is not a valid request type.
471int GetStunSuccessResponseType(int request_type);
472
473// Returns the error response type for the given request type.
474// Returns -1 if |request_type| is not a valid request type.
475int GetStunErrorResponseType(int request_type);
476
477// Returns whether a given message is a request type.
478bool IsStunRequestType(int msg_type);
479
480// Returns whether a given message is an indication type.
481bool IsStunIndicationType(int msg_type);
482
483// Returns whether a given response is a success type.
484bool IsStunSuccessResponseType(int msg_type);
485
486// Returns whether a given response is an error type.
487bool IsStunErrorResponseType(int msg_type);
488
489// Computes the STUN long-term credential hash.
490bool ComputeStunCredentialHash(const std::string& username,
Yves Gerey665174f2018-06-19 15:03:05 +0200491 const std::string& realm,
492 const std::string& password,
493 std::string* hash);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000494
Jonas Oreland202994c2017-12-18 12:10:43 +0100495// Make a copy af |attribute| and return a new StunAttribute.
496// This is useful if you don't care about what kind of attribute you
497// are handling.
498//
499// The implementation copies by calling Write() followed by Read().
500//
501// If |tmp_buffer| is supplied this buffer will be used, otherwise
502// a buffer will created in the method.
503std::unique_ptr<StunAttribute> CopyStunAttribute(
504 const StunAttribute& attribute,
505 rtc::ByteBufferWriter* tmp_buffer_ptr = 0);
506
Steve Anton6c38cc72017-11-29 10:25:58 -0800507// TODO(?): Move the TURN/ICE stuff below out to separate files.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000508extern const char TURN_MAGIC_COOKIE_VALUE[4];
509
510// "GTURN" STUN methods.
Steve Anton6c38cc72017-11-29 10:25:58 -0800511// TODO(?): Rename these methods to GTURN_ to make it clear they aren't
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000512// part of standard STUN/TURN.
513enum RelayMessageType {
514 // For now, using the same defs from TurnMessageType below.
515 // STUN_ALLOCATE_REQUEST = 0x0003,
516 // STUN_ALLOCATE_RESPONSE = 0x0103,
517 // STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
Yves Gerey665174f2018-06-19 15:03:05 +0200518 STUN_SEND_REQUEST = 0x0004,
519 STUN_SEND_RESPONSE = 0x0104,
520 STUN_SEND_ERROR_RESPONSE = 0x0114,
521 STUN_DATA_INDICATION = 0x0115,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000522};
523
524// "GTURN"-specific STUN attributes.
Steve Anton6c38cc72017-11-29 10:25:58 -0800525// TODO(?): Rename these attributes to GTURN_ to avoid conflicts.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000526enum RelayAttributeType {
Yves Gerey665174f2018-06-19 15:03:05 +0200527 STUN_ATTR_LIFETIME = 0x000d, // UInt32
528 STUN_ATTR_MAGIC_COOKIE = 0x000f, // ByteString, 4 bytes
529 STUN_ATTR_BANDWIDTH = 0x0010, // UInt32
530 STUN_ATTR_DESTINATION_ADDRESS = 0x0011, // Address
531 STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, // Address
532 STUN_ATTR_DATA = 0x0013, // ByteString
533 STUN_ATTR_OPTIONS = 0x8001, // UInt32
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000534};
535
536// A "GTURN" STUN message.
537class RelayMessage : public StunMessage {
538 protected:
Steve Antonca7d54e2017-10-25 14:42:51 -0700539 StunAttributeValueType GetAttributeValueType(int type) const override;
540 StunMessage* CreateNew() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000541};
542
543// Defined in TURN RFC 5766.
544enum TurnMessageType {
Yves Gerey665174f2018-06-19 15:03:05 +0200545 STUN_ALLOCATE_REQUEST = 0x0003,
546 STUN_ALLOCATE_RESPONSE = 0x0103,
547 STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
548 TURN_REFRESH_REQUEST = 0x0004,
549 TURN_REFRESH_RESPONSE = 0x0104,
550 TURN_REFRESH_ERROR_RESPONSE = 0x0114,
551 TURN_SEND_INDICATION = 0x0016,
552 TURN_DATA_INDICATION = 0x0017,
553 TURN_CREATE_PERMISSION_REQUEST = 0x0008,
554 TURN_CREATE_PERMISSION_RESPONSE = 0x0108,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000555 TURN_CREATE_PERMISSION_ERROR_RESPONSE = 0x0118,
Yves Gerey665174f2018-06-19 15:03:05 +0200556 TURN_CHANNEL_BIND_REQUEST = 0x0009,
557 TURN_CHANNEL_BIND_RESPONSE = 0x0109,
558 TURN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000559};
560
561enum TurnAttributeType {
Yves Gerey665174f2018-06-19 15:03:05 +0200562 STUN_ATTR_CHANNEL_NUMBER = 0x000C, // UInt32
563 STUN_ATTR_TURN_LIFETIME = 0x000d, // UInt32
564 STUN_ATTR_XOR_PEER_ADDRESS = 0x0012, // XorAddress
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000565 // TODO(mallinath) - Uncomment after RelayAttributes are renamed.
566 // STUN_ATTR_DATA = 0x0013, // ByteString
Yves Gerey665174f2018-06-19 15:03:05 +0200567 STUN_ATTR_XOR_RELAYED_ADDRESS = 0x0016, // XorAddress
568 STUN_ATTR_EVEN_PORT = 0x0018, // ByteString, 1 byte.
569 STUN_ATTR_REQUESTED_TRANSPORT = 0x0019, // UInt32
570 STUN_ATTR_DONT_FRAGMENT = 0x001A, // No content, Length = 0
571 STUN_ATTR_RESERVATION_TOKEN = 0x0022, // ByteString, 8 bytes.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000572 // TODO(mallinath) - Rename STUN_ATTR_TURN_LIFETIME to STUN_ATTR_LIFETIME and
573 // STUN_ATTR_TURN_DATA to STUN_ATTR_DATA. Also rename RelayMessage attributes
574 // by appending G to attribute name.
575};
576
577// RFC 5766-defined errors.
578enum TurnErrorType {
Yves Gerey665174f2018-06-19 15:03:05 +0200579 STUN_ERROR_FORBIDDEN = 403,
580 STUN_ERROR_ALLOCATION_MISMATCH = 437,
581 STUN_ERROR_WRONG_CREDENTIALS = 441,
582 STUN_ERROR_UNSUPPORTED_PROTOCOL = 442
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000583};
Eldar Relloda13ea22019-06-01 12:23:43 +0300584
585extern const int SERVER_NOT_REACHABLE_ERROR;
586
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000587extern const char STUN_ERROR_REASON_FORBIDDEN[];
588extern const char STUN_ERROR_REASON_ALLOCATION_MISMATCH[];
589extern const char STUN_ERROR_REASON_WRONG_CREDENTIALS[];
590extern const char STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL[];
591class TurnMessage : public StunMessage {
592 protected:
Steve Antonca7d54e2017-10-25 14:42:51 -0700593 StunAttributeValueType GetAttributeValueType(int type) const override;
594 StunMessage* CreateNew() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000595};
596
597// RFC 5245 ICE STUN attributes.
598enum IceAttributeType {
honghaize1a0c942016-02-16 14:54:56 -0800599 STUN_ATTR_PRIORITY = 0x0024, // UInt32
600 STUN_ATTR_USE_CANDIDATE = 0x0025, // No content, Length = 0
601 STUN_ATTR_ICE_CONTROLLED = 0x8029, // UInt64
602 STUN_ATTR_ICE_CONTROLLING = 0x802A, // UInt64
Honghai Zhang8cd8f812016-08-03 19:50:41 -0700603 STUN_ATTR_NOMINATION = 0xC001, // UInt32
honghaiza0c44ea2016-03-23 16:07:48 -0700604 // UInt32. The higher 16 bits are the network ID. The lower 16 bits are the
605 // network cost.
606 STUN_ATTR_NETWORK_INFO = 0xC057
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000607};
608
609// RFC 5245-defined errors.
610enum IceErrorCode {
Yves Gerey665174f2018-06-19 15:03:05 +0200611 STUN_ERROR_ROLE_CONFLICT = 487,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000612};
613extern const char STUN_ERROR_REASON_ROLE_CONFLICT[];
614
615// A RFC 5245 ICE STUN message.
616class IceMessage : public StunMessage {
617 protected:
Steve Antonca7d54e2017-10-25 14:42:51 -0700618 StunAttributeValueType GetAttributeValueType(int type) const override;
619 StunMessage* CreateNew() const override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000620};
621
622} // namespace cricket
623
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200624#endif // P2P_BASE_STUN_H_