diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-08 09:44:22 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-08 09:44:22 +0000 |
commit | 0c3654065bb42edc0156a774831ad831b8ee9b11 (patch) | |
tree | 10c6d26aa67590029ddebc0c989b3b22333e8e78 | |
parent | 4bca423b67f5d156e171091d2a06a5c8b7e419b4 (diff) | |
download | chromium_src-0c3654065bb42edc0156a774831ad831b8ee9b11.zip chromium_src-0c3654065bb42edc0156a774831ad831b8ee9b11.tar.gz chromium_src-0c3654065bb42edc0156a774831ad831b8ee9b11.tar.bz2 |
Use GURL for stringifying IPEndPoint rather than the system network libraries.
BUG=126212
Review URL: https://chromiumcodereview.appspot.com/10910136
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@155569 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/base/ip_endpoint.cc | 53 | ||||
-rw-r--r-- | net/base/ip_endpoint_unittest.cc | 4 | ||||
-rw-r--r-- | net/base/net_util.cc | 73 | ||||
-rw-r--r-- | net/base/net_util.h | 53 | ||||
-rw-r--r-- | net/base/net_util_unittest.cc | 23 |
5 files changed, 143 insertions, 63 deletions
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc index b8a161b..8dc8e9a 100644 --- a/net/base/ip_endpoint.cc +++ b/net/base/ip_endpoint.cc @@ -80,52 +80,29 @@ bool IPEndPoint::ToSockAddr(struct sockaddr* address, return true; } -bool IPEndPoint::FromSockAddr(const struct sockaddr* address, - socklen_t address_length) { - DCHECK(address); - switch (address->sa_family) { - case AF_INET: { - if (address_length < kSockaddrInSize) - return false; - const struct sockaddr_in* addr = - reinterpret_cast<const struct sockaddr_in*>(address); - port_ = base::NetToHost16(addr->sin_port); - const char* bytes = reinterpret_cast<const char*>(&addr->sin_addr); - address_.assign(&bytes[0], &bytes[kIPv4AddressSize]); - break; - } - case AF_INET6: { - if (address_length < kSockaddrIn6Size) - return false; - const struct sockaddr_in6* addr = - reinterpret_cast<const struct sockaddr_in6*>(address); - port_ = base::NetToHost16(addr->sin6_port); - const char* bytes = reinterpret_cast<const char*>(&addr->sin6_addr); - address_.assign(&bytes[0], &bytes[kIPv6AddressSize]); - break; - } - default: - return false; +bool IPEndPoint::FromSockAddr(const struct sockaddr* sock_addr, + socklen_t sock_addr_len) { + DCHECK(sock_addr); + + const uint8* address; + size_t address_len; + uint16 port; + if (!GetIPAddressFromSockAddr(sock_addr, sock_addr_len, &address, + &address_len, &port)) { + return false; } + + address_.assign(address, address + address_len); + port_ = port; return true; } std::string IPEndPoint::ToString() const { - SockaddrStorage storage; - if (!ToSockAddr(storage.addr, &storage.addr_len)) { - return std::string(); - } - // TODO(szym): Don't use getnameinfo. http://crbug.com/126212 - return NetAddressToStringWithPort(storage.addr, storage.addr_len); + return IPAddressToStringWithPort(address_, port_); } std::string IPEndPoint::ToStringWithoutPort() const { - SockaddrStorage storage; - if (!ToSockAddr(storage.addr, &storage.addr_len)) { - return std::string(); - } - // TODO(szym): Don't use getnameinfo. http://crbug.com/126212 - return NetAddressToString(storage.addr, storage.addr_len); + return IPAddressToString(address_); } bool IPEndPoint::operator<(const IPEndPoint& that) const { diff --git a/net/base/ip_endpoint_unittest.cc b/net/base/ip_endpoint_unittest.cc index f93a08f..2ddc282 100644 --- a/net/base/ip_endpoint_unittest.cc +++ b/net/base/ip_endpoint_unittest.cc @@ -163,10 +163,6 @@ TEST_F(IPEndPointTest, ToString) { int port = 100 + index; IPEndPoint endpoint(tests[index].ip_address, port); const std::string result = endpoint.ToString(); - if (tests[index].ipv6 && result.empty()) { - // NetAddressToStringWithPort may fail on systems without IPv6. - continue; - } EXPECT_EQ(tests[index].host_normalized + ":" + base::IntToString(port), result); } diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 40c734f..df30c5f 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -1626,8 +1626,64 @@ std::string GetHostAndOptionalPort(const GURL& url) { return url.host(); } -std::string NetAddressToString(const struct addrinfo* net_address) { - return NetAddressToString(net_address->ai_addr, net_address->ai_addrlen); +// Extracts the address and port portions of a sockaddr. +bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, + socklen_t sock_addr_len, + const uint8** address, + size_t* address_len, + uint16* port) { + if (sock_addr->sa_family == AF_INET) { + if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) + return false; + const struct sockaddr_in* addr = + reinterpret_cast<const struct sockaddr_in*>(sock_addr); + *address = reinterpret_cast<const uint8*>(&addr->sin_addr); + *address_len = kIPv4AddressSize; + *port = base::NetToHost16(addr->sin_port); + return true; + } + + if (sock_addr->sa_family == AF_INET6) { + if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in6))) + return false; + const struct sockaddr_in6* addr = + reinterpret_cast<const struct sockaddr_in6*>(sock_addr); + *address = reinterpret_cast<const unsigned char*>(&addr->sin6_addr); + *address_len = kIPv6AddressSize; + *port = base::NetToHost16(addr->sin6_port); + return true; + } + + return false; // Unrecognized |sa_family|. +} + +std::string IPAddressToString(const uint8* address, + size_t address_len) { + std::string str; + url_canon::StdStringCanonOutput output(&str); + + if (address_len == kIPv4AddressSize) { + url_canon::AppendIPv4Address(address, &output); + } else if (address_len == kIPv6AddressSize) { + url_canon::AppendIPv6Address(address, &output); + } else { + CHECK(false) << "Invalid IP address with length: " << address_len; + } + + output.Complete(); + return str; +} + +std::string IPAddressToStringWithPort(const uint8* address, + size_t address_len, + uint16 port) { + std::string address_str = IPAddressToString(address, address_len); + + if (address_len == kIPv6AddressSize) { + // Need to bracket IPv6 addresses since they contain colons. + return base::StringPrintf("[%s]:%d", address_str.c_str(), port); + } + return base::StringPrintf("%s:%d", address_str.c_str(), port); } std::string NetAddressToString(const struct sockaddr* net_address, @@ -1650,10 +1706,6 @@ std::string NetAddressToString(const struct sockaddr* net_address, return std::string(buffer); } -std::string NetAddressToStringWithPort(const struct addrinfo* net_address) { - return NetAddressToStringWithPort( - net_address->ai_addr, net_address->ai_addrlen); -} std::string NetAddressToStringWithPort(const struct sockaddr* net_address, socklen_t address_len) { std::string ip_address_string = NetAddressToString(net_address, address_len); @@ -1670,6 +1722,15 @@ std::string NetAddressToStringWithPort(const struct sockaddr* net_address, return base::StringPrintf("%s:%d", ip_address_string.c_str(), port); } +std::string IPAddressToString(const IPAddressNumber& addr) { + return IPAddressToString(&addr.front(), addr.size()); +} + +std::string IPAddressToStringWithPort(const IPAddressNumber& addr, + uint16 port) { + return IPAddressToStringWithPort(&addr.front(), addr.size(), port); +} + std::string GetHostName() { #if defined(OS_WIN) EnsureWinsockInit(); diff --git a/net/base/net_util.h b/net/base/net_util.h index fef0a78..ddbf018 100644 --- a/net/base/net_util.h +++ b/net/base/net_util.h @@ -47,6 +47,17 @@ namespace net { typedef uint32 FormatUrlType; typedef uint32 FormatUrlTypes; +// IPAddressNumber is used to represent an IP address's numeric value as an +// array of bytes, from most significant to least significant. This is the +// network byte ordering. +// +// IPv4 addresses will have length 4, whereas IPv6 address will have length 16. +typedef std::vector<unsigned char> IPAddressNumber; +typedef std::vector<IPAddressNumber> IPAddressList; + +static const size_t kIPv4AddressSize = 4; +static const size_t kIPv6AddressSize = 16; + // Nothing is ommitted. NET_EXPORT extern const FormatUrlType kFormatUrlOmitNothing; @@ -108,17 +119,40 @@ struct SockaddrStorage { struct sockaddr* const addr; }; -// Returns the string representation of an address, like "192.168.0.1". -// Returns empty string on failure. +// Extracts the IP address and port portions of a sockaddr. +bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, + socklen_t sock_addr_len, + const unsigned char** address, + size_t* address_len, + uint16* port); + +// Returns the string representation of an IP address. +// For example: "192.168.0.1" or "::1". +NET_EXPORT std::string IPAddressToString(const uint8* address, + size_t address_len); + +// Returns the string representation of an IP address along with its port. +// For example: "192.168.0.1:99" or "[::1]:80". +NET_EXPORT std::string IPAddressToStringWithPort(const uint8* address, + size_t address_len, + uint16 port); + +// Same as IPAddressToString() but for a sockaddr. NET_EXPORT std::string NetAddressToString(const struct sockaddr* net_address, socklen_t address_len); -// Same as NetAddressToString, but additionally includes the port number. For -// example: "192.168.0.1:99" or "[::1]:80". +// Same as IPAddressToStringWithPort() but for a sockaddr. NET_EXPORT std::string NetAddressToStringWithPort( const struct sockaddr* net_address, socklen_t address_len); +// Same as IPAddressToString() but for an IPAddressNumber. +NET_EXPORT std::string IPAddressToString(const IPAddressNumber& addr); + +// Same as IPAddressToStringWithPort() but for an IPAddressNumber. +NET_EXPORT std::string IPAddressToStringWithPort( + const IPAddressNumber& addr, uint16 port); + // Returns the hostname of the current system. Returns empty string on failure. NET_EXPORT std::string GetHostName(); @@ -403,17 +437,6 @@ NET_EXPORT IPv6SupportResult TestIPv6Support(); // Also returns false if it cannot determine this. bool HaveOnlyLoopbackAddresses(); -// IPAddressNumber is used to represent an IP address's numeric value as an -// array of bytes, from most significant to least significant. This is the -// network byte ordering. -// -// IPv4 addresses will have length 4, whereas IPv6 address will have length 16. -typedef std::vector<unsigned char> IPAddressNumber; -typedef std::vector<IPAddressNumber> IPAddressList; - -static const size_t kIPv4AddressSize = 4; -static const size_t kIPv6AddressSize = 16; - // Parses an IP address literal (either IPv4 or IPv6) to its numeric value. // Returns true on success and fills |ip_number| with the numeric value. NET_EXPORT_PRIVATE bool ParseIPLiteralToNumber(const std::string& ip_literal, diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc index ffab57e..a99fbe5 100644 --- a/net/base/net_util_unittest.cc +++ b/net/base/net_util_unittest.cc @@ -2254,6 +2254,29 @@ TEST(NetUtilTest, GetHostAndOptionalPort) { } } +TEST(NetUtilTest, IPAddressToString) { + uint8 addr1[4] = {0, 0, 0, 0}; + EXPECT_EQ("0.0.0.0", IPAddressToString(addr1, sizeof(addr1))); + + uint8 addr2[4] = {192, 168, 0, 1}; + EXPECT_EQ("192.168.0.1", IPAddressToString(addr2, sizeof(addr2))); + + uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98}; + EXPECT_EQ("fedc:ba98::", IPAddressToString(addr3, sizeof(addr3))); +} + +TEST(NetUtilTest, IPAddressToStringWithPort) { + uint8 addr1[4] = {0, 0, 0, 0}; + EXPECT_EQ("0.0.0.0:3", IPAddressToStringWithPort(addr1, sizeof(addr1), 3)); + + uint8 addr2[4] = {192, 168, 0, 1}; + EXPECT_EQ("192.168.0.1:99", + IPAddressToStringWithPort(addr2, sizeof(addr2), 99)); + + uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98}; + EXPECT_EQ("[fedc:ba98::]:8080", + IPAddressToStringWithPort(addr3, sizeof(addr3), 8080)); +} TEST(NetUtilTest, NetAddressToString_IPv4) { const struct { |