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