diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 05:33:45 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 05:33:45 +0000 |
commit | 7be4c7eef651408e7e0cd30edf5b48e2ee93f226 (patch) | |
tree | b3d6849e0df9a999c5a9d6425dd4004bd474d508 /net/base/net_util.cc | |
parent | 196e32aed9931577e45f76d482f5db8372a51a31 (diff) | |
download | chromium_src-7be4c7eef651408e7e0cd30edf5b48e2ee93f226.zip chromium_src-7be4c7eef651408e7e0cd30edf5b48e2ee93f226.tar.gz chromium_src-7be4c7eef651408e7e0cd30edf5b48e2ee93f226.tar.bz2 |
Revert 39998 - Revert 39996 Refine IPv6 probe to require that the client has an IPv6 address on an interface
This is a second attempt to land a reviewed change. It was reverted because
the tree got very red (for other reasons), and it was plausible that this
change was causing startup latency in Mac and Linux (causing both perf bots
to go red). If this landing turns those perf-bots red (tonight) I'll need
to revert. (... and I'll need to rearchitect to do the probes
asynchronously, and get off the startup-critical-path.
This currently only works on Posix, not windows.
Network changes are monitored, and the test is repeated each time interfaces
change (which is a subset of any IP addresses changing).
The test performed is still relatively low latency, and we *may* need
to eventually move to an high latency test, such as a DNS resolution,
or an actual test connection. If we move in that direction, then we'll
need to post a task to perform the work, rather than immediately returning.
BUG=25680
BUG=12754
r=wtc,eroman
Review URL: http://codereview.chromium.org/652072
TBR=jar@chromium.org
Review URL: http://codereview.chromium.org/660073
TBR=jar@chromium.org
Review URL: http://codereview.chromium.org/661164
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40099 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/net_util.cc')
-rw-r--r-- | net/base/net_util.cc | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc index a2eb04d..dea8c40 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -21,9 +21,11 @@ #include <ws2tcpip.h> #include <wspiapi.h> // Needed for Win2k compat. #elif defined(OS_POSIX) +#include <fcntl.h> +#include <ifaddrs.h> #include <netdb.h> +#include <net/if.h> #include <sys/socket.h> -#include <fcntl.h> #endif #include "base/base64.h" @@ -257,7 +259,7 @@ bool DecodeBQEncoding(const std::string& part, RFC2047EncodingType enc_type, bool DecodeWord(const std::string& encoded_word, const std::string& referrer_charset, - bool *is_rfc2047, + bool* is_rfc2047, std::string* output) { if (!IsStringASCII(encoded_word)) { // Try UTF-8, referrer_charset and the native OS default charset in turn. @@ -1541,15 +1543,21 @@ void SetExplicitlyAllowedPorts(const std::wstring& allowed_ports) { enum IPv6SupportStatus { IPV6_CANNOT_CREATE_SOCKETS, IPV6_CAN_CREATE_SOCKETS, + IPV6_GETIFADDRS_FAILED, + IPV6_GLOBAL_ADDRESS_MISSING, + IPV6_GLOBAL_ADDRESS_PRESENT, IPV6_SUPPORT_MAX // Bounding values for enumeration. }; static void IPv6SupportResults(IPv6SupportStatus result) { static bool run_once = false; - if (run_once) - return; - run_once = true; - UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); + if (run_once) { + run_once = true; + UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status", result, IPV6_SUPPORT_MAX); + } else { + UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest", result, + IPV6_SUPPORT_MAX); + } } // TODO(jar): The following is a simple estimate of IPv6 support. We may need @@ -1557,27 +1565,58 @@ static void IPv6SupportResults(IPv6SupportStatus result) { // static bool IPv6Supported() { #if defined(OS_POSIX) - int test_socket; - - test_socket = socket(AF_INET6, SOCK_STREAM, 0); + int test_socket = socket(AF_INET6, SOCK_STREAM, 0); if (test_socket == -1) { IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); return false; } - close(test_socket); - IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); + + // Check to see if any interface has a IPv6 address. + struct ifaddrs* interface_addr = NULL; + int rv = getifaddrs(&interface_addr); + if (rv != 0) { + IPv6SupportResults(IPV6_GETIFADDRS_FAILED); + return true; // Don't yet block IPv6. + } + + bool found_ipv6 = false; + for (struct ifaddrs* interface = interface_addr; + interface != NULL; + interface = interface->ifa_next) { + if (!(IFF_UP & interface->ifa_flags)) + continue; + if (IFF_LOOPBACK & interface->ifa_flags) + continue; + struct sockaddr* addr = interface->ifa_addr; + if (!addr) + continue; + if (addr->sa_family != AF_INET6) + continue; + // Safe cast since this is AF_INET6. + struct sockaddr_in6* addr_in6 = + reinterpret_cast<struct sockaddr_in6*>(addr); + struct in6_addr* sin6_addr = &addr_in6->sin6_addr; + if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) + continue; + found_ipv6 = true; + break; + } + freeifaddrs(interface_addr); + if (!found_ipv6) { + IPv6SupportResults(IPV6_GLOBAL_ADDRESS_MISSING); + return false; + } + + IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); return true; #elif defined(OS_WIN) EnsureWinsockInit(); - SOCKET test_socket; - - test_socket = socket(AF_INET6, SOCK_STREAM, 0); + SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0); if (test_socket == INVALID_SOCKET) { IPv6SupportResults(IPV6_CANNOT_CREATE_SOCKETS); return false; } - closesocket(test_socket); IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); return true; @@ -1587,5 +1626,4 @@ bool IPv6Supported() { #endif // defined(various platforms) } - } // namespace net |