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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 ucnv_close(converter); | 252 ucnv_close(converter); |
251 if (U_FAILURE(err)) { | 253 if (U_FAILURE(err)) { |
252 return false; | 254 return false; |
253 } | 255 } |
254 output->resize(length); | 256 output->resize(length); |
255 return true; | 257 return true; |
256 } | 258 } |
257 | 259 |
258 bool DecodeWord(const std::string& encoded_word, | 260 bool DecodeWord(const std::string& encoded_word, |
259 const std::string& referrer_charset, | 261 const std::string& referrer_charset, |
260 bool *is_rfc2047, | 262 bool* is_rfc2047, |
261 std::string* output) { | 263 std::string* output) { |
262 if (!IsStringASCII(encoded_word)) { | 264 if (!IsStringASCII(encoded_word)) { |
263 // Try UTF-8, referrer_charset and the native OS default charset in turn. | 265 // Try UTF-8, referrer_charset and the native OS default charset in turn. |
264 if (IsStringUTF8(encoded_word)) { | 266 if (IsStringUTF8(encoded_word)) { |
265 *output = encoded_word; | 267 *output = encoded_word; |
266 } else { | 268 } else { |
267 std::wstring wide_output; | 269 std::wstring wide_output; |
268 if (!referrer_charset.empty() && | 270 if (!referrer_charset.empty() && |
269 base::CodepageToWide(encoded_word, referrer_charset.c_str(), | 271 base::CodepageToWide(encoded_word, referrer_charset.c_str(), |
270 base::OnStringConversionError::FAIL, | 272 base::OnStringConversionError::FAIL, |
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 allowed_ports.substr(last, length)))); | 1536 allowed_ports.substr(last, length)))); |
1535 last = i + 1; | 1537 last = i + 1; |
1536 } | 1538 } |
1537 } | 1539 } |
1538 explicitly_allowed_ports = ports; | 1540 explicitly_allowed_ports = ports; |
1539 } | 1541 } |
1540 | 1542 |
1541 enum IPv6SupportStatus { | 1543 enum IPv6SupportStatus { |
1542 IPV6_CANNOT_CREATE_SOCKETS, | 1544 IPV6_CANNOT_CREATE_SOCKETS, |
1543 IPV6_CAN_CREATE_SOCKETS, | 1545 IPV6_CAN_CREATE_SOCKETS, |
| 1546 IPV6_GETIFADDRS_FAILED, |
| 1547 IPV6_GLOBAL_ADDRESS_MISSING, |
| 1548 IPV6_GLOBAL_ADDRESS_PRESENT, |
1544 IPV6_SUPPORT_MAX // Bounding values for enumeration. | 1549 IPV6_SUPPORT_MAX // Bounding values for enumeration. |
1545 }; | 1550 }; |
1546 | 1551 |
1547 static void IPv6SupportResults(IPv6SupportStatus result) { | 1552 static void IPv6SupportResults(IPv6SupportStatus result) { |
1548 static bool run_once = false; | 1553 static bool run_once = false; |
1549 if (run_once) | 1554 if (run_once) { |
1550 return; | 1555 run_once = true; |
1551 run_once = true; | 1556 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); |
1552 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); | 1557 } else { |
| 1558 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest", result, |
| 1559 IPV6_SUPPORT_MAX); |
| 1560 } |
1553 } | 1561 } |
1554 | 1562 |
1555 // TODO(jar): The following is a simple estimate of IPv6 support. We may need | 1563 // TODO(jar): The following is a simple estimate of IPv6 support. We may need |
1556 // to do a test resolution, and a test connection, to REALLY verify support. | 1564 // to do a test resolution, and a test connection, to REALLY verify support. |
1557 // static | 1565 // static |
1558 bool IPv6Supported() { | 1566 bool IPv6Supported() { |
1559 #if defined(OS_POSIX) | 1567 #if defined(OS_POSIX) |
1560 int test_socket; | 1568 int test_socket = socket(AF_INET6, SOCK_STREAM, 0); |
1561 | |
1562 test_socket = socket(AF_INET6, SOCK_STREAM, 0); | |
1563 if (test_socket == -1) { | 1569 if (test_socket == -1) { |
1564 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); | 1570 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); |
1565 return false; | 1571 return false; |
1566 } | 1572 } |
| 1573 close(test_socket); |
1567 | 1574 |
1568 close(test_socket); | 1575 // Check to see if any interface has a IPv6 address. |
1569 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); | 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); |
1570 return true; | 1612 return true; |
1571 #elif defined(OS_WIN) | 1613 #elif defined(OS_WIN) |
1572 EnsureWinsockInit(); | 1614 EnsureWinsockInit(); |
1573 SOCKET test_socket; | 1615 SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0); |
1574 | |
1575 test_socket = socket(AF_INET6, SOCK_STREAM, 0); | |
1576 if (test_socket == INVALID_SOCKET) { | 1616 if (test_socket == INVALID_SOCKET) { |
1577 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); | 1617 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); |
1578 return false; | 1618 return false; |
1579 } | 1619 } |
1580 | |
1581 closesocket(test_socket); | 1620 closesocket(test_socket); |
1582 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); | 1621 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); |
1583 return true; | 1622 return true; |
1584 #else | 1623 #else |
1585 NOTIMPLEMENTED(); | 1624 NOTIMPLEMENTED(); |
1586 return true; | 1625 return true; |
1587 #endif // defined(various platforms) | 1626 #endif // defined(various platforms) |
1588 } | 1627 } |
1589 | 1628 |
1590 | |
1591 } // namespace net | 1629 } // namespace net |
OLD | NEW |