| 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, &host_addr)) |
| 1411 return false; |
| 1412 switch (host_info.family) { |
| 1413 case url_canon::CanonHostInfo::IPV4: |
| 1414 return IsIPAddressReserved(host_addr, true); |
| 1415 case url_canon::CanonHostInfo::IPV6: |
| 1416 return IsIPAddressReserved(host_addr, false); |
| 1417 case url_canon::CanonHostInfo::NEUTRAL: |
| 1418 case url_canon::CanonHostInfo::BROKEN: |
| 1419 return false; |
| 1420 } |
| 1421 } |
| 1412 | 1422 |
| 1413 // Check for a registry controlled portion of |hostname|, ignoring private | 1423 // Check for a registry controlled portion of |hostname|, ignoring private |
| 1414 // registries, as they already chain to ICANN-administered registries, | 1424 // registries, as they already chain to ICANN-administered registries, |
| 1415 // and explicitly ignoring unknown registries. | 1425 // and explicitly ignoring unknown registries. |
| 1416 // | 1426 // |
| 1417 // Note: This means that as new gTLDs are introduced on the Internet, they | 1427 // 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 | 1428 // will be treated as non-unique until the registry controlled domain list |
| 1419 // is updated. However, because gTLDs are expected to provide significant | 1429 // is updated. However, because gTLDs are expected to provide significant |
| 1420 // advance notice to deprecate older versions of this code, this an | 1430 // advance notice to deprecate older versions of this code, this an |
| 1421 // acceptable tradeoff. | 1431 // acceptable tradeoff. |
| 1422 return 0 == registry_controlled_domains::GetRegistryLength( | 1432 return 0 == registry_controlled_domains::GetRegistryLength( |
| 1423 canonical_name, | 1433 canonical_name, |
| 1424 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, | 1434 registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
| 1425 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); | 1435 registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
| 1426 } | 1436 } |
| 1427 | 1437 |
| 1438 bool IsIPAddressReserved(const IPAddressNumber& host_addr, bool ipv4) { |
| 1439 // We shouldn't compare IPv4 to IPv6 (they have different range |
| 1440 // reservations), so we keep separate arrays. |
| 1441 // Within each array, adjacent ranges are consolidated when possible. |
| 1442 // Sources for info: |
| 1443 // www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml |
| 1444 // www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml |
| 1445 // They're formatted here with the prefix as the last element. For example: |
| 1446 // 10.0.0.0/8 becomes 10,0,0,0,8 and fec0::/10 becomes 0xfe,0xc0,0,0,0...,10. |
| 1447 unsigned char reserved_ipv4[][5] = { |
| 1448 { 0,0,0,0,8 }, { 10,0,0,0,8 }, { 100,64,0,0,10 }, { 127,0,0,0,8 }, |
| 1449 { 169,254,0,0,16 }, { 172,16,0,0,12 }, { 192,0,2,0,24 }, { 192,88,99,0,24 }, |
| 1450 { 192,168,0,0,16 }, { 198,18,0,0,15 }, { 198,51,100,0,24 }, |
| 1451 { 203,0,113,0,24 }, { 224,0,0,0,3 } |
| 1452 }; |
| 1453 unsigned char reserved_ipv6[][17] = { |
| 1454 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 }, |
| 1455 { 0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, |
| 1456 { 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2 }, |
| 1457 { 0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3 }, |
| 1458 { 0xe0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4 }, |
| 1459 { 0xf0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5 }, |
| 1460 { 0xf8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6 }, |
| 1461 { 0xfc,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7 }, |
| 1462 { 0xfe,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9 }, |
| 1463 { 0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, |
| 1464 { 0xfe,0xc0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10 }, |
| 1465 }; |
| 1466 |
| 1467 // Code altered from IPNumberMatchesPrefix; we don't call it directly to avoid |
| 1468 // unnecessary parsing and conversions. |
| 1469 size_t arr_size = (ipv4) ? |
| 1470 arraysize(reserved_ipv4) : arraysize(reserved_ipv6); |
| 1471 for (size_t i = 0; i < arr_size; ++i) { |
| 1472 bool match = true; |
| 1473 int prefix; |
| 1474 if (ipv4) |
| 1475 prefix = reserved_ipv4[i][4]; |
| 1476 else |
| 1477 prefix = reserved_ipv6[i][16]; |
| 1478 // Compare all the bytes that fall entirely within the prefix. |
| 1479 int num_entire_bytes_in_prefix = prefix / 8; |
| 1480 for (int j = 0; j < num_entire_bytes_in_prefix; ++j) { |
| 1481 if (ipv4 && (host_addr[j] != reserved_ipv4[i][j])) { |
| 1482 match = false; |
| 1483 } else if (!ipv4 && (host_addr[j] != reserved_ipv6[i][j])) { |
| 1484 match = false; |
| 1485 } |
| 1486 } |
| 1487 // In case the prefix was not a multiple of 8, there will be 1 byte |
| 1488 // which is only partially masked. |
| 1489 int remaining_bits = prefix % 8; |
| 1490 if (remaining_bits != 0) { |
| 1491 unsigned char mask = 0xFF << (8 - remaining_bits); |
| 1492 int j = num_entire_bytes_in_prefix; |
| 1493 if (ipv4 && ((host_addr[j] & mask) != (reserved_ipv4[i][j] & mask))) { |
| 1494 match = false; |
| 1495 } else if (!ipv4 && |
| 1496 ((host_addr[j] & mask) != (reserved_ipv6[i][j] & mask))) { |
| 1497 match = false; |
| 1498 } |
| 1499 } |
| 1500 if (match) |
| 1501 return true; |
| 1502 } |
| 1503 return false; |
| 1504 } |
| 1505 |
| 1428 // Extracts the address and port portions of a sockaddr. | 1506 // Extracts the address and port portions of a sockaddr. |
| 1429 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, | 1507 bool GetIPAddressFromSockAddr(const struct sockaddr* sock_addr, |
| 1430 socklen_t sock_addr_len, | 1508 socklen_t sock_addr_len, |
| 1431 const uint8** address, | 1509 const uint8** address, |
| 1432 size_t* address_len, | 1510 size_t* address_len, |
| 1433 uint16* port) { | 1511 uint16* port) { |
| 1434 if (sock_addr->sa_family == AF_INET) { | 1512 if (sock_addr->sa_family == AF_INET) { |
| 1435 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) | 1513 if (sock_addr_len < static_cast<socklen_t>(sizeof(struct sockaddr_in))) |
| 1436 return false; | 1514 return false; |
| 1437 const struct sockaddr_in* addr = | 1515 const struct sockaddr_in* addr = |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2081 | 2159 |
| 2082 NetworkInterface::NetworkInterface(const std::string& name, | 2160 NetworkInterface::NetworkInterface(const std::string& name, |
| 2083 const IPAddressNumber& address) | 2161 const IPAddressNumber& address) |
| 2084 : name(name), address(address) { | 2162 : name(name), address(address) { |
| 2085 } | 2163 } |
| 2086 | 2164 |
| 2087 NetworkInterface::~NetworkInterface() { | 2165 NetworkInterface::~NetworkInterface() { |
| 2088 } | 2166 } |
| 2089 | 2167 |
| 2090 } // namespace net | 2168 } // namespace net |
| OLD | NEW |