147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketaddress.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sys/types.h> 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sys/socket.h> 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <netinet/in.h> 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(OPENBSD) 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <netinet/in_systm.h> 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if !defined(__native_client__) 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <netinet/ip.h> 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <arpa/inet.h> 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <netdb.h> 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <unistd.h> 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sstream> 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/byteorder.h" 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h" 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h" 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/nethelpers.h" 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h" 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress::SocketAddress() { 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Clear(); 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress::SocketAddress(const std::string& hostname, int port) { 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(hostname); 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(port); 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress::SocketAddress(uint32 ip_as_host_order_integer, int port) { 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(IPAddress(ip_as_host_order_integer)); 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(port); 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress::SocketAddress(const IPAddress& ip, int port) { 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(ip); 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(port); 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress::SocketAddress(const SocketAddress& addr) { 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org this->operator=(addr); 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::Clear() { 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostname_.clear(); 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = false; 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = IPAddress(); 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org port_ = 0; 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsNil() const { 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return hostname_.empty() && IPIsUnspec(ip_) && 0 == port_; 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsComplete() const { 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (!IPIsAny(ip_)) && (0 != port_); 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress& SocketAddress::operator=(const SocketAddress& addr) { 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostname_ = addr.hostname_; 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = addr.ip_; 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org port_ = addr.port_; 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = addr.literal_; 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = addr.scope_id_; 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return *this; 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetIP(uint32 ip_as_host_order_integer) { 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostname_.clear(); 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = false; 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = IPAddress(ip_as_host_order_integer); 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetIP(const IPAddress& ip) { 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostname_.clear(); 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = false; 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = ip; 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetIP(const std::string& hostname) { 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org hostname_ = hostname; 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = IPFromString(hostname, &ip_); 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!literal_) { 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = IPAddress(); 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetResolvedIP(uint32 ip_as_host_order_integer) { 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = IPAddress(ip_as_host_order_integer); 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetResolvedIP(const IPAddress& ip) { 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ip_ = ip; 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org scope_id_ = 0; 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::SetPort(int port) { 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT((0 <= port) && (port < 65536)); 124c2e6614c20710991cdbae41993e6c92d64dab9afhenrike@webrtc.org port_ = static_cast<uint16>(port); 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 SocketAddress::ip() const { 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ip_.v4AddressAsHostOrderInteger(); 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst IPAddress& SocketAddress::ipaddr() const { 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ip_; 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint16 SocketAddress::port() const { 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return port_; 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::HostAsURIString() const { 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If the hostname was a literal IP string, it may need to have square 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // brackets added (for SocketAddress::ToString()). 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!literal_ && !hostname_.empty()) 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return hostname_; 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ip_.family() == AF_INET6) { 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return "[" + ip_.ToString() + "]"; 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ip_.ToString(); 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::HostAsSensitiveURIString() const { 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If the hostname was a literal IP string, it may need to have square 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // brackets added (for SocketAddress::ToString()). 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!literal_ && !hostname_.empty()) 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return hostname_; 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ip_.family() == AF_INET6) { 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return "[" + ip_.ToSensitiveString() + "]"; 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ip_.ToSensitiveString(); 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::PortAsString() const { 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::ostringstream ost; 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ost << port_; 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ost.str(); 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::ToString() const { 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::ostringstream ost; 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ost << *this; 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ost.str(); 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::ToSensitiveString() const { 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::ostringstream ost; 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ost << HostAsSensitiveURIString() << ":" << port(); 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ost.str(); 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::FromString(const std::string& str) { 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (str.at(0) == '[') { 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string::size_type closebracket = str.rfind(']'); 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (closebracket != std::string::npos) { 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string::size_type colon = str.find(':', closebracket); 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (colon != std::string::npos && colon > closebracket) { 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(strtoul(str.substr(colon + 1).c_str(), NULL, 10)); 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(str.substr(1, closebracket - 1)); 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org std::string::size_type pos = str.find(':'); 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (std::string::npos == pos) 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(strtoul(str.substr(pos + 1).c_str(), NULL, 10)); 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(str.substr(0, pos)); 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::ostream& operator<<(std::ostream& os, const SocketAddress& addr) { 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org os << addr.HostAsURIString() << ":" << addr.port(); 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return os; 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsAnyIP() const { 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPIsAny(ip_); 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsLoopbackIP() const { 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPIsLoopback(ip_) || (IPIsAny(ip_) && 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 0 == strcmp(hostname_.c_str(), "localhost")); 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsPrivateIP() const { 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPIsPrivate(ip_); 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::IsUnresolvedIP() const { 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPIsUnspec(ip_) && !literal_ && !hostname_.empty(); 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::operator==(const SocketAddress& addr) const { 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return EqualIPs(addr) && EqualPorts(addr); 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::operator<(const SocketAddress& addr) const { 230c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org if (ip_ != addr.ip_) 231c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org return ip_ < addr.ip_; 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 233c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org // We only check hostnames if both IPs are ANY or unspecified. This matches 234c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org // EqualIPs(). 235c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org if ((IPIsAny(ip_) || IPIsUnspec(ip_)) && hostname_ != addr.hostname_) 236c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org return hostname_ < addr.hostname_; 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return port_ < addr.port_; 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::EqualIPs(const SocketAddress& addr) const { 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (ip_ == addr.ip_) && 243c4b828d1b37c297978031b1a6871a03cc2522c3ahenrike@webrtc.org ((!IPIsAny(ip_) && !IPIsUnspec(ip_)) || (hostname_ == addr.hostname_)); 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::EqualPorts(const SocketAddress& addr) const { 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return (port_ == addr.port_); 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t SocketAddress::Hash() const { 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t h = 0; 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org h ^= HashIP(ip_); 25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org h ^= port_ | (port_ << 16); 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return h; 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketAddress::ToSockAddr(sockaddr_in* saddr) const { 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(saddr, 0, sizeof(*saddr)); 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ip_.family() != AF_INET) { 26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_family = AF_UNSPEC; 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return; 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_family = AF_INET; 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_port = HostToNetwork16(port_); 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (IPIsAny(ip_)) { 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_addr.s_addr = INADDR_ANY; 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else { 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_addr = ip_.ipv4_address(); 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::FromSockAddr(const sockaddr_in& saddr) { 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (saddr.sin_family != AF_INET) 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetIP(NetworkToHost32(saddr.sin_addr.s_addr)); 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetPort(NetworkToHost16(saddr.sin_port)); 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org literal_ = false; 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic size_t ToSockAddrStorageHelper(sockaddr_storage* addr, 282c2e6614c20710991cdbae41993e6c92d64dab9afhenrike@webrtc.org IPAddress ip, uint16 port, int scope_id) { 28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org memset(addr, 0, sizeof(sockaddr_storage)); 284c2e6614c20710991cdbae41993e6c92d64dab9afhenrike@webrtc.org addr->ss_family = static_cast<unsigned short>(ip.family()); 28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (addr->ss_family == AF_INET6) { 28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org sockaddr_in6* saddr = reinterpret_cast<sockaddr_in6*>(addr); 28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin6_addr = ip.ipv6_address(); 28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin6_port = HostToNetwork16(port); 28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin6_scope_id = scope_id; 29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return sizeof(sockaddr_in6); 29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (addr->ss_family == AF_INET) { 29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org sockaddr_in* saddr = reinterpret_cast<sockaddr_in*>(addr); 29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_addr = ip.ipv4_address(); 29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org saddr->sin_port = HostToNetwork16(port); 29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return sizeof(sockaddr_in); 29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 0; 29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t SocketAddress::ToDualStackSockAddrStorage(sockaddr_storage *addr) const { 30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ToSockAddrStorageHelper(addr, ip_.AsIPv6Address(), port_, scope_id_); 30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgsize_t SocketAddress::ToSockAddrStorage(sockaddr_storage* addr) const { 30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ToSockAddrStorageHelper(addr, ip_, port_, scope_id_); 30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string SocketAddress::IPToString(uint32 ip_as_host_order_integer) { 30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPAddress(ip_as_host_order_integer).ToString(); 31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string IPToSensitiveString(uint32 ip_as_host_order_integer) { 31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return IPAddress(ip_as_host_order_integer).ToSensitiveString(); 31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::StringToIP(const std::string& hostname, uint32* ip) { 31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org in_addr addr; 31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (rtc::inet_pton(AF_INET, hostname.c_str(), &addr) == 0) 31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *ip = NetworkToHost32(addr.s_addr); 32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddress::StringToIP(const std::string& hostname, IPAddress* ip) { 32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org in_addr addr4; 32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (rtc::inet_pton(AF_INET, hostname.c_str(), &addr4) > 0) { 32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ip) { 32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *ip = IPAddress(addr4); 32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org in6_addr addr6; 33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (rtc::inet_pton(AF_INET6, hostname.c_str(), &addr6) > 0) { 33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (ip) { 33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *ip = IPAddress(addr6); 33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 SocketAddress::StringToIP(const std::string& hostname) { 34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint32 ip = 0; 34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org StringToIP(hostname, &ip); 34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return ip; 34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SocketAddressFromSockAddrStorage(const sockaddr_storage& addr, 35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketAddress* out) { 35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (!out) { 35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (addr.ss_family == AF_INET) { 35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const sockaddr_in* saddr = reinterpret_cast<const sockaddr_in*>(&addr); 35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *out = SocketAddress(IPAddress(saddr->sin_addr), 35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NetworkToHost16(saddr->sin_port)); 35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (addr.ss_family == AF_INET6) { 36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const sockaddr_in6* saddr = reinterpret_cast<const sockaddr_in6*>(&addr); 36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *out = SocketAddress(IPAddress(saddr->sin6_addr), 36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org NetworkToHost16(saddr->sin6_port)); 36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org out->SetScopeID(saddr->sin6_scope_id); 36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return true; 36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocketAddress EmptySocketAddressWithFamily(int family) { 37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (family == AF_INET) { 37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SocketAddress(IPAddress(INADDR_ANY), 0); 37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } else if (family == AF_INET6) { 37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SocketAddress(IPAddress(in6addr_any), 0); 37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return SocketAddress(); 37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 379