summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-08 22:15:54 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-08 22:15:54 +0000
commit32eaa332c7ef3f5480b0e5cfc4f42418a13c9189 (patch)
tree2d3155f68162a9523b1b12cbb54c8a35863664a7
parent26788a65a7f9094a0acd44ea69c3cdbea5b1f498 (diff)
downloadchromium_src-32eaa332c7ef3f5480b0e5cfc4f42418a13c9189.zip
chromium_src-32eaa332c7ef3f5480b0e5cfc4f42418a13c9189.tar.gz
chromium_src-32eaa332c7ef3f5480b0e5cfc4f42418a13c9189.tar.bz2
Add IPv6 probing support, and disable IPv6 resolution when it is useless
I've added minimal probing to check if IPv6 is at all possible, and when it is not, then we disable IPv6 resolution. I've also added histograms and A/B test support to evaluate the impact of this change. (I landed originally, but had tree problems, and this is a new CL to tryto reland). Note that I've switched back to MACRO style enums as well, per http://dev.chromium.org/developers/coding-style (search for "enum"). This version now does the conditional testing at a higher level (in io_thread.h), so that it should interfere less with other testing. r=wtc,eroman Review URL: http://codereview.chromium.org/585005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38402 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/io_thread.cc21
-rw-r--r--chrome/browser/net/dns_host_info.cc14
-rw-r--r--chrome/common/chrome_switches.cc7
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--net/base/net_util.cc50
-rw-r--r--net/base/net_util.h5
6 files changed, 95 insertions, 3 deletions
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc
index 39f4cf6..33604f5 100644
--- a/chrome/browser/io_thread.cc
+++ b/chrome/browser/io_thread.cc
@@ -15,6 +15,7 @@
#include "net/base/host_cache.h"
#include "net/base/host_resolver.h"
#include "net/base/host_resolver_impl.h"
+#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_request.h"
@@ -36,8 +37,24 @@ net::HostResolver* CreateGlobalHostResolver(
global_host_resolver =
net::CreateSystemHostResolver(network_change_notifier);
- if (command_line.HasSwitch(switches::kDisableIPv6))
- global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
+ if (!command_line.HasSwitch(switches::kEnableIPv6)) {
+ // Measure impact of allowing IPv6 support without probing.
+ const FieldTrial::Probability kDivisor = 100;
+ const FieldTrial::Probability kProbability = 50; // 50% probability.
+ FieldTrial* trial = new FieldTrial("IPv6_Probe", kDivisor);
+ int skip_group = trial->AppendGroup("_IPv6_probe_skipped", kProbability);
+ trial->AppendGroup("_IPv6_probe_done",
+ FieldTrial::kAllRemainingProbability);
+ bool use_ipv6_probe = (trial->group() != skip_group);
+
+ // Perform probe, and then optionally use result to disable IPv6.
+ // Some users report confused OS handling of IPv6, leading to large
+ // latency. If we can show that IPv6 is not supported, then disabliing it
+ // will work around such problems.
+ if ((!net::IPv6Supported() && use_ipv6_probe) ||
+ command_line.HasSwitch(switches::kDisableIPv6))
+ global_host_resolver->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4);
+ }
}
return global_host_resolver;
diff --git a/chrome/browser/net/dns_host_info.cc b/chrome/browser/net/dns_host_info.cc
index 8946f7f..45e088b 100644
--- a/chrome/browser/net/dns_host_info.cc
+++ b/chrome/browser/net/dns_host_info.cc
@@ -9,6 +9,7 @@
#include <algorithm>
#include <string>
+#include "base/field_trial.h"
#include "base/format_macros.h"
#include "base/histogram.h"
#include "base/logging.h"
@@ -120,7 +121,18 @@ void DnsHostInfo::SetFoundState() {
state_ = FOUND;
resolve_duration_ = GetDuration();
if (kMaxNonNetworkDnsLookupDuration <= resolve_duration_) {
- UMA_HISTOGRAM_LONG_TIMES("DNS.PrefetchFoundNameL", resolve_duration_);
+ UMA_HISTOGRAM_CUSTOM_TIMES("DNS.PrefetchResolution", resolve_duration_,
+ kMaxNonNetworkDnsLookupDuration, TimeDelta::FromMinutes(15), 100);
+
+ static bool use_ipv6_histogram(FieldTrialList::Find("IPv6_Probe") &&
+ !FieldTrialList::Find("IPv6_Probe")->group_name().empty());
+ if (use_ipv6_histogram) {
+ UMA_HISTOGRAM_CUSTOM_TIMES(
+ FieldTrial::MakeName("DNS.PrefetchResolution", "IPv6_Probe"),
+ resolve_duration_, kMaxNonNetworkDnsLookupDuration,
+ TimeDelta::FromMinutes(15), 100);
+ }
+
// Record potential beneficial time, and maybe we'll get a cache hit.
// We keep the maximum, as the warming we did earlier may still be
// helping with a cache upstream in DNS resolution.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 5d76c4d..d3fdbcb 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -104,6 +104,7 @@ const char kDisableHangMonitor[] = "disable-hang-monitor";
// Don't resolve hostnames to IPv6 addresses. This can be used when debugging
// issues relating to IPv6, but shouldn't otherwise be needed. Be sure to
// file bugs if something isn't working properly in the presence of IPv6.
+// This flag can be overidden by the "enable-ipv6" flag.
const char kDisableIPv6[] = "disable-ipv6";
// Prevent images from loading.
@@ -221,6 +222,12 @@ const char kEnableGeolocation[] = "enable-geolocation";
// Enable the Indexed Database API.
const char kEnableIndexedDatabase[] = "enable-indexed-database";
+// Enable IPv6 support, even if probes suggest that it may not be fully
+// supported. Some probes may require internet connections, and this flag will
+// allow support independent of application testing.
+// This flag overrides "disable-ipv6" which appears elswhere in this file.
+const char kEnableIPv6[] = "enable-ipv6";
+
// Enable the GPU plugin and Pepper 3D rendering.
const char kEnableGPUPlugin[] = "enable-gpu-plugin";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index f7c86aa..e6be99f 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -80,6 +80,7 @@ extern const char kEnableFileCookies[];
extern const char kEnableGeolocation[];
extern const char kEnableGPUPlugin[];
extern const char kEnableIndexedDatabase[];
+extern const char kEnableIPv6[];
extern const char kEnableLogging[];
extern const char kEnableMonitorProfile[];
extern const char kEnableNativeWebWorkers[];
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index 43fa906..a2eb04d 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -1538,4 +1538,54 @@ void SetExplicitlyAllowedPorts(const std::wstring& allowed_ports) {
explicitly_allowed_ports = ports;
}
+enum IPv6SupportStatus {
+ IPV6_CANNOT_CREATE_SOCKETS,
+ IPV6_CAN_CREATE_SOCKETS,
+ 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);
+}
+
+// TODO(jar): The following is a simple estimate of IPv6 support. We may need
+// to do a test resolution, and a test connection, to REALLY verify support.
+// static
+bool IPv6Supported() {
+#if defined(OS_POSIX)
+ int test_socket;
+
+ 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);
+ return true;
+#elif defined(OS_WIN)
+ EnsureWinsockInit();
+ SOCKET test_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;
+#else
+ NOTIMPLEMENTED();
+ return true;
+#endif // defined(various platforms)
+}
+
+
} // namespace net
diff --git a/net/base/net_util.h b/net/base/net_util.h
index d9affe6..28edad9 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -283,6 +283,11 @@ GURL SimplifyUrlForRequest(const GURL& url);
void SetExplicitlyAllowedPorts(const std::wstring& allowed_ports);
+// Perform a simplistic test to see if IPv6 is supported by trying to create an
+// IPv6 socket.
+// TODO(jar): Make test more in-depth as needed.
+bool IPv6Supported();
+
} // namespace net
#endif // NET_BASE_NET_UTIL_H_