1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/stun.h" 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <cstring> 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h" 34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochusing talk_base::ByteBuffer; 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace cricket { 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_BAD_REQUEST = "BAD REQUEST"; 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_UNAUTHORIZED = "UNAUTHORIZED"; 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_UNKNOWN_ATTRIBUTE = "UNKNOWN ATTRIBUTE"; 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_STALE_CREDENTIALS = "STALE CREDENTIALS"; 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_INTEGRITY_CHECK_FAILURE = "INTEGRITY CHECK FAILURE"; 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_MISSING_USERNAME = "MISSING USERNAME"; 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_USE_TLS = "USE TLS"; 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_SERVER_ERROR = "SERVER ERROR"; 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst std::string STUN_ERROR_REASON_GLOBAL_FAILURE = "GLOBAL FAILURE"; 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessage::StunMessage() : type_(0), length_(0), 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transaction_id_("0000000000000000") { 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(transaction_id_.size() == 16); 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrs_ = new std::vector<StunAttribute*>(); 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessage::~StunMessage() { 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (unsigned i = 0; i < attrs_->size(); i++) 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete (*attrs_)[i]; 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete attrs_; 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunMessage::SetTransactionID(const std::string& str) { 62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(str.size() == 16); 63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transaction_id_ = str; 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunMessage::AddAttribute(StunAttribute* attr) { 67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrs_->push_back(attr); 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch length_ += attr->length() + 4; 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunAddressAttribute* 72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessage::GetAddress(StunAttributeType type) const { 73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAPPED_ADDRESS: 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_RESPONSE_ADDRESS: 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS: 77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGED_ADDRESS: 78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_REFLECTED_FROM: 79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_ALTERNATE_SERVER: 80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DESTINATION_ADDRESS: 81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS2: 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunAddressAttribute*>(GetAttribute(type)); 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(0); 86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunUInt32Attribute* 91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessage::GetUInt32(StunAttributeType type) const { 92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGE_REQUEST: 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_LIFETIME: 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_BANDWIDTH: 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_OPTIONS: 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunUInt32Attribute*>(GetAttribute(type)); 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(0); 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunByteStringAttribute* 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessage::GetByteString(StunAttributeType type) const { 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_USERNAME: 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_PASSWORD: 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MESSAGE_INTEGRITY: 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DATA: 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAGIC_COOKIE: 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunByteStringAttribute*>(GetAttribute(type)); 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(0); 117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunErrorCodeAttribute* StunMessage::GetErrorCode() const { 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunErrorCodeAttribute*>( 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetAttribute(STUN_ATTR_ERROR_CODE)); 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunUInt16ListAttribute* StunMessage::GetUnknownAttributes() const { 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunUInt16ListAttribute*>( 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES)); 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunTransportPrefsAttribute* StunMessage::GetTransportPrefs() const { 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return reinterpret_cast<const StunTransportPrefsAttribute*>( 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch GetAttribute(STUN_ATTR_TRANSPORT_PREFERENCES)); 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochconst StunAttribute* StunMessage::GetAttribute(StunAttributeType type) const { 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (unsigned i = 0; i < attrs_->size(); i++) { 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((*attrs_)[i]->type() == type) 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (*attrs_)[i]; 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunMessage::Read(ByteBuffer* buf) { 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&type_)) 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (type_ & 0x8000) { 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // rtp and rtcp set MSB of first byte, since first two bits are version, 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // and version is always 2 (10). If set, this is not a stun packet. 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&length_)) 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::string transaction_id; 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadString(&transaction_id, 16)) 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(transaction_id.size() == 16); 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch transaction_id_ = transaction_id; 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length_ > buf->Length()) 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrs_->resize(0); 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch size_t rest = buf->Length() - length_; 169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (buf->Length() > rest) { 170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint16 attr_type, attr_length; 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&attr_type)) 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&attr_length)) 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StunAttribute* attr = StunAttribute::Create(attr_type, attr_length); 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!attr || !attr->Read(buf)) 178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attrs_->push_back(attr); 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (buf->Length() != rest) { 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // fixme: shouldn't be doing this 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LERROR) << "wrong message length (" << rest << " != " << buf->Length() 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch << ")"; 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunMessage::Write(ByteBuffer* buf) const { 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16(type_); 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16(length_); 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteString(transaction_id_); 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (unsigned i = 0; i < attrs_->size(); i++) { 199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16((*attrs_)[i]->type()); 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16((*attrs_)[i]->length()); 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (*attrs_)[i]->Write(buf); 202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunAttribute::StunAttribute(uint16 type, uint16 length) 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : type_(type), length_(length) { 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunAttribute* StunAttribute::Create(uint16 type, uint16 length) { 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAPPED_ADDRESS: 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_RESPONSE_ADDRESS: 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS: 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGED_ADDRESS: 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_REFLECTED_FROM: 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_ALTERNATE_SERVER: 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DESTINATION_ADDRESS: 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS2: 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length != StunAddressAttribute::SIZE) 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunAddressAttribute(type); 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGE_REQUEST: 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_LIFETIME: 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_BANDWIDTH: 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_OPTIONS: 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length != StunUInt32Attribute::SIZE) 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunUInt32Attribute(type); 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_USERNAME: 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_PASSWORD: 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAGIC_COOKIE: 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (length % 4 == 0) ? new StunByteStringAttribute(type, length) : 0; 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MESSAGE_INTEGRITY: 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (length == 20) ? new StunByteStringAttribute(type, length) : 0; 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 239f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DATA: 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunByteStringAttribute(type, length); 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_ERROR_CODE: 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length < StunErrorCodeAttribute::MIN_SIZE) 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunErrorCodeAttribute(type, length); 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_UNKNOWN_ATTRIBUTES: 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (length % 2 == 0) ? new StunUInt16ListAttribute(type, length) : 0; 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_TRANSPORT_PREFERENCES: 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((length != StunTransportPrefsAttribute::SIZE1) && 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (length != StunTransportPrefsAttribute::SIZE2)) 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunTransportPrefsAttribute(type, length); 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunAddressAttribute* StunAttribute::CreateAddress(uint16 type) { 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAPPED_ADDRESS: 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_RESPONSE_ADDRESS: 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS: 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGED_ADDRESS: 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_REFLECTED_FROM: 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_ALTERNATE_SERVER: 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DESTINATION_ADDRESS: 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_SOURCE_ADDRESS2: 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunAddressAttribute(type); 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(false); 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunUInt32Attribute* StunAttribute::CreateUInt32(uint16 type) { 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_CHANGE_REQUEST: 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_LIFETIME: 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_BANDWIDTH: 284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_OPTIONS: 285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunUInt32Attribute(type); 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(false); 289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunByteStringAttribute* StunAttribute::CreateByteString(uint16 type) { 294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (type) { 295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_USERNAME: 296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_PASSWORD: 297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MESSAGE_INTEGRITY: 298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_DATA: 299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ATTR_MAGIC_COOKIE: 300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunByteStringAttribute(type, 0); 301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(false); 304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return 0; 305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunErrorCodeAttribute* StunAttribute::CreateErrorCode() { 309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunErrorCodeAttribute( 310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch STUN_ATTR_ERROR_CODE, StunErrorCodeAttribute::MIN_SIZE); 311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunUInt16ListAttribute* StunAttribute::CreateUnknownAttributes() { 314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunUInt16ListAttribute(STUN_ATTR_UNKNOWN_ATTRIBUTES, 0); 315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunTransportPrefsAttribute* StunAttribute::CreateTransportPrefs() { 318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return new StunTransportPrefsAttribute( 319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch STUN_ATTR_TRANSPORT_PREFERENCES, StunTransportPrefsAttribute::SIZE1); 320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunAddressAttribute::StunAddressAttribute(uint16 type) 323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, SIZE), family_(0), port_(0), ip_(0) { 324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunAddressAttribute::Read(ByteBuffer* buf) { 327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint8 dummy; 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt8(&dummy)) 329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt8(&family_)) 331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&port_)) 333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt32(&ip_)) 335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunAddressAttribute::Write(ByteBuffer* buf) const { 340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt8(0); 341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt8(family_); 342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16(port_); 343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt32(ip_); 344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunUInt32Attribute::StunUInt32Attribute(uint16 type) 347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, SIZE), bits_(0) { 348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunUInt32Attribute::GetBit(int index) const { 351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT((0 <= index) && (index < 32)); 352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return static_cast<bool>((bits_ >> index) & 0x1); 353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunUInt32Attribute::SetBit(int index, bool value) { 356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT((0 <= index) && (index < 32)); 357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bits_ &= ~(1 << index); 358f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bits_ |= value ? (1 << index) : 0; 359f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 360f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunUInt32Attribute::Read(ByteBuffer* buf) { 3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt32(&bits_)) 363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunUInt32Attribute::Write(ByteBuffer* buf) const { 368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt32(bits_); 369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunByteStringAttribute::StunByteStringAttribute(uint16 type, uint16 length) 372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, length), bytes_(0) { 373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunByteStringAttribute::~StunByteStringAttribute() { 376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete [] bytes_; 377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunByteStringAttribute::SetBytes(char* bytes, uint16 length) { 380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete [] bytes_; 381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bytes_ = bytes; 382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetLength(length); 383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunByteStringAttribute::CopyBytes(const char* bytes) { 386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CopyBytes(bytes, static_cast<uint16>(strlen(bytes))); 387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunByteStringAttribute::CopyBytes(const void* bytes, uint16 length) { 390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch char* new_bytes = new char[length]; 391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch std::memcpy(new_bytes, bytes, length); 392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetBytes(new_bytes, length); 393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochuint8 StunByteStringAttribute::GetByte(int index) const { 396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(bytes_ != NULL); 397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT((0 <= index) && (index < length())); 398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return static_cast<uint8>(bytes_[index]); 399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunByteStringAttribute::SetByte(int index, uint8 value) { 402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(bytes_ != NULL); 403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT((0 <= index) && (index < length())); 404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bytes_[index] = value; 405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunByteStringAttribute::Read(ByteBuffer* buf) { 408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch bytes_ = new char[length()]; 409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!buf->ReadBytes(bytes_, length())) 410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunByteStringAttribute::Write(ByteBuffer* buf) const { 415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteBytes(bytes_, length()); 416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunErrorCodeAttribute::StunErrorCodeAttribute(uint16 type, uint16 length) 419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, length), class_(0), number_(0) { 420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunErrorCodeAttribute::~StunErrorCodeAttribute() { 423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunErrorCodeAttribute::SetErrorCode(uint32 code) { 426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch class_ = (uint8)((code >> 8) & 0x7); 427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch number_ = (uint8)(code & 0xff); 428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunErrorCodeAttribute::SetReason(const std::string& reason) { 431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetLength(MIN_SIZE + static_cast<uint16>(reason.size())); 432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch reason_ = reason; 433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunErrorCodeAttribute::Read(ByteBuffer* buf) { 436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint32 val; 4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt32(&val)) 438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((val >> 11) != 0) 441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LERROR) << "error-code bits not zero"; 442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetErrorCode(val); 444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadString(&reason_, length() - 4)) 446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunErrorCodeAttribute::Write(ByteBuffer* buf) const { 452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt32(error_code()); 453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteString(reason_); 454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunUInt16ListAttribute::StunUInt16ListAttribute(uint16 type, uint16 length) 457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, length) { 458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attr_types_ = new std::vector<uint16>(); 459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunUInt16ListAttribute::~StunUInt16ListAttribute() { 462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete attr_types_; 463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochsize_t StunUInt16ListAttribute::Size() const { 466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return attr_types_->size(); 467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochuint16 StunUInt16ListAttribute::GetType(int index) const { 470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (*attr_types_)[index]; 471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunUInt16ListAttribute::SetType(int index, uint16 value) { 474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch (*attr_types_)[index] = value; 475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunUInt16ListAttribute::AddType(uint16 value) { 478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attr_types_->push_back(value); 479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetLength(static_cast<uint16>(attr_types_->size() * 2)); 480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunUInt16ListAttribute::Read(ByteBuffer* buf) { 483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (int i = 0; i < length() / 2; i++) { 484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint16 attr; 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt16(&attr)) 486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch attr_types_->push_back(attr); 488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunUInt16ListAttribute::Write(ByteBuffer* buf) const { 493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (unsigned i = 0; i < attr_types_->size(); i++) 494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt16((*attr_types_)[i]); 495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunTransportPrefsAttribute::StunTransportPrefsAttribute( 498f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint16 type, uint16 length) 499f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch : StunAttribute(type, length), preallocate_(false), prefs_(0), addr_(0) { 500f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunTransportPrefsAttribute::~StunTransportPrefsAttribute() { 503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete addr_; 504f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 505f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 506f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunTransportPrefsAttribute::SetPreallocateAddress( 507f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch StunAddressAttribute* addr) { 508f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!addr) { 509f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch preallocate_ = false; 510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch addr_ = 0; 511f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetLength(SIZE1); 512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 513f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch preallocate_ = true; 514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch addr_ = addr; 515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SetLength(SIZE2); 516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool StunTransportPrefsAttribute::Read(ByteBuffer* buf) { 520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch uint32 val; 5213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!buf->ReadUInt32(&val)) 522f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 523f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 524f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if ((val >> 3) != 0) 525f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LERROR) << "transport-preferences bits not zero"; 526f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 527f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch preallocate_ = static_cast<bool>((val >> 2) & 0x1); 528f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch prefs_ = (uint8)(val & 0x3); 529f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 530f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (preallocate_ && (prefs_ == 3)) 531f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch LOG(LERROR) << "transport-preferences imcompatible P and Typ"; 532f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 533f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!preallocate_) { 534f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length() != StunUInt32Attribute::SIZE) 535f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 536f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 537f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (length() != StunUInt32Attribute::SIZE + StunAddressAttribute::SIZE) 538f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return false; 539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch addr_ = new StunAddressAttribute(STUN_ATTR_SOURCE_ADDRESS); 541f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch addr_->Read(buf); 542f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 543f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 544f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return true; 545f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 546f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 547f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid StunTransportPrefsAttribute::Write(ByteBuffer* buf) const { 548f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buf->WriteUInt32((preallocate_ ? 4 : 0) | prefs_); 549f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 550f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (preallocate_) 551f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch addr_->Write(buf); 552f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 553f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 554f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessageType GetStunResponseType(StunMessageType request_type) { 555f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (request_type) { 556f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_SHARED_SECRET_REQUEST: 557f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_SHARED_SECRET_RESPONSE; 558f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ALLOCATE_REQUEST: 559f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_ALLOCATE_RESPONSE; 560f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_SEND_REQUEST: 561f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_SEND_RESPONSE; 562f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 563f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_BINDING_RESPONSE; 564f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 565f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 566f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 567f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochStunMessageType GetStunErrorResponseType(StunMessageType request_type) { 568f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch switch (request_type) { 569f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_SHARED_SECRET_REQUEST: 570f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_SHARED_SECRET_ERROR_RESPONSE; 571f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_ALLOCATE_REQUEST: 572f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_ALLOCATE_ERROR_RESPONSE; 573f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch case STUN_SEND_REQUEST: 574f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_SEND_ERROR_RESPONSE; 575f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch default: 576f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return STUN_BINDING_ERROR_RESPONSE; 577f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 578f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 579f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 580f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace cricket 581