diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 21:58:31 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-24 21:58:31 +0000 |
commit | 26b0f376d66975c03c3d24afd72257f34c9bb5f6 (patch) | |
tree | 9d6fea5b7c12347ffe5fa1f00778b14779ad52a4 /net | |
parent | 3c6f8e155866a42aed692b88231f4c6a62fae8c7 (diff) | |
download | chromium_src-26b0f376d66975c03c3d24afd72257f34c9bb5f6.zip chromium_src-26b0f376d66975c03c3d24afd72257f34c9bb5f6.tar.gz chromium_src-26b0f376d66975c03c3d24afd72257f34c9bb5f6.tar.bz2 |
Add IPv6 probe support for Windows
This is meant to test to see if AI_ADDRCONFIG is doing its
job in windows, or if we have to do the scans when there is
a network change.
Also switch to always doing probe support on Mac/Linux platforms.
There appears to be (on aggregate) around a 40% degradation of
DNS resolution times on the Mac, and about 17% degration on
Linux, when we don't probe. It is likely that a few users
are greatly impacted by this, and are able to move the average
of the whole user population.
BUG=12754
BUG=25680
r=wtc
Review URL: http://codereview.chromium.org/1210003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42544 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/base/net_util.cc | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc index 67726f4e..ff19d3e 100644 --- a/net/base/net_util.cc +++ b/net/base/net_util.cc @@ -1555,10 +1555,11 @@ void SetExplicitlyAllowedPorts(const std::wstring& allowed_ports) { enum IPv6SupportStatus { IPV6_CANNOT_CREATE_SOCKETS, - IPV6_CAN_CREATE_SOCKETS, + IPV6_CAN_CREATE_SOCKETS, // Deprecated: No longer used. IPV6_GETIFADDRS_FAILED, IPV6_GLOBAL_ADDRESS_MISSING, IPV6_GLOBAL_ADDRESS_PRESENT, + IPV6_INTERFACE_ARRAY_TOO_SHORT, IPV6_SUPPORT_MAX // Bounding values for enumeration. }; @@ -1631,8 +1632,43 @@ bool IPv6Supported() { return false; } closesocket(test_socket); - IPv6SupportResults(IPV6_CAN_CREATE_SOCKETS); - return true; + + // Check to see if any interface has a IPv6 address. + // Note: The original IPv6 socket can't be used here, as WSAIoctl() will fail. + test_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, 0); + DCHECK(test_socket != INVALID_SOCKET); + INTERFACE_INFO interfaces[128]; + DWORD bytes_written = 0; + int rv = WSAIoctl(test_socket, SIO_GET_INTERFACE_LIST, NULL, 0, interfaces, + sizeof(interfaces), &bytes_written, NULL, NULL); + closesocket(test_socket); + + if (0 != rv) { + if (WSAGetLastError() == WSAEFAULT) + IPv6SupportResults(IPV6_INTERFACE_ARRAY_TOO_SHORT); + else + IPv6SupportResults(IPV6_GETIFADDRS_FAILED); + return true; // Don't yet block IPv6. + } + size_t interface_count = bytes_written / sizeof(interfaces[0]); + for (size_t i = 0; i < interface_count; ++i) { + INTERFACE_INFO* interface = &interfaces[i]; + if (!(IFF_UP & interface->iiFlags)) + continue; + if (IFF_LOOPBACK & interface->iiFlags) + continue; + sockaddr* addr = &interface->iiAddress.Address; + if (addr->sa_family != AF_INET6) + continue; + struct in6_addr* sin6_addr = &interface->iiAddress.AddressIn6.sin6_addr; + if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr)) + continue; + IPv6SupportResults(IPV6_GLOBAL_ADDRESS_PRESENT); + return true; + } + + IPv6SupportResults(IPV6_GLOBAL_ADDRESS_MISSING); + return false; #else NOTIMPLEMENTED(); return true; |