Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: net/base/net_util.cc

Issue 19286002: Remove interface probing for IPv6 support from HostResolverImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Make --enable-ipv6 disable probing. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/net_util.h ('k') | net/dns/host_resolver.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <iterator> 8 #include <iterator>
9 #include <map> 9 #include <map>
10 10
(...skipping 1777 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 1788
1789 ScopedPortException::~ScopedPortException() { 1789 ScopedPortException::~ScopedPortException() {
1790 std::multiset<int>::iterator it = 1790 std::multiset<int>::iterator it =
1791 g_explicitly_allowed_ports.Get().find(port_); 1791 g_explicitly_allowed_ports.Get().find(port_);
1792 if (it != g_explicitly_allowed_ports.Get().end()) 1792 if (it != g_explicitly_allowed_ports.Get().end())
1793 g_explicitly_allowed_ports.Get().erase(it); 1793 g_explicitly_allowed_ports.Get().erase(it);
1794 else 1794 else
1795 NOTREACHED(); 1795 NOTREACHED();
1796 } 1796 }
1797 1797
1798 namespace {
1799
1800 const char* kFinalStatusNames[] = {
1801 "Cannot create sockets",
1802 "Can create sockets",
1803 "Can't get addresses",
1804 "Global ipv6 address missing",
1805 "Global ipv6 address present",
1806 "Interface array too short",
1807 "Probing not supported", // IPV6_SUPPORT_MAX
1808 };
1809 COMPILE_ASSERT(arraysize(kFinalStatusNames) == IPV6_SUPPORT_MAX + 1,
1810 IPv6SupportStatus_name_count_mismatch);
1811
1812 // TODO(jar): The following is a simple estimate of IPv6 support. We may need
1813 // to do a test resolution, and a test connection, to REALLY verify support.
1814 IPv6SupportResult TestIPv6SupportInternal() {
1815 #if defined(OS_ANDROID)
1816 // TODO: We should fully implement IPv6 probe once 'getifaddrs' API available;
1817 // Another approach is implementing the similar feature by
1818 // java.net.NetworkInterface through JNI.
1819 NOTIMPLEMENTED();
1820 return IPv6SupportResult(true, IPV6_SUPPORT_MAX, 0);
1821 #elif defined(OS_POSIX)
1822 int test_socket = socket(AF_INET6, SOCK_STREAM, 0);
1823 if (test_socket == -1)
1824 return IPv6SupportResult(false, IPV6_CANNOT_CREATE_SOCKETS, errno);
1825 close(test_socket);
1826
1827 // Check to see if any interface has a IPv6 address.
1828 struct ifaddrs* interface_addr = NULL;
1829 int rv = getifaddrs(&interface_addr);
1830 if (rv != 0) {
1831 // Don't yet block IPv6.
1832 return IPv6SupportResult(true, IPV6_GETIFADDRS_FAILED, errno);
1833 }
1834
1835 bool found_ipv6 = false;
1836 for (struct ifaddrs* interface = interface_addr;
1837 interface != NULL;
1838 interface = interface->ifa_next) {
1839 if (!(IFF_UP & interface->ifa_flags))
1840 continue;
1841 if (IFF_LOOPBACK & interface->ifa_flags)
1842 continue;
1843 struct sockaddr* addr = interface->ifa_addr;
1844 if (!addr)
1845 continue;
1846 if (addr->sa_family != AF_INET6)
1847 continue;
1848 // Safe cast since this is AF_INET6.
1849 struct sockaddr_in6* addr_in6 =
1850 reinterpret_cast<struct sockaddr_in6*>(addr);
1851 struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
1852 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr))
1853 continue;
1854 found_ipv6 = true;
1855 break;
1856 }
1857 freeifaddrs(interface_addr);
1858 if (!found_ipv6)
1859 return IPv6SupportResult(false, IPV6_GLOBAL_ADDRESS_MISSING, 0);
1860
1861 return IPv6SupportResult(true, IPV6_GLOBAL_ADDRESS_PRESENT, 0);
1862 #elif defined(OS_WIN)
1863 EnsureWinsockInit();
1864 SOCKET test_socket = socket(AF_INET6, SOCK_STREAM, 0);
1865 if (test_socket == INVALID_SOCKET) {
1866 return IPv6SupportResult(false,
1867 IPV6_CANNOT_CREATE_SOCKETS,
1868 WSAGetLastError());
1869 }
1870 closesocket(test_socket);
1871
1872 // Check to see if any interface has a IPv6 address.
1873 // The GetAdaptersAddresses MSDN page recommends using a size of 15000 to
1874 // avoid reallocation.
1875 ULONG adapters_size = 15000;
1876 scoped_ptr_malloc<IP_ADAPTER_ADDRESSES> adapters;
1877 ULONG error;
1878 int num_tries = 0;
1879 do {
1880 adapters.reset(
1881 reinterpret_cast<PIP_ADAPTER_ADDRESSES>(malloc(adapters_size)));
1882 // Return only unicast addresses.
1883 error = GetAdaptersAddresses(AF_UNSPEC,
1884 GAA_FLAG_SKIP_ANYCAST |
1885 GAA_FLAG_SKIP_MULTICAST |
1886 GAA_FLAG_SKIP_DNS_SERVER |
1887 GAA_FLAG_SKIP_FRIENDLY_NAME,
1888 NULL, adapters.get(), &adapters_size);
1889 num_tries++;
1890 } while (error == ERROR_BUFFER_OVERFLOW && num_tries <= 3);
1891 if (error == ERROR_NO_DATA)
1892 return IPv6SupportResult(false, IPV6_GLOBAL_ADDRESS_MISSING, error);
1893 if (error != ERROR_SUCCESS) {
1894 // Don't yet block IPv6.
1895 return IPv6SupportResult(true, IPV6_GETIFADDRS_FAILED, error);
1896 }
1897
1898 PIP_ADAPTER_ADDRESSES adapter;
1899 for (adapter = adapters.get(); adapter; adapter = adapter->Next) {
1900 if (adapter->OperStatus != IfOperStatusUp)
1901 continue;
1902 if (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
1903 continue;
1904 PIP_ADAPTER_UNICAST_ADDRESS unicast_address;
1905 for (unicast_address = adapter->FirstUnicastAddress;
1906 unicast_address;
1907 unicast_address = unicast_address->Next) {
1908 if (unicast_address->Address.lpSockaddr->sa_family != AF_INET6)
1909 continue;
1910 // Safe cast since this is AF_INET6.
1911 struct sockaddr_in6* addr_in6 = reinterpret_cast<struct sockaddr_in6*>(
1912 unicast_address->Address.lpSockaddr);
1913 struct in6_addr* sin6_addr = &addr_in6->sin6_addr;
1914 if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || IN6_IS_ADDR_LINKLOCAL(sin6_addr))
1915 continue;
1916 const uint8 kTeredoPrefix[] = { 0x20, 0x01, 0, 0 };
1917 if (!memcmp(sin6_addr->s6_addr, kTeredoPrefix, arraysize(kTeredoPrefix)))
1918 continue;
1919 return IPv6SupportResult(true, IPV6_GLOBAL_ADDRESS_PRESENT, 0);
1920 }
1921 }
1922
1923 return IPv6SupportResult(false, IPV6_GLOBAL_ADDRESS_MISSING, 0);
1924 #else
1925 NOTIMPLEMENTED();
1926 return IPv6SupportResult(true, IPV6_SUPPORT_MAX, 0);
1927 #endif // defined(various platforms)
1928 }
1929
1930 } // namespace
1931
1932 IPv6SupportResult::IPv6SupportResult(bool ipv6_supported,
1933 IPv6SupportStatus ipv6_support_status,
1934 int os_error)
1935 : ipv6_supported(ipv6_supported),
1936 ipv6_support_status(ipv6_support_status),
1937 os_error(os_error) {
1938 }
1939
1940 base::Value* IPv6SupportResult::ToNetLogValue(
1941 NetLog::LogLevel /* log_level */) const {
1942 base::DictionaryValue* dict = new base::DictionaryValue();
1943 dict->SetBoolean("ipv6_supported", ipv6_supported);
1944 dict->SetString("ipv6_support_status",
1945 kFinalStatusNames[ipv6_support_status]);
1946 if (os_error)
1947 dict->SetInteger("os_error", os_error);
1948 return dict;
1949 }
1950
1951 IPv6SupportResult TestIPv6Support() {
1952 IPv6SupportResult result = TestIPv6SupportInternal();
1953
1954 // Record UMA.
1955 if (result.ipv6_support_status != IPV6_SUPPORT_MAX) {
1956 static bool run_once = false;
1957 if (!run_once) {
1958 run_once = true;
1959 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status",
1960 result.ipv6_support_status,
1961 IPV6_SUPPORT_MAX);
1962 } else {
1963 UMA_HISTOGRAM_ENUMERATION("Net.IPv6Status_retest",
1964 result.ipv6_support_status,
1965 IPV6_SUPPORT_MAX);
1966 }
1967 }
1968 return result;
1969 }
1970
1971 bool HaveOnlyLoopbackAddresses() { 1798 bool HaveOnlyLoopbackAddresses() {
1972 #if defined(OS_ANDROID) 1799 #if defined(OS_ANDROID)
1973 return android::HaveOnlyLoopbackAddresses(); 1800 return android::HaveOnlyLoopbackAddresses();
1974 #elif defined(OS_POSIX) 1801 #elif defined(OS_POSIX)
1975 struct ifaddrs* interface_addr = NULL; 1802 struct ifaddrs* interface_addr = NULL;
1976 int rv = getifaddrs(&interface_addr); 1803 int rv = getifaddrs(&interface_addr);
1977 if (rv != 0) { 1804 if (rv != 0) {
1978 DVLOG(1) << "getifaddrs() failed with errno = " << errno; 1805 DVLOG(1) << "getifaddrs() failed with errno = " << errno;
1979 return false; 1806 return false;
1980 } 1807 }
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
2224 2051
2225 NetworkInterface::NetworkInterface(const std::string& name, 2052 NetworkInterface::NetworkInterface(const std::string& name,
2226 const IPAddressNumber& address) 2053 const IPAddressNumber& address)
2227 : name(name), address(address) { 2054 : name(name), address(address) {
2228 } 2055 }
2229 2056
2230 NetworkInterface::~NetworkInterface() { 2057 NetworkInterface::~NetworkInterface() {
2231 } 2058 }
2232 2059
2233 } // namespace net 2060 } // namespace net
OLDNEW
« no previous file with comments | « net/base/net_util.h ('k') | net/dns/host_resolver.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698