HRESULT CStunMessageBuilder::AddMappedAddressImpl(uint16_t attribute, const CSocketAddress& addr) { uint16_t port; size_t length; uint8_t ip[STUN_IPV6_LENGTH]; HRESULT hr = S_OK; uint8_t family = (addr.GetFamily()==AF_INET) ? STUN_ATTRIBUTE_FIELD_IPV4 :STUN_ATTRIBUTE_FIELD_IPV6; size_t attributeSize = (family == STUN_ATTRIBUTE_FIELD_IPV4) ? STUN_ATTRIBUTE_MAPPEDADDRESS_SIZE_IPV4 : STUN_ATTRIBUTE_MAPPEDADDRESS_SIZE_IPV6; Chk(AddAttributeHeader(attribute, attributeSize)); port = addr.GetPort_NBO(); length = addr.GetIP_NBO(ip, sizeof(ip)); // if we ever had a length that was not a multiple of 4, we'd need to add padding ASSERT((length == STUN_IPV4_LENGTH) || (length == STUN_IPV6_LENGTH)); Chk(_stream.WriteUint8(0)); Chk(_stream.WriteUint8(family)); Chk(_stream.WriteUint16(port)); Chk(_stream.Write(ip, length)); Cleanup: return hr; }
//static HRESULT CStunSocket::Create(const CSocketAddress& addrlocal, SocketRole role, boost::shared_ptr<CStunSocket>* pStunSocketShared) { int sock = -1; int ret; CStunSocket* pSocket = NULL; sockaddr_storage addrBind = {}; socklen_t sizeaddrBind; HRESULT hr = S_OK; ChkIfA(pStunSocketShared == NULL, E_INVALIDARG); sock = socket(addrlocal.GetFamily(), SOCK_DGRAM, 0); ChkIf(sock < 0, ERRNOHR); ret = bind(sock, addrlocal.GetSockAddr(), addrlocal.GetSockAddrLength()); ChkIf(ret < 0, ERRNOHR); // call get sockname to find out what port we just binded to. (Useful for when addrLocal.port is 0) sizeaddrBind = sizeof(addrBind); ret = ::getsockname(sock, (sockaddr*)&addrBind, &sizeaddrBind); ChkIf(ret < 0, ERRNOHR); pSocket = new CStunSocket(); pSocket->_sock = sock; pSocket->_addrlocal = CSocketAddress(*(sockaddr*)&addrBind); pSocket->_role = role; sock = -1; { boost::shared_ptr<CStunSocket> spTmp(pSocket); pStunSocketShared->swap(spTmp); } Cleanup: if (sock != -1) { close(sock); sock = -1; } return hr; }