Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 #include <map> | 9 #include <map> |
| 10 | 10 |
| (...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1384 } | 1384 } |
| 1385 | 1385 |
| 1386 std::string GetHostAndOptionalPort(const GURL& url) { | 1386 std::string GetHostAndOptionalPort(const GURL& url) { |
| 1387 // For IPv6 literals, GURL::host() already includes the brackets | 1387 // For IPv6 literals, GURL::host() already includes the brackets |
| 1388 // so it is safe to just append a colon. | 1388 // so it is safe to just append a colon. |
| 1389 if (url.has_port()) | 1389 if (url.has_port()) |
| 1390 return base::StringPrintf("%s:%s", url.host().c_str(), url.port().c_str()); | 1390 return base::StringPrintf("%s:%s", url.host().c_str(), url.port().c_str()); |
| 1391 return url.host(); | 1391 return url.host(); |
| 1392 } | 1392 } |
| 1393 | 1393 |
| 1394 // static | |
| 1395 bool IsHostnameNonUnique(const std::string& hostname) { | 1394 bool IsHostnameNonUnique(const std::string& hostname) { |
| 1396 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. | 1395 // CanonicalizeHost requires surrounding brackets to parse an IPv6 address. |
| 1397 const std::string host_or_ip = hostname.find(':') != std::string::npos ? | 1396 const std::string host_or_ip = hostname.find(':') != std::string::npos ? |
| 1398 "[" + hostname + "]" : hostname; | 1397 "[" + hostname + "]" : hostname; |
| 1399 url_canon::CanonHostInfo host_info; | 1398 url_canon::CanonHostInfo host_info; |
| 1400 std::string canonical_name = CanonicalizeHost(host_or_ip, &host_info); | 1399 std::string canonical_name = CanonicalizeHost(host_or_ip, &host_info); |
| 1401 | 1400 |
| 1402 // If canonicalization fails, then the input is truly malformed. However, | 1401 // If canonicalization fails, then the input is truly malformed. However, |
| 1403 // to avoid mis-reporting bad inputs as "non-unique", treat them as unique. | 1402 // to avoid mis-reporting bad inputs as "non-unique", treat them as unique. |
| 1404 if (canonical_name.empty()) | 1403 if (canonical_name.empty()) |
| 1405 return false; | 1404 return false; |
| 1406 | 1405 |
| 1407 // If |hostname| is an IP address, presume it's unique. | 1406 // If |hostname| is an IP address, check to see if it's in an IANA-reserved |
| 1408 // TODO(rsleevi): In the future, this should also reject IP addresses in | 1407 // range. |
| 1409 // IANA-reserved ranges. | 1408 if (host_info.IsIPAddress()) { |
| 1410 if (host_info.IsIPAddress()) | 1409 IPAddressNumber host_addr; |
| 1411 return false; | 1410 if (!ParseIPLiteralToNumber(hostname.substr(host_info.out_host.begin, |
| 1411 host_info.out_host.len), | |
| 1412 &host_addr)) { | |
| 1413 return false; | |
| 1414 } | |
| 1415 switch (host_info.family) { | |
| 1416 case url_canon::CanonHostInfo::IPV4: | |
| 1417 case url_canon::CanonHostInfo::IPV6: | |
| 1418 return IsIPAddressReserved(host_addr); | |
| 1419 case url_canon::CanonHostInfo::NEUTRAL: | |
| 1420 case url_canon::CanonHostInfo::BROKEN: | |
| 1421 return false; | |
| 1422 } | |
| 1423 } | |
| 1412 | 1424 |
| 1413 // Check for a registry controlled portion of |hostname|, ignoring private | 1425 // Check for a registry controlled portion of |hostname|, ignoring private |
| 1414 // registries, as they already chain to ICANN-administered registries, | 1426 // registries, as they already chain to ICANN-administered registries, |
| 1415 // and explicitly ignoring unknown registries. | 1427 // and explicitly ignoring unknown registries. |
| 1416 // | 1428 // |
| 1417 // Note: This means that as new gTLDs are introduced on the Internet, they | 1429 // Note: This means that as new gTLDs are introduced on the Internet, they |
| 1418 // will be treated as non-unique until the registry controlled domain list | 1430 // will be treated as non-unique until the registry controlled domain list |
| 1419 // is updated. However, because gTLDs are expected to provide significant | 1431 // is updated. However, because gTLDs are expected to provide significant |
| 1420 // advance notice to deprecate older versions of this code, this an | 1432 // advance notice to deprecate older versions of this code, this an |
| 1421 // acceptable tradeoff. | 1433 // acceptable tradeoff. |
| 1422 return 0 == registry_controlled_domains::GetRegistryLength( | 1434 return 0 == registry_controlled_domains::GetRegistryLength( |
| 1423 canonical_name, | 1435 canonical_name, |
| 1424 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | 1436 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
| 1425 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | 1437 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
| 1426 } | 1438 } |
| 1427 | 1439 |
| 1440 template<typename Arr, typename Length> | |
|
Ryan Sleevi
2013/08/09 22:50:12
You can treat length as a size_t and let integer p
felt
2013/08/10 03:04:33
Done.
| |
| 1441 bool IPNumberPrefixCheck(const IPAddressNumber& ip_number, | |
| 1442 Arr ip_prefix, | |
|
Ryan Sleevi
2013/08/09 22:50:12
This doesn't match your definition in the header (
felt
2013/08/10 03:04:33
Done.
| |
| 1443 Length prefix_length_in_bits) { | |
| 1444 // Compare all the bytes that fall entirely within the prefix. | |
| 1445 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8; | |
| 1446 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) { | |
| 1447 if (ip_number[i] != ip_prefix[i]) | |
| 1448 return false; | |
| 1449 } | |
| 1450 | |
| 1451 // In case the prefix was not a multiple of 8, there will be 1 byte | |
| 1452 // which is only partially masked. | |
| 1453 int remaining_bits = prefix_length_in_bits % 8; | |
| 1454 if (remaining_bits != 0) { | |
| 1455 unsigned char mask = 0xFF << (8 - remaining_bits); | |
| 1456 int i = num_entire_bytes_in_prefix; | |
| 1457 if ((ip_number[i] & mask) != (ip_prefix[i] & mask)) | |
| 1458 return false; | |
| 1459 } | |
| 1460 return true; | |
| 1461 } | |
| 1462 | |
| 1463 // We shouldn't compare IPv4 to IPv6 (they have different range reservations), | |
| 1464 // so we keep separate arrays. Within each array, adjacent reserved ranges are | |
| 1465 // consolidated when possible. | |
| 1466 // Sources for info: | |
| 1467 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml | |
| 1468 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml | |
| 1469 // They're formatted here with the prefix as the last element. For example: | |
| 1470 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10. | |
| 1471 bool IsIPAddressReserved(const IPAddressNumber& host_addr) { | |
| 1472 const unsigned char reserved_ipv4[][5] = { | |
|
Ryan Sleevi
2013/08/09 22:50:12
nit: static const unsigned char kReservedIPv4
felt
2013/08/10 03:04:33
Done.
| |
| 1473 { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 }, | |
| 1474 { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 }, { 192,88,99,0,24 }, | |
| 1475 { 192,168,0,0,16 }, { 198,18,0,0,15 }, { 198,51,100,0,24 }, | |
| 1476 { 203,0,113,0,24 }, { 224,0,0,0,3 } | |
| 1477 }; | |
| 1478 const unsigned char reserved_ipv6[][17] = { | |
|
Ryan Sleevi
2013/08/09 22:50:12
nit: static const unsigned char kReservedIPv6
felt
2013/08/10 03:04:33
Done.
| |
| 1479 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 }, | |
| 1480 { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, | |
| 1481 { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, | |
| 1482 { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 }, | |
| 1483 { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 }, | |
| 1484 { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 }, | |
| 1485 { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 }, | |
| 1486 { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 }, | |
| 1487 { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 }, | |
| 1488 { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, | |
| 1489 { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, | |
| 1490 }; | |
| 1491 bool ipv4 = (host_addr.size() == kIPv4AddressSize); | |
| 1492 size_t arr_size = (ipv4) ? | |
| 1493 arraysize(reserved_ipv4) : arraysize(reserved_ipv6); | |
| 1494 bool match = false; | |
| 1495 for (size_t i = 0; i < arr_size; ++i) { | |
| 1496 if (ipv4) { | |
| 1497 match = IPNumberPrefixCheck( | |
| 1498 host_addr, reserved_ipv4[i], reserved_ipv4[i][4]); | |
| 1499 } else { | |
| 1500 match = IPNumberPrefixCheck( | |
| 1501 host_addr, reserved_ipv6[i], reserved_ipv6[i][16]); | |
| 1502 } | |
| 1503 if (match) | |
| 1504 return true; | |
| 1505 } | |
|
Ryan Sleevi
2013/08/09 22:50:12
FWIW, you could rewrite this as
size_t array_size
Ryan Sleevi
2013/08/09 22:51:31
and I made a typo :)
"const char* const* array" -
felt
2013/08/10 03:04:33
I didn't use this exactly, but something like it.
| |
| 1506 return false; | |
| 1507 } | |
| 1508 | |
| 1428 // Extracts the address and port portions of a sockaddr. | 1509 // Extracts the address and port portions of a sockaddr. |
| 1429 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, | 1510 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, |
| 1430 socklen_t sock_addr_len, | 1511 socklen_t sock_addr_len, |
| 1431 const uint8** address, | 1512 const uint8** address, |
| 1432 size_t* address_len, | 1513 size_t* address_len, |
| 1433 uint16* port) { | 1514 uint16* port) { |
| 1434 if (sock_addr->sa_family == AF_INET) { | 1515 if (sock_addr->sa_family == AF_INET) { |
| 1435 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) | 1516 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) |
| 1436 return false; | 1517 return false; |
| 1437 const struct sockaddr_in* addr = | 1518 const struct sockaddr_in* addr = |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1989 if (ip_number.size() != ip_prefix.size()) { | 2070 if (ip_number.size() != ip_prefix.size()) { |
| 1990 if (ip_number.size() == 4) { | 2071 if (ip_number.size() == 4) { |
| 1991 return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number), | 2072 return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number), |
| 1992 ip_prefix, prefix_length_in_bits); | 2073 ip_prefix, prefix_length_in_bits); |
| 1993 } | 2074 } |
| 1994 return IPNumberMatchesPrefix(ip_number, | 2075 return IPNumberMatchesPrefix(ip_number, |
| 1995 ConvertIPv4NumberToIPv6Number(ip_prefix), | 2076 ConvertIPv4NumberToIPv6Number(ip_prefix), |
| 1996 96 + prefix_length_in_bits); | 2077 96 + prefix_length_in_bits); |
| 1997 } | 2078 } |
| 1998 | 2079 |
| 1999 // Otherwise we are comparing two IPv4 addresses, or two IPv6 addresses. | 2080 return IPNumberPrefixCheck(ip_number, ip_prefix, prefix_length_in_bits); |
|
Ryan Sleevi
2013/08/09 22:50:12
Just pass &ip_prefix[0] here - char* goodness, wit
felt
2013/08/10 03:04:33
Ahhhh.
| |
| 2000 // Compare all the bytes that fall entirely within the prefix. | |
| 2001 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8; | |
| 2002 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) { | |
| 2003 if (ip_number[i] != ip_prefix[i]) | |
| 2004 return false; | |
| 2005 } | |
| 2006 | |
| 2007 // In case the prefix was not a multiple of 8, there will be 1 byte | |
| 2008 // which is only partially masked. | |
| 2009 int remaining_bits = prefix_length_in_bits % 8; | |
| 2010 if (remaining_bits != 0) { | |
| 2011 unsigned char mask = 0xFF << (8 - remaining_bits); | |
| 2012 int i = num_entire_bytes_in_prefix; | |
| 2013 if ((ip_number[i] & mask) != (ip_prefix[i] & mask)) | |
| 2014 return false; | |
| 2015 } | |
| 2016 | |
| 2017 return true; | |
| 2018 } | 2081 } |
| 2019 | 2082 |
| 2020 const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address, | 2083 const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address, |
| 2021 socklen_t address_len) { | 2084 socklen_t address_len) { |
| 2022 if (address->sa_family == AF_INET) { | 2085 if (address->sa_family == AF_INET) { |
| 2023 DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len)); | 2086 DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len)); |
| 2024 const struct sockaddr_in* sockaddr = | 2087 const struct sockaddr_in* sockaddr = |
| 2025 reinterpret_cast<const struct sockaddr_in*>(address); | 2088 reinterpret_cast<const struct sockaddr_in*>(address); |
| 2026 return &sockaddr->sin_port; | 2089 return &sockaddr->sin_port; |
| 2027 } else if (address->sa_family == AF_INET6) { | 2090 } else if (address->sa_family == AF_INET6) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2081 | 2144 |
| 2082 NetworkInterface::NetworkInterface(const std::string& name, | 2145 NetworkInterface::NetworkInterface(const std::string& name, |
| 2083 const IPAddressNumber& address) | 2146 const IPAddressNumber& address) |
| 2084 : name(name), address(address) { | 2147 : name(name), address(address) { |
| 2085 } | 2148 } |
| 2086 | 2149 |
| 2087 NetworkInterface::~NetworkInterface() { | 2150 NetworkInterface::~NetworkInterface() { |
| 2088 } | 2151 } |
| 2089 | 2152 |
| 2090 } // namespace net | 2153 } // namespace net |
| OLD | NEW |