OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/p2p/base/stun.h" | 11 #include "webrtc/p2p/base/stun.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <memory> | 15 #include <memory> |
16 | 16 |
17 #include "webrtc/base/byteorder.h" | 17 #include "webrtc/base/byteorder.h" |
18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/crc32.h" | 19 #include "webrtc/base/crc32.h" |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
21 #include "webrtc/base/messagedigest.h" | 21 #include "webrtc/base/messagedigest.h" |
| 22 #include "webrtc/base/ptr_util.h" |
22 #include "webrtc/base/stringencode.h" | 23 #include "webrtc/base/stringencode.h" |
23 | 24 |
24 using rtc::ByteBufferReader; | 25 using rtc::ByteBufferReader; |
25 using rtc::ByteBufferWriter; | 26 using rtc::ByteBufferWriter; |
26 | 27 |
27 namespace cricket { | 28 namespace cricket { |
28 | 29 |
29 const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server"; | 30 const char STUN_ERROR_REASON_TRY_ALTERNATE_SERVER[] = "Try Alternate Server"; |
30 const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request"; | 31 const char STUN_ERROR_REASON_BAD_REQUEST[] = "Bad Request"; |
31 const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized"; | 32 const char STUN_ERROR_REASON_UNAUTHORIZED[] = "Unauthorized"; |
(...skipping 27 matching lines...) Expand all Loading... |
59 } | 60 } |
60 | 61 |
61 bool StunMessage::SetTransactionID(const std::string& str) { | 62 bool StunMessage::SetTransactionID(const std::string& str) { |
62 if (!IsValidTransactionId(str)) { | 63 if (!IsValidTransactionId(str)) { |
63 return false; | 64 return false; |
64 } | 65 } |
65 transaction_id_ = str; | 66 transaction_id_ = str; |
66 return true; | 67 return true; |
67 } | 68 } |
68 | 69 |
69 void StunMessage::AddAttribute(StunAttribute* attr) { | 70 void StunMessage::AddAttribute(std::unique_ptr<StunAttribute> attr) { |
70 // Fail any attributes that aren't valid for this type of message. | 71 // Fail any attributes that aren't valid for this type of message. |
71 RTC_DCHECK_EQ(attr->value_type(), GetAttributeValueType(attr->type())); | 72 RTC_DCHECK_EQ(attr->value_type(), GetAttributeValueType(attr->type())); |
72 | 73 |
73 attrs_.emplace_back(attr); | |
74 attr->SetOwner(this); | 74 attr->SetOwner(this); |
75 size_t attr_length = attr->length(); | 75 size_t attr_length = attr->length(); |
76 if (attr_length % 4 != 0) { | 76 if (attr_length % 4 != 0) { |
77 attr_length += (4 - (attr_length % 4)); | 77 attr_length += (4 - (attr_length % 4)); |
78 } | 78 } |
79 length_ += static_cast<uint16_t>(attr_length + 4); | 79 length_ += static_cast<uint16_t>(attr_length + 4); |
| 80 |
| 81 attrs_.push_back(std::move(attr)); |
80 } | 82 } |
81 | 83 |
82 const StunAddressAttribute* StunMessage::GetAddress(int type) const { | 84 const StunAddressAttribute* StunMessage::GetAddress(int type) const { |
83 switch (type) { | 85 switch (type) { |
84 case STUN_ATTR_MAPPED_ADDRESS: { | 86 case STUN_ATTR_MAPPED_ADDRESS: { |
85 // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is | 87 // Return XOR-MAPPED-ADDRESS when MAPPED-ADDRESS attribute is |
86 // missing. | 88 // missing. |
87 const StunAttribute* mapped_address = | 89 const StunAttribute* mapped_address = |
88 GetAttribute(STUN_ATTR_MAPPED_ADDRESS); | 90 GetAttribute(STUN_ATTR_MAPPED_ADDRESS); |
89 if (!mapped_address) | 91 if (!mapped_address) |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 } | 202 } |
201 | 203 |
202 bool StunMessage::AddMessageIntegrity(const std::string& password) { | 204 bool StunMessage::AddMessageIntegrity(const std::string& password) { |
203 return AddMessageIntegrity(password.c_str(), password.size()); | 205 return AddMessageIntegrity(password.c_str(), password.size()); |
204 } | 206 } |
205 | 207 |
206 bool StunMessage::AddMessageIntegrity(const char* key, | 208 bool StunMessage::AddMessageIntegrity(const char* key, |
207 size_t keylen) { | 209 size_t keylen) { |
208 // Add the attribute with a dummy value. Since this is a known attribute, it | 210 // Add the attribute with a dummy value. Since this is a known attribute, it |
209 // can't fail. | 211 // can't fail. |
210 StunByteStringAttribute* msg_integrity_attr = | 212 auto msg_integrity_attr_ptr = rtc::MakeUnique<StunByteStringAttribute>( |
211 new StunByteStringAttribute(STUN_ATTR_MESSAGE_INTEGRITY, | 213 STUN_ATTR_MESSAGE_INTEGRITY, std::string(kStunMessageIntegritySize, '0')); |
212 std::string(kStunMessageIntegritySize, '0')); | 214 auto* msg_integrity_attr = msg_integrity_attr_ptr.get(); |
213 AddAttribute(msg_integrity_attr); | 215 AddAttribute(std::move(msg_integrity_attr_ptr)); |
214 | 216 |
215 // Calculate the HMAC for the message. | 217 // Calculate the HMAC for the message. |
216 ByteBufferWriter buf; | 218 ByteBufferWriter buf; |
217 if (!Write(&buf)) | 219 if (!Write(&buf)) |
218 return false; | 220 return false; |
219 | 221 |
220 int msg_len_for_hmac = static_cast<int>( | 222 int msg_len_for_hmac = static_cast<int>( |
221 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); | 223 buf.Length() - kStunAttributeHeaderSize - msg_integrity_attr->length()); |
222 char hmac[kStunMessageIntegritySize]; | 224 char hmac[kStunMessageIntegritySize]; |
223 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, | 225 size_t ret = rtc::ComputeHmac(rtc::DIGEST_SHA_1, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 // Check the fingerprint value. | 264 // Check the fingerprint value. |
263 uint32_t fingerprint = | 265 uint32_t fingerprint = |
264 rtc::GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize); | 266 rtc::GetBE32(fingerprint_attr_data + kStunAttributeHeaderSize); |
265 return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) == | 267 return ((fingerprint ^ STUN_FINGERPRINT_XOR_VALUE) == |
266 rtc::ComputeCrc32(data, size - fingerprint_attr_size)); | 268 rtc::ComputeCrc32(data, size - fingerprint_attr_size)); |
267 } | 269 } |
268 | 270 |
269 bool StunMessage::AddFingerprint() { | 271 bool StunMessage::AddFingerprint() { |
270 // Add the attribute with a dummy value. Since this is a known attribute, | 272 // Add the attribute with a dummy value. Since this is a known attribute, |
271 // it can't fail. | 273 // it can't fail. |
272 StunUInt32Attribute* fingerprint_attr = | 274 auto fingerprint_attr_ptr = |
273 new StunUInt32Attribute(STUN_ATTR_FINGERPRINT, 0); | 275 rtc::MakeUnique<StunUInt32Attribute>(STUN_ATTR_FINGERPRINT, 0); |
274 AddAttribute(fingerprint_attr); | 276 auto fingerprint_attr = fingerprint_attr_ptr.get(); |
| 277 AddAttribute(std::move(fingerprint_attr_ptr)); |
275 | 278 |
276 // Calculate the CRC-32 for the message and insert it. | 279 // Calculate the CRC-32 for the message and insert it. |
277 ByteBufferWriter buf; | 280 ByteBufferWriter buf; |
278 if (!Write(&buf)) | 281 if (!Write(&buf)) |
279 return false; | 282 return false; |
280 | 283 |
281 int msg_len_for_crc32 = static_cast<int>( | 284 int msg_len_for_crc32 = static_cast<int>( |
282 buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length()); | 285 buf.Length() - kStunAttributeHeaderSize - fingerprint_attr->length()); |
283 uint32_t c = rtc::ComputeCrc32(buf.Data(), msg_len_for_crc32); | 286 uint32_t c = rtc::ComputeCrc32(buf.Data(), msg_len_for_crc32); |
284 | 287 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 return new StunByteStringAttribute(type, length); | 449 return new StunByteStringAttribute(type, length); |
447 case STUN_VALUE_ERROR_CODE: | 450 case STUN_VALUE_ERROR_CODE: |
448 return new StunErrorCodeAttribute(type, length); | 451 return new StunErrorCodeAttribute(type, length); |
449 case STUN_VALUE_UINT16_LIST: | 452 case STUN_VALUE_UINT16_LIST: |
450 return new StunUInt16ListAttribute(type, length); | 453 return new StunUInt16ListAttribute(type, length); |
451 default: | 454 default: |
452 return NULL; | 455 return NULL; |
453 } | 456 } |
454 } | 457 } |
455 | 458 |
456 StunAddressAttribute* StunAttribute::CreateAddress(uint16_t type) { | 459 std::unique_ptr<StunAddressAttribute> StunAttribute::CreateAddress( |
457 return new StunAddressAttribute(type, 0); | 460 uint16_t type) { |
| 461 return rtc::MakeUnique<StunAddressAttribute>(type, 0); |
458 } | 462 } |
459 | 463 |
460 StunXorAddressAttribute* StunAttribute::CreateXorAddress(uint16_t type) { | 464 std::unique_ptr<StunXorAddressAttribute> StunAttribute::CreateXorAddress( |
461 return new StunXorAddressAttribute(type, 0, NULL); | 465 uint16_t type) { |
| 466 return rtc::MakeUnique<StunXorAddressAttribute>(type, 0, nullptr); |
462 } | 467 } |
463 | 468 |
464 StunUInt64Attribute* StunAttribute::CreateUInt64(uint16_t type) { | 469 std::unique_ptr<StunUInt64Attribute> StunAttribute::CreateUInt64( |
465 return new StunUInt64Attribute(type); | 470 uint16_t type) { |
| 471 return rtc::MakeUnique<StunUInt64Attribute>(type); |
466 } | 472 } |
467 | 473 |
468 StunUInt32Attribute* StunAttribute::CreateUInt32(uint16_t type) { | 474 std::unique_ptr<StunUInt32Attribute> StunAttribute::CreateUInt32( |
469 return new StunUInt32Attribute(type); | 475 uint16_t type) { |
| 476 return rtc::MakeUnique<StunUInt32Attribute>(type); |
470 } | 477 } |
471 | 478 |
472 StunByteStringAttribute* StunAttribute::CreateByteString(uint16_t type) { | 479 std::unique_ptr<StunByteStringAttribute> StunAttribute::CreateByteString( |
473 return new StunByteStringAttribute(type, 0); | 480 uint16_t type) { |
| 481 return rtc::MakeUnique<StunByteStringAttribute>(type, 0); |
474 } | 482 } |
475 | 483 |
476 StunErrorCodeAttribute* StunAttribute::CreateErrorCode() { | 484 std::unique_ptr<StunErrorCodeAttribute> StunAttribute::CreateErrorCode() { |
477 return new StunErrorCodeAttribute( | 485 return rtc::MakeUnique<StunErrorCodeAttribute>( |
478 STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE); | 486 STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE); |
479 } | 487 } |
480 | 488 |
481 StunUInt16ListAttribute* StunAttribute::CreateUnknownAttributes() { | 489 std::unique_ptr<StunUInt16ListAttribute> |
482 return new StunUInt16ListAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, 0); | 490 StunAttribute::CreateUnknownAttributes() { |
| 491 return rtc::MakeUnique<StunUInt16ListAttribute>(STUN_ATTR_UNKNOWN_ATTRIBUTES, |
| 492 0); |
483 } | 493 } |
484 | 494 |
485 StunAddressAttribute::StunAddressAttribute(uint16_t type, | 495 StunAddressAttribute::StunAddressAttribute(uint16_t type, |
486 const rtc::SocketAddress& addr) | 496 const rtc::SocketAddress& addr) |
487 : StunAttribute(type, 0) { | 497 : StunAttribute(type, 0) { |
488 SetAddress(addr); | 498 SetAddress(addr); |
489 } | 499 } |
490 | 500 |
491 StunAddressAttribute::StunAddressAttribute(uint16_t type, uint16_t length) | 501 StunAddressAttribute::StunAddressAttribute(uint16_t type, uint16_t length) |
492 : StunAttribute(type, length) { | 502 : StunAttribute(type, length) { |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 WritePadding(buf); | 759 WritePadding(buf); |
750 return true; | 760 return true; |
751 } | 761 } |
752 | 762 |
753 void StunByteStringAttribute::SetBytes(char* bytes, size_t length) { | 763 void StunByteStringAttribute::SetBytes(char* bytes, size_t length) { |
754 delete [] bytes_; | 764 delete [] bytes_; |
755 bytes_ = bytes; | 765 bytes_ = bytes; |
756 SetLength(static_cast<uint16_t>(length)); | 766 SetLength(static_cast<uint16_t>(length)); |
757 } | 767 } |
758 | 768 |
| 769 const uint16_t StunErrorCodeAttribute::MIN_SIZE = 4; |
| 770 |
759 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, | 771 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, |
760 int code, | 772 int code, |
761 const std::string& reason) | 773 const std::string& reason) |
762 : StunAttribute(type, 0) { | 774 : StunAttribute(type, 0) { |
763 SetCode(code); | 775 SetCode(code); |
764 SetReason(reason); | 776 SetReason(reason); |
765 } | 777 } |
766 | 778 |
767 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, uint16_t length) | 779 StunErrorCodeAttribute::StunErrorCodeAttribute(uint16_t type, uint16_t length) |
768 : StunAttribute(type, length), class_(0), number_(0) { | 780 : StunAttribute(type, length), class_(0), number_(0) { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 digest, sizeof(digest)); | 918 digest, sizeof(digest)); |
907 if (size == 0) { | 919 if (size == 0) { |
908 return false; | 920 return false; |
909 } | 921 } |
910 | 922 |
911 *hash = std::string(digest, size); | 923 *hash = std::string(digest, size); |
912 return true; | 924 return true; |
913 } | 925 } |
914 | 926 |
915 } // namespace cricket | 927 } // namespace cricket |
OLD | NEW |