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> |
(...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 ports.insert(StringToInt(WideToASCII( | 1548 ports.insert(StringToInt(WideToASCII( |
1549 allowed_ports.substr(last, length)))); | 1549 allowed_ports.substr(last, length)))); |
1550 last = i + 1; | 1550 last = i + 1; |
1551 } | 1551 } |
1552 } | 1552 } |
1553 explicitly_allowed_ports = ports; | 1553 explicitly_allowed_ports = ports; |
1554 } | 1554 } |
1555 | 1555 |
1556 enum IPv6SupportStatus { | 1556 enum IPv6SupportStatus { |
1557 IPV6_CANNOT_CREATE_SOCKETS, | 1557 IPV6_CANNOT_CREATE_SOCKETS, |
1558 IPV6_CAN_CREATE_SOCKETS, | 1558 IPV6_CAN_CREATE_SOCKETS, // Deprecated: No longer used. |
1559 IPV6_GETIFADDRS_FAILED, | 1559 IPV6_GETIFADDRS_FAILED, |
1560 IPV6_GLOBAL_ADDRESS_MISSING, | 1560 IPV6_GLOBAL_ADDRESS_MISSING, |
1561 IPV6_GLOBAL_ADDRESS_PRESENT, | 1561 IPV6_GLOBAL_ADDRESS_PRESENT, |
| 1562 IPV6_INTERFACE_ARRAY_TOO_SHORT, |
1562 IPV6_SUPPORT_MAX // Bounding values for enumeration. | 1563 IPV6_SUPPORT_MAX // Bounding values for enumeration. |
1563 }; | 1564 }; |
1564 | 1565 |
1565 static void IPv6SupportResults(IPv6SupportStatus result) { | 1566 static void IPv6SupportResults(IPv6SupportStatus result) { |
1566 static bool run_once = false; | 1567 static bool run_once = false; |
1567 if (!run_once) { | 1568 if (!run_once) { |
1568 run_once = true; | 1569 run_once = true; |
1569 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); | 1570 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); |
1570 } else { | 1571 } else { |
1571 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest", result, | 1572 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest", result, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); | 1625 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); |
1625 return true; | 1626 return true; |
1626 #elif defined(OS_WIN) | 1627 #elif defined(OS_WIN) |
1627 EnsureWinsockInit(); | 1628 EnsureWinsockInit(); |
1628 SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0); | 1629 SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0); |
1629 if (test_socket == INVALID_SOCKET) { | 1630 if (test_socket == INVALID_SOCKET) { |
1630 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); | 1631 IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); |
1631 return false; | 1632 return false; |
1632 } | 1633 } |
1633 closesocket(test_socket); | 1634 closesocket(test_socket); |
1634 IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); | 1635 |
1635 return true; | 1636 // Check to see if any interface has a IPv6 address. |
| 1637 // Note: The original IPv6 socket can't be used here, as WSAIoctl() will fail. |
| 1638 test_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, 0); |
| 1639 DCHECK(test_socket != INVALID_SOCKET); |
| 1640 INTERFACE_INFO interfaces[128]; |
| 1641 DWORD bytes_written = 0; |
| 1642 int rv = WSAIoctl(test_socket, SIO_GET_INTERFACE_LIST, NULL, 0, interfaces, |
| 1643 sizeof(interfaces), &bytes_written, NULL, NULL); |
| 1644 closesocket(test_socket); |
| 1645 |
| 1646 if (0 != rv) { |
| 1647 if (WSAGetLastError() == WSAEFAULT) |
| 1648 IPv6SupportResults(IPV6_INTERFACE_ARRAY_TOO_SHORT); |
| 1649 else |
| 1650 IPv6SupportResults(IPV6_GETIFADDRS_FAILED); |
| 1651 return true; // Don't yet block IPv6. |
| 1652 } |
| 1653 size_t interface_count = bytes_written / sizeof(interfaces[0]); |
| 1654 for (size_t i = 0; i < interface_count; ++i) { |
| 1655 INTERFACE_INFO* interface = &interfaces[i]; |
| 1656 if (!(IFF_UP & interface->iiFlags)) |
| 1657 continue; |
| 1658 if (IFF_LOOPBACK & interface->iiFlags) |
| 1659 continue; |
| 1660 sockaddr* addr = &interface->iiAddress.Address; |
| 1661 if (addr->sa_family != AF_INET6) |
| 1662 continue; |
| 1663 struct in6_addr* sin6_addr = &interface->iiAddress.AddressIn6.sin6_addr; |
| 1664 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) |
| 1665 continue; |
| 1666 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); |
| 1667 return true; |
| 1668 } |
| 1669 |
| 1670 IPv6SupportResults(IPV6_GLOBAL_ADDRESS_MISSING); |
| 1671 return false; |
1636 #else | 1672 #else |
1637 NOTIMPLEMENTED(); | 1673 NOTIMPLEMENTED(); |
1638 return true; | 1674 return true; |
1639 #endif // defined(various platforms) | 1675 #endif // defined(various platforms) |
1640 } | 1676 } |
1641 | 1677 |
1642 } // namespace net | 1678 } // namespace net |
OLD | NEW |