| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2012 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 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 static const int kMinChannelNumber = 0x4000; | 34 static const int kMinChannelNumber = 0x4000; |
| 35 static const int kMaxChannelNumber = 0x7FFF; | 35 static const int kMaxChannelNumber = 0x7FFF; |
| 36 | 36 |
| 37 static const size_t kNonceKeySize = 16; | 37 static const size_t kNonceKeySize = 16; |
| 38 static const size_t kNonceSize = 40; | 38 static const size_t kNonceSize = 40; |
| 39 | 39 |
| 40 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U; | 40 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U; |
| 41 | 41 |
| 42 // TODO(mallinath) - Move these to a common place. | 42 // TODO(mallinath) - Move these to a common place. |
| 43 inline bool IsTurnChannelData(uint16 msg_type) { | 43 inline bool IsTurnChannelData(uint16_t msg_type) { |
| 44 // The first two bits of a channel data message are 0b01. | 44 // The first two bits of a channel data message are 0b01. |
| 45 return ((msg_type & 0xC000) == 0x4000); | 45 return ((msg_type & 0xC000) == 0x4000); |
| 46 } | 46 } |
| 47 | 47 |
| 48 // IDs used for posted messages for TurnServerAllocation. | 48 // IDs used for posted messages for TurnServerAllocation. |
| 49 enum { | 49 enum { |
| 50 MSG_ALLOCATION_TIMEOUT, | 50 MSG_ALLOCATION_TIMEOUT, |
| 51 }; | 51 }; |
| 52 | 52 |
| 53 // Encapsulates a TURN permission. | 53 // Encapsulates a TURN permission. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 const char* data, size_t size, | 193 const char* data, size_t size, |
| 194 const rtc::SocketAddress& addr, | 194 const rtc::SocketAddress& addr, |
| 195 const rtc::PacketTime& packet_time) { | 195 const rtc::PacketTime& packet_time) { |
| 196 // Fail if the packet is too small to even contain a channel header. | 196 // Fail if the packet is too small to even contain a channel header. |
| 197 if (size < TURN_CHANNEL_HEADER_SIZE) { | 197 if (size < TURN_CHANNEL_HEADER_SIZE) { |
| 198 return; | 198 return; |
| 199 } | 199 } |
| 200 InternalSocketMap::iterator iter = server_sockets_.find(socket); | 200 InternalSocketMap::iterator iter = server_sockets_.find(socket); |
| 201 ASSERT(iter != server_sockets_.end()); | 201 ASSERT(iter != server_sockets_.end()); |
| 202 TurnServerConnection conn(addr, iter->second, socket); | 202 TurnServerConnection conn(addr, iter->second, socket); |
| 203 uint16 msg_type = rtc::GetBE16(data); | 203 uint16_t msg_type = rtc::GetBE16(data); |
| 204 if (!IsTurnChannelData(msg_type)) { | 204 if (!IsTurnChannelData(msg_type)) { |
| 205 // This is a STUN message. | 205 // This is a STUN message. |
| 206 HandleStunMessage(&conn, data, size); | 206 HandleStunMessage(&conn, data, size); |
| 207 } else { | 207 } else { |
| 208 // This is a channel message; let the allocation handle it. | 208 // This is a channel message; let the allocation handle it. |
| 209 TurnServerAllocation* allocation = FindAllocation(&conn); | 209 TurnServerAllocation* allocation = FindAllocation(&conn); |
| 210 if (allocation) { | 210 if (allocation) { |
| 211 allocation->HandleChannelData(data, size); | 211 allocation->HandleChannelData(data, size); |
| 212 } | 212 } |
| 213 } | 213 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 if (alloc) { | 387 if (alloc) { |
| 388 alloc->HandleTurnMessage(msg); | 388 alloc->HandleTurnMessage(msg); |
| 389 } else { | 389 } else { |
| 390 SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR, | 390 SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR, |
| 391 "Failed to allocate socket"); | 391 "Failed to allocate socket"); |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 | 394 |
| 395 std::string TurnServer::GenerateNonce() const { | 395 std::string TurnServer::GenerateNonce() const { |
| 396 // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now)) | 396 // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now)) |
| 397 uint32 now = rtc::Time(); | 397 uint32_t now = rtc::Time(); |
| 398 std::string input(reinterpret_cast<const char*>(&now), sizeof(now)); | 398 std::string input(reinterpret_cast<const char*>(&now), sizeof(now)); |
| 399 std::string nonce = rtc::hex_encode(input.c_str(), input.size()); | 399 std::string nonce = rtc::hex_encode(input.c_str(), input.size()); |
| 400 nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input); | 400 nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input); |
| 401 ASSERT(nonce.size() == kNonceSize); | 401 ASSERT(nonce.size() == kNonceSize); |
| 402 return nonce; | 402 return nonce; |
| 403 } | 403 } |
| 404 | 404 |
| 405 bool TurnServer::ValidateNonce(const std::string& nonce) const { | 405 bool TurnServer::ValidateNonce(const std::string& nonce) const { |
| 406 // Check the size. | 406 // Check the size. |
| 407 if (nonce.size() != kNonceSize) { | 407 if (nonce.size() != kNonceSize) { |
| 408 return false; | 408 return false; |
| 409 } | 409 } |
| 410 | 410 |
| 411 // Decode the timestamp. | 411 // Decode the timestamp. |
| 412 uint32 then; | 412 uint32_t then; |
| 413 char* p = reinterpret_cast<char*>(&then); | 413 char* p = reinterpret_cast<char*>(&then); |
| 414 size_t len = rtc::hex_decode(p, sizeof(then), | 414 size_t len = rtc::hex_decode(p, sizeof(then), |
| 415 nonce.substr(0, sizeof(then) * 2)); | 415 nonce.substr(0, sizeof(then) * 2)); |
| 416 if (len != sizeof(then)) { | 416 if (len != sizeof(then)) { |
| 417 return false; | 417 return false; |
| 418 } | 418 } |
| 419 | 419 |
| 420 // Verify the HMAC. | 420 // Verify the HMAC. |
| 421 if (nonce.substr(sizeof(then) * 2) != rtc::ComputeHmac( | 421 if (nonce.substr(sizeof(then) * 2) != rtc::ComputeHmac( |
| 422 rtc::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) { | 422 rtc::DIGEST_MD5, nonce_key_, std::string(p, sizeof(then)))) { |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 << ", peer=" << peer_attr->GetAddress(); | 754 << ", peer=" << peer_attr->GetAddress(); |
| 755 | 755 |
| 756 // Send a success response. | 756 // Send a success response. |
| 757 TurnMessage response; | 757 TurnMessage response; |
| 758 InitResponse(msg, &response); | 758 InitResponse(msg, &response); |
| 759 SendResponse(&response); | 759 SendResponse(&response); |
| 760 } | 760 } |
| 761 | 761 |
| 762 void TurnServerAllocation::HandleChannelData(const char* data, size_t size) { | 762 void TurnServerAllocation::HandleChannelData(const char* data, size_t size) { |
| 763 // Extract the channel number from the data. | 763 // Extract the channel number from the data. |
| 764 uint16 channel_id = rtc::GetBE16(data); | 764 uint16_t channel_id = rtc::GetBE16(data); |
| 765 Channel* channel = FindChannel(channel_id); | 765 Channel* channel = FindChannel(channel_id); |
| 766 if (channel) { | 766 if (channel) { |
| 767 // Send the data to the peer address. | 767 // Send the data to the peer address. |
| 768 SendExternal(data + TURN_CHANNEL_HEADER_SIZE, | 768 SendExternal(data + TURN_CHANNEL_HEADER_SIZE, |
| 769 size - TURN_CHANNEL_HEADER_SIZE, channel->peer()); | 769 size - TURN_CHANNEL_HEADER_SIZE, channel->peer()); |
| 770 } else { | 770 } else { |
| 771 LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id=" | 771 LOG_J(LS_WARNING, this) << "Received channel data for invalid channel, id=" |
| 772 << channel_id; | 772 << channel_id; |
| 773 } | 773 } |
| 774 } | 774 } |
| 775 | 775 |
| 776 void TurnServerAllocation::OnExternalPacket( | 776 void TurnServerAllocation::OnExternalPacket( |
| 777 rtc::AsyncPacketSocket* socket, | 777 rtc::AsyncPacketSocket* socket, |
| 778 const char* data, size_t size, | 778 const char* data, size_t size, |
| 779 const rtc::SocketAddress& addr, | 779 const rtc::SocketAddress& addr, |
| 780 const rtc::PacketTime& packet_time) { | 780 const rtc::PacketTime& packet_time) { |
| 781 ASSERT(external_socket_.get() == socket); | 781 ASSERT(external_socket_.get() == socket); |
| 782 Channel* channel = FindChannel(addr); | 782 Channel* channel = FindChannel(addr); |
| 783 if (channel) { | 783 if (channel) { |
| 784 // There is a channel bound to this address. Send as a channel message. | 784 // There is a channel bound to this address. Send as a channel message. |
| 785 rtc::ByteBuffer buf; | 785 rtc::ByteBuffer buf; |
| 786 buf.WriteUInt16(channel->id()); | 786 buf.WriteUInt16(channel->id()); |
| 787 buf.WriteUInt16(static_cast<uint16>(size)); | 787 buf.WriteUInt16(static_cast<uint16_t>(size)); |
| 788 buf.WriteBytes(data, size); | 788 buf.WriteBytes(data, size); |
| 789 server_->Send(&conn_, buf); | 789 server_->Send(&conn_, buf); |
| 790 } else if (HasPermission(addr.ipaddr())) { | 790 } else if (HasPermission(addr.ipaddr())) { |
| 791 // No channel, but a permission exists. Send as a data indication. | 791 // No channel, but a permission exists. Send as a data indication. |
| 792 TurnMessage msg; | 792 TurnMessage msg; |
| 793 msg.SetType(TURN_DATA_INDICATION); | 793 msg.SetType(TURN_DATA_INDICATION); |
| 794 msg.SetTransactionID( | 794 msg.SetTransactionID( |
| 795 rtc::CreateRandomString(kStunTransactionIdLength)); | 795 rtc::CreateRandomString(kStunTransactionIdLength)); |
| 796 VERIFY(msg.AddAttribute(new StunXorAddressAttribute( | 796 VERIFY(msg.AddAttribute(new StunXorAddressAttribute( |
| 797 STUN_ATTR_XOR_PEER_ADDRESS, addr))); | 797 STUN_ATTR_XOR_PEER_ADDRESS, addr))); |
| 798 VERIFY(msg.AddAttribute(new StunByteStringAttribute( | 798 VERIFY(msg.AddAttribute(new StunByteStringAttribute( |
| 799 STUN_ATTR_DATA, data, size))); | 799 STUN_ATTR_DATA, data, size))); |
| 800 server_->SendStun(&conn_, &msg); | 800 server_->SendStun(&conn_, &msg); |
| 801 } else { | 801 } else { |
| 802 LOG_J(LS_WARNING, this) << "Received external packet without permission, " | 802 LOG_J(LS_WARNING, this) << "Received external packet without permission, " |
| 803 << "peer=" << addr; | 803 << "peer=" << addr; |
| 804 } | 804 } |
| 805 } | 805 } |
| 806 | 806 |
| 807 int TurnServerAllocation::ComputeLifetime(const TurnMessage* msg) { | 807 int TurnServerAllocation::ComputeLifetime(const TurnMessage* msg) { |
| 808 // Return the smaller of our default lifetime and the requested lifetime. | 808 // Return the smaller of our default lifetime and the requested lifetime. |
| 809 uint32 lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds | 809 uint32_t lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds |
| 810 const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME); | 810 const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME); |
| 811 if (lifetime_attr && lifetime_attr->value() < lifetime) { | 811 if (lifetime_attr && lifetime_attr->value() < lifetime) { |
| 812 lifetime = lifetime_attr->value(); | 812 lifetime = lifetime_attr->value(); |
| 813 } | 813 } |
| 814 return lifetime; | 814 return lifetime; |
| 815 } | 815 } |
| 816 | 816 |
| 817 bool TurnServerAllocation::HasPermission(const rtc::IPAddress& addr) { | 817 bool TurnServerAllocation::HasPermission(const rtc::IPAddress& addr) { |
| 818 return (FindPermission(addr) != NULL); | 818 return (FindPermission(addr) != NULL); |
| 819 } | 819 } |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT); | 936 thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT); |
| 937 } | 937 } |
| 938 | 938 |
| 939 void TurnServerAllocation::Channel::OnMessage(rtc::Message* msg) { | 939 void TurnServerAllocation::Channel::OnMessage(rtc::Message* msg) { |
| 940 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); | 940 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); |
| 941 SignalDestroyed(this); | 941 SignalDestroyed(this); |
| 942 delete this; | 942 delete this; |
| 943 } | 943 } |
| 944 | 944 |
| 945 } // namespace cricket | 945 } // namespace cricket |
| OLD | NEW |