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 bool IPNumberPrefixCheck(const IPAddressNumber& ip_number, | |
| 1441 const unsigned char* ip_prefix, | |
| 1442 size_t prefix_length_in_bits) { | |
| 1443 // Compare all the bytes that fall entirely within the prefix. | |
| 1444 int num_entire_bytes_in_prefix = prefix_length_in_bits / 8; | |
| 1445 for (int i = 0; i < num_entire_bytes_in_prefix; ++i) { | |
| 1446 if (ip_number[i] != ip_prefix[i]) | |
| 1447 return false; | |
| 1448 } | |
| 1449 | |
| 1450 // In case the prefix was not a multiple of 8, there will be 1 byte | |
| 1451 // which is only partially masked. | |
| 1452 int remaining_bits = prefix_length_in_bits % 8; | |
| 1453 if (remaining_bits != 0) { | |
| 1454 unsigned char mask = 0xFF << (8 - remaining_bits); | |
| 1455 int i = num_entire_bytes_in_prefix; | |
| 1456 if ((ip_number[i] & mask) != (ip_prefix[i] & mask)) | |
|
Ryan Sleevi
2013/08/12 21:11:51
style nit: indentation is off by one here
felt
2013/08/13 04:17:06
Done.
| |
| 1457 return false; | |
| 1458 } | |
| 1459 return true; | |
| 1460 } | |
| 1461 | |
| 1462 // We shouldn't compare IPv4 to IPv6 (they have different range reservations), | |
| 1463 // so we keep separate arrays. Within each array, adjacent reserved ranges are | |
| 1464 // consolidated when possible. | |
|
Ryan Sleevi
2013/08/12 21:11:51
Can you rewrite this comment without the "We". Enj
felt
2013/08/13 04:17:06
Oh, huh, I hadn't heard that before. Done.
| |
| 1465 // Sources for info: | |
| 1466 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml | |
| 1467 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml | |
| 1468 // They're formatted here with the prefix as the last element. For example: | |
| 1469 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10. | |
| 1470 bool IsIPAddressReserved(const IPAddressNumber& host_addr) { | |
| 1471 static const unsigned char kReservedIPv4[][5] = { | |
| 1472 { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 }, | |
| 1473 { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 }, { 192,88,99,0,24 }, | |
| 1474 { 192,168,0,0,16 }, { 198,18,0,0,15 }, { 198,51,100,0,24 }, | |
| 1475 { 203,0,113,0,24 }, { 224,0,0,0,3 } | |
|
Ryan Sleevi
2013/08/12 21:11:51
style nit: four spaces
felt
2013/08/13 04:17:06
Done.
| |
| 1476 }; | |
| 1477 static const unsigned char kReservedIPv6[][17] = { | |
| 1478 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 }, | |
| 1479 { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, | |
| 1480 { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, | |
| 1481 { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 }, | |
| 1482 { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 }, | |
| 1483 { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 }, | |
| 1484 { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 }, | |
| 1485 { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 }, | |
| 1486 { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 }, | |
| 1487 { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, | |
| 1488 { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, | |
|
Ryan Sleevi
2013/08/12 21:11:51
style nit: four spaces
felt
2013/08/13 04:17:06
Done.
| |
| 1489 }; | |
| 1490 size_t array_size = 0; | |
| 1491 const unsigned char* array = NULL; | |
| 1492 switch (host_addr.size()) { | |
| 1493 case kIPv4AddressSize: | |
| 1494 array_size = arraysize(kReservedIPv4); | |
| 1495 array = kReservedIPv4[0]; | |
| 1496 break; | |
| 1497 case kIPv6AddressSize: | |
| 1498 array_size = arraysize(kReservedIPv6); | |
| 1499 array = kReservedIPv6[0]; | |
| 1500 break; | |
| 1501 } | |
| 1502 if (!array) | |
| 1503 return false; | |
| 1504 int width = host_addr.size()+1; | |
|
Ryan Sleevi
2013/08/12 21:11:51
style nit: "host_addr.size()+1" -> "host_addr.size
felt
2013/08/13 04:17:06
Done.
| |
| 1505 for (size_t i = 0; i < array_size*width; i = i + width) { | |
|
Ryan Sleevi
2013/08/12 21:11:51
style nit:
"array_size*width" -> "array_size * wid
felt
2013/08/13 04:17:06
is it generally preferred to avoid indexing, or is
Ryan Sleevi
2013/08/13 20:45:39
Shorter and more readable. Forms like (&foo[bar])[
| |
| 1506 if (IPNumberPrefixCheck( | |
| 1507 host_addr, &array[i], (&array[i])[width-1])) { | |
| 1508 return true; | |
| 1509 } | |
| 1510 } | |
| 1511 return false; | |
| 1512 } | |
| 1513 | |
| 1428 // Extracts the address and port portions of a sockaddr. | 1514 // Extracts the address and port portions of a sockaddr. |
| 1429 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, | 1515 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, |
| 1430 socklen_t sock_addr_len, | 1516 socklen_t sock_addr_len, |
| 1431 const uint8** address, | 1517 const uint8** address, |
| 1432 size_t* address_len, | 1518 size_t* address_len, |
| 1433 uint16* port) { | 1519 uint16* port) { |
| 1434 if (sock_addr->sa_family == AF_INET) { | 1520 if (sock_addr->sa_family == AF_INET) { |
| 1435 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) | 1521 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) |
| 1436 return false; | 1522 return false; |
| 1437 const struct sockaddr_in* addr = | 1523 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()) { | 2075 if (ip_number.size() != ip_prefix.size()) { |
| 1990 if (ip_number.size() == 4) { | 2076 if (ip_number.size() == 4) { |
| 1991 return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number), | 2077 return IPNumberMatchesPrefix(ConvertIPv4NumberToIPv6Number(ip_number), |
| 1992 ip_prefix, prefix_length_in_bits); | 2078 ip_prefix, prefix_length_in_bits); |
| 1993 } | 2079 } |
| 1994 return IPNumberMatchesPrefix(ip_number, | 2080 return IPNumberMatchesPrefix(ip_number, |
| 1995 ConvertIPv4NumberToIPv6Number(ip_prefix), | 2081 ConvertIPv4NumberToIPv6Number(ip_prefix), |
| 1996 96 + prefix_length_in_bits); | 2082 96 + prefix_length_in_bits); |
| 1997 } | 2083 } |
| 1998 | 2084 |
| 1999 // Otherwise we are comparing two IPv4 addresses, or two IPv6 addresses. | 2085 return IPNumberPrefixCheck(ip_number, &ip_prefix[0], prefix_length_in_bits); |
| 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 } | 2086 } |
| 2019 | 2087 |
| 2020 const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address, | 2088 const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address, |
| 2021 socklen_t address_len) { | 2089 socklen_t address_len) { |
| 2022 if (address->sa_family == AF_INET) { | 2090 if (address->sa_family == AF_INET) { |
| 2023 DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len)); | 2091 DCHECK_LE(sizeof(sockaddr_in), static_cast<size_t>(address_len)); |
| 2024 const struct sockaddr_in* sockaddr = | 2092 const struct sockaddr_in* sockaddr = |
| 2025 reinterpret_cast<const struct sockaddr_in*>(address); | 2093 reinterpret_cast<const struct sockaddr_in*>(address); |
| 2026 return &sockaddr->sin_port; | 2094 return &sockaddr->sin_port; |
| 2027 } else if (address->sa_family == AF_INET6) { | 2095 } else if (address->sa_family == AF_INET6) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2081 | 2149 |
| 2082 NetworkInterface::NetworkInterface(const std::string& name, | 2150 NetworkInterface::NetworkInterface(const std::string& name, |
| 2083 const IPAddressNumber& address) | 2151 const IPAddressNumber& address) |
| 2084 : name(name), address(address) { | 2152 : name(name), address(address) { |
| 2085 } | 2153 } |
| 2086 | 2154 |
| 2087 NetworkInterface::~NetworkInterface() { | 2155 NetworkInterface::~NetworkInterface() { |
| 2088 } | 2156 } |
| 2089 | 2157 |
| 2090 } // namespace net | 2158 } // namespace net |
| OLD | NEW |