Chromium Code Reviews| Index: net/base/net_util.cc |
| diff --git a/net/base/net_util.cc b/net/base/net_util.cc |
| index 958e3c3bca82049671f39fda3574b7eca3871664..df6b3fa6168c453185a76f9dec8759370907ef05 100644 |
| --- a/net/base/net_util.cc |
| +++ b/net/base/net_util.cc |
| @@ -1391,7 +1391,6 @@ std::string GetHostAndOptionalPort(const GURL& url) { |
| return url.host(); |
| } |
| -// static |
| bool IsHostnameNonUnique(const std::string& hostname) { |
| // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. |
| const std::string host_or_ip = hostname.find(':') != std::string::npos ? |
| @@ -1404,11 +1403,19 @@ bool IsHostnameNonUnique(const std::string& hostname) { |
| if (canonical_name.empty()) |
| return false; |
| - // If |hostname| is an IP address, presume it's unique. |
| - // TODO(rsleevi): In the future, this should also reject IP addresses in |
| - // IANA-reserved ranges. |
| - if (host_info.IsIPAddress()) |
| - return false; |
| + // If |hostname| is an IP address, check to see if it's in an IANA-reserved |
| + // range. |
| + if (host_info.IsIPAddress()) { |
| + switch (host_info.family) { |
| + case url_canon::CanonHostInfo::IPV4: |
| + return IsIPAddressReserved(hostname, true); |
| + case url_canon::CanonHostInfo::IPV6: |
| + return IsIPAddressReserved(hostname, false); |
| + case url_canon::CanonHostInfo::NEUTRAL: |
| + case url_canon::CanonHostInfo::BROKEN: |
| + return false; |
| + } |
| + } |
| // Check for a registry controlled portion of |hostname|, ignoring private |
| // registries, as they already chain to ICANN-administered registries, |
| @@ -1425,6 +1432,47 @@ bool IsHostnameNonUnique(const std::string& hostname) { |
| registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
| } |
| +bool IsIPAddressReserved(const std::string& hostname, bool ipv4) { |
| + LOG(INFO) << "IsIPAddressReserved " << hostname; |
| + IPAddressNumber host_addr; |
| + if (!ParseIPLiteralToNumber(hostname, &host_addr)) return false; |
|
Ryan Sleevi
2013/08/07 19:04:44
nit: linebreak for the if.
felt
2013/08/08 19:35:33
Done.
|
| + |
| + // We shouldn't compare IPv4 to IPv6, so we keep separate arrays. |
| + static const char* const reserved_ipv4[] = { |
| + "0.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "127.0.0.0/8", |
| + "169.254.0.0/16", "172.16.0.0/12", "192.0.2.0/24", "192.88.99.0/24", |
| + "192.168.0.0/16", "198.18.0.0/15", "198.51.100.0/24", "203.0.113.0/24", |
| + "224.0.0.0/8", "225.0.0.0/8", "226.0.0.0/8", "227.0.0.0/8", "228.0.0.0/8", |
| + "229.0.0.0/8", "230.0.0.0/8", "231.0.0.0/8", "232.0.0.0/8", "233.0.0.0/8", |
| + "234.0.0.0/8", "235.0.0.0/8", "236.0.0.0/8", "237.0.0.0/8", "238.0.0.0/8", |
| + "239.0.0.0/8", "240.0.0.0/8", "241.0.0.0/8", "242.0.0.0/8", "243.0.0.0/8", |
| + "244.0.0.0/8", "245.0.0.0/8", "246.0.0.0/8", "247.0.0.0/8", "248.0.0.0/8", |
| + "249.0.0.0/8", "250.0.0.0/8", "251.0.0.0/8", "252.0.0.0/8", "253.0.0.0/8", |
| + "254.0.0.0/8", "255.0.0.0/8" |
| + }; |
|
Ryan Sleevi
2013/08/07 19:04:44
List the sources for these.
eg:
http://www.iana.o
felt
2013/08/08 19:35:33
Done.
|
| + static const char* const reserved_ipv6[] = { |
| + "0000::/8", "::1/128", "0100::/8", "0200::/7", "0400::/6", "0800::/5", |
| + "1000::/4", "4000::/3", "6000::/3", "8000::/3", "a000::/3", "c000::/3", |
| + "e000::/4", "f000::/5", "f800::/6", "FC00::/7", "fe00::/9", "fe80::/10", |
| + "fec0::/10" |
|
Ryan Sleevi
2013/08/07 19:04:44
List the sources for this data:
http://www.iana.o
felt
2013/08/08 19:35:33
Done
|
| + }; |
|
Ryan Sleevi
2013/08/07 19:04:44
Rather than storing these as strings (and re-parsi
felt
2013/08/08 19:35:33
Done.
|
| + |
| + size_t array_size = |
| + ipv4 ? arraysize(reserved_ipv4) : arraysize(reserved_ipv6); |
| + for (size_t i = 0; i < array_size; i++) { |
| + IPAddressNumber reserved_address; |
| + size_t prefix_length; |
| + DCHECK(ParseCIDRBlock(ipv4 ? reserved_ipv4[i] : reserved_ipv6[i], |
| + &reserved_address, |
| + &prefix_length)); |
| + LOG(INFO) << ipv4; |
| + LOG(INFO) << i; |
| + if (IPNumberMatchesPrefix(host_addr, reserved_address, prefix_length)) |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| // Extracts the address and port portions of a sockaddr. |
| bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, |
| socklen_t sock_addr_len, |