| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <map> | 8 #include <map> |
| 9 #include <unicode/ucnv.h> | 9 #include <unicode/ucnv.h> |
| 10 #include <unicode/uidna.h> | 10 #include <unicode/uidna.h> |
| 11 #include <unicode/ulocdata.h> | 11 #include <unicode/ulocdata.h> |
| 12 #include <unicode/uniset.h> | 12 #include <unicode/uniset.h> |
| 13 #include <unicode/uscript.h> | 13 #include <unicode/uscript.h> |
| 14 #include <unicode/uset.h> | 14 #include <unicode/uset.h> |
| 15 | 15 |
| 16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 17 | 17 |
| 18 #if defined(OS_WIN) | 18 #if defined(OS_WIN) |
| 19 #include <windows.h> | 19 #include <windows.h> |
| 20 #include <winsock2.h> | 20 #include <winsock2.h> |
| 21 #include <ws2tcpip.h> | 21 #include <ws2tcpip.h> |
| 22 #include <wspiapi.h> // Needed for Win2k compat. | 22 #include <wspiapi.h> // Needed for Win2k compat. |
| 23 #elif defined(OS_POSIX) | 23 #elif defined(OS_POSIX) |
| 24 #include <netdb.h> |
| 25 #include <sys/socket.h> |
| 24 #include <fcntl.h> | 26 #include <fcntl.h> |
| 25 #include <ifaddrs.h> | |
| 26 #include <netdb.h> | |
| 27 #include <net/if.h> | |
| 28 #include <sys/socket.h> | |
| 29 #endif | 27 #endif |
| 30 | 28 |
| 31 #include "base/base64.h" | 29 #include "base/base64.h" |
| 32 #include "base/basictypes.h" | 30 #include "base/basictypes.h" |
| 33 #include "base/file_path.h" | 31 #include "base/file_path.h" |
| 34 #include "base/file_util.h" | 32 #include "base/file_util.h" |
| 35 #include "base/i18n/file_util_icu.h" | 33 #include "base/i18n/file_util_icu.h" |
| 36 #include "base/i18n/icu_string_conversions.h" | 34 #include "base/i18n/icu_string_conversions.h" |
| 37 #include "base/i18n/time_formatting.h" | 35 #include "base/i18n/time_formatting.h" |
| 38 #include "base/json/string_escape.h" | 36 #include "base/json/string_escape.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 ucnv_close(converter); | 250 ucnv_close(converter); |
| 253 if (U_FAILURE(err)) { | 251 if (U_FAILURE(err)) { |
| 254 return false; | 252 return false; |
| 255 } | 253 } |
| 256 output->resize(length); | 254 output->resize(length); |
| 257 return true; | 255 return true; |
| 258 } | 256 } |
| 259 | 257 |
| 260 bool DecodeWord(const std::string& encoded_word, | 258 bool DecodeWord(const std::string& encoded_word, |
| 261 const std::string& referrer_charset, | 259 const std::string& referrer_charset, |
| 262 bool* is_rfc2047, | 260 bool *is_rfc2047, |
| 263 std::string* output) { | 261 std::string* output) { |
| 264 if (!IsStringASCII(encoded_word)) { | 262 if (!IsStringASCII(encoded_word)) { |
| 265 // Try UTF-8, referrer_charset and the native OS default charset in turn. | 263 // Try UTF-8, referrer_charset and the native OS default charset in turn. |
| 266 if (IsStringUTF8(encoded_word)) { | 264 if (IsStringUTF8(encoded_word)) { |
| 267 *output = encoded_word; | 265 *output = encoded_word; |
| 268 } else { | 266 } else { |
| 269 std::wstring wide_output; | 267 std::wstring wide_output; |
| 270 if (!referrer_charset.empty() && | 268 if (!referrer_charset.empty() && |
| 271 base::CodepageToWide(encoded_word, referrer_charset.c_str(), | 269 base::CodepageToWide(encoded_word, referrer_charset.c_str(), |
| 272 base::OnStringConversionError::FAIL, | 270 base::OnStringConversionError::FAIL, |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1536 allowed_ports.substr(last, length)))); | 1534 allowed_ports.substr(last, length)))); |
| 1537 last = i + 1; | 1535 last = i + 1; |
| 1538 } | 1536 } |
| 1539 } | 1537 } |
| 1540 explicitly_allowed_ports = ports; | 1538 explicitly_allowed_ports = ports; |
| 1541 } | 1539 } |
| 1542 | 1540 |
| 1543 enum IPv6SupportStatus { | 1541 enum IPv6SupportStatus { |
| 1544 IPV6_CANNOT_CREATE_SOCKETS, | 1542 IPV6_CANNOT_CREATE_SOCKETS, |
| 1545 IPV6_CAN_CREATE_SOCKETS, | 1543 IPV6_CAN_CREATE_SOCKETS, |
| 1546 IPV6_GETIFADDRS_FAILED, | |
| 1547 IPV6_GLOBAL_ADDRESS_MISSING, | |
| 1548 IPV6_GLOBAL_ADDRESS_PRESENT, | |
| 1549 IPV6_SUPPORT_MAX // Bounding values for enumeration. | 1544 IPV6_SUPPORT_MAX // Bounding values for enumeration. |
| 1550 }; | 1545 }; |
| 1551 | 1546 |
| 1552 static void IPv6SupportResults(IPv6SupportStatus result) { | 1547 static void IPv6SupportResults(IPv6SupportStatus result) { |
| 1553 static bool run_once = false; | 1548 static bool run_once = false; |
| 1554 if (run_once) { | 1549 if (run_once) |
| 1555 run_once = true; | 1550 return; |
| 1556 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); | 1551 run_once = true; |
| 1557 } else { | 1552 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); |
| 1558 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest", result, | |
| 1559 IPV6_SUPPORT_MAX); | |
| 1560 } | |
| 1561 } | 1553 } |
| 1562 | 1554 |
| 1563 // TODO(jar): The following is a simple estimate of IPv6 support. We may need | 1555 // TODO(jar): The following is a simple estimate of IPv6 support. We may need |
| 1564 // to do a test resolution, and a test connection, to REALLY verify support. | 1556 // to do a test resolution, and a test connection, to REALLY verify support. |
| 1565 // static | 1557 // static |
| 1566 bool IPv6Supported() { | 1558 bool IPv6Supported() { |
| 1567 #if defined(OS_POSIX) | 1559 #if defined(OS_POSIX) |
| 1568 int test_socket = socket(AF_INET6, SOCK_STREAM, 0); | 1560 int test_socket; |
| 1561 |
| 1562 test_socket = socket(AF_INET6, SOCK_STREAM, 0); |
| 1569 if (test_socket == -1) { | 1563 if (test_socket == -1) { |
| 1570 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); | 1564 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); |
| 1571 return false; | 1565 return false; |
| 1572 } | 1566 } |
| 1567 |
| 1573 close(test_socket); | 1568 close(test_socket); |
| 1574 | 1569 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); |
| 1575 // Check to see if any interface has a IPv6 address. | |
| 1576 struct ifaddrs* interface_addr = NULL; | |
| 1577 int rv = getifaddrs(&interface_addr); | |
| 1578 if (rv != 0) { | |
| 1579 IPv6SupportResults(IPV6_GETIFADDRS_FAILED); | |
| 1580 return true; // Don't yet block IPv6. | |
| 1581 } | |
| 1582 | |
| 1583 bool found_ipv6 = false; | |
| 1584 for (struct ifaddrs* interface = interface_addr; | |
| 1585 interface != NULL; | |
| 1586 interface = interface->ifa_next) { | |
| 1587 if (!(IFF_UP & interface->ifa_flags)) | |
| 1588 continue; | |
| 1589 if (IFF_LOOPBACK & interface->ifa_flags) | |
| 1590 continue; | |
| 1591 struct sockaddr* addr = interface->ifa_addr; | |
| 1592 if (!addr) | |
| 1593 continue; | |
| 1594 if (addr->sa_family != AF_INET6) | |
| 1595 continue; | |
| 1596 // Safe cast since this is AF_INET6. | |
| 1597 struct sockaddr_in6* addr_in6 = | |
| 1598 reinterpret_cast<struct sockaddr_in6*>(addr); | |
| 1599 struct in6_addr* sin6_addr = &addr_in6->sin6_addr; | |
| 1600 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) | |
| 1601 continue; | |
| 1602 found_ipv6 = true; | |
| 1603 break; | |
| 1604 } | |
| 1605 freeifaddrs(interface_addr); | |
| 1606 if (!found_ipv6) { | |
| 1607 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_MISSING); | |
| 1608 return false; | |
| 1609 } | |
| 1610 | |
| 1611 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); | |
| 1612 return true; | 1570 return true; |
| 1613 #elif defined(OS_WIN) | 1571 #elif defined(OS_WIN) |
| 1614 EnsureWinsockInit(); | 1572 EnsureWinsockInit(); |
| 1615 SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0); | 1573 SOCKET test_socket; |
| 1574 |
| 1575 test_socket = socket(AF_INET6, SOCK_STREAM, 0); |
| 1616 if (test_socket == INVALID_SOCKET) { | 1576 if (test_socket == INVALID_SOCKET) { |
| 1617 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); | 1577 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); |
| 1618 return false; | 1578 return false; |
| 1619 } | 1579 } |
| 1580 |
| 1620 closesocket(test_socket); | 1581 closesocket(test_socket); |
| 1621 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); | 1582 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); |
| 1622 return true; | 1583 return true; |
| 1623 #else | 1584 #else |
| 1624 NOTIMPLEMENTED(); | 1585 NOTIMPLEMENTED(); |
| 1625 return true; | 1586 return true; |
| 1626 #endif // defined(various platforms) | 1587 #endif // defined(various platforms) |
| 1627 } | 1588 } |
| 1628 | 1589 |
| 1590 |
| 1629 } // namespace net | 1591 } // namespace net |
| OLD | NEW |