DNS: Per-network-type and Finch-variable timeouts

Right now, our DNS timeouts are fixed (6 seconds between calls to thehost resolver, 1 second default retransmission timeout for the internalresolver, and 5 second maximum even with exponential backoff). Thisworks okay on some network types, but could be a lot more patient on
some types (e.g. 2G cell networks).

This CL makes these timeouts configurable via field trials, after which
I willexperiment and find optimal values for each network type, and then
bake in some per-type defaults.

Note that this modifies the behavior of the async resolver in some
cases: if the right field trial is enabled, it will reset accumulated
RTT stats whenever the network *type* changes, not just when the IP
address changes (i.e. the device switches networks entirely).

BUG=595352

Review URL: https://codereview.chromium.org/1778933002

Cr-Commit-Position: refs/heads/master@{#381991}
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc
index bc1617c..c19d0ac 100644
--- a/net/dns/host_resolver_impl.cc
+++ b/net/dns/host_resolver_impl.cc
@@ -65,6 +65,10 @@
 
 namespace {
 
+// Default delay between calls to the system resolver for the same hostname.
+// (Can be overridden by field trial.)
+const int64_t kDnsDefaultUnresponsiveDelayMs = 6000;
+
 // Limit the size of hostnames that will be resolved to combat issues in
 // some platform's resolvers.
 const size_t kMaxHostLength = 4096;
@@ -1836,7 +1840,8 @@
     size_t max_retry_attempts)
     : resolver_proc(resolver_proc),
       max_retry_attempts(max_retry_attempts),
-      unresponsive_delay(base::TimeDelta::FromMilliseconds(6000)),
+      unresponsive_delay(
+          base::TimeDelta::FromMilliseconds(kDnsDefaultUnresponsiveDelayMs)),
       retry_factor(2) {
   // Maximum of 4 retry attempts for host resolution.
   static const size_t kDefaultMaxRetryAttempts = 4u;
@@ -1878,12 +1883,15 @@
   new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr());
 #endif
   NetworkChangeNotifier::AddIPAddressObserver(this);
+  NetworkChangeNotifier::AddConnectionTypeObserver(this);
   NetworkChangeNotifier::AddDNSObserver(this);
 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \
     !defined(OS_ANDROID)
   EnsureDnsReloaderInit();
 #endif
 
+  OnConnectionTypeChanged(NetworkChangeNotifier::GetConnectionType());
+
   {
     DnsConfig dns_config;
     NetworkChangeNotifier::GetDnsConfig(&dns_config);
@@ -1903,6 +1911,7 @@
   STLDeleteValues(&jobs_);
 
   NetworkChangeNotifier::RemoveIPAddressObserver(this);
+  NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
   NetworkChangeNotifier::RemoveDNSObserver(this);
 }
 
@@ -2341,6 +2350,15 @@
   // |this| may be deleted inside AbortAllInProgressJobs().
 }
 
+void HostResolverImpl::OnConnectionTypeChanged(
+    NetworkChangeNotifier::ConnectionType type) {
+  proc_params_.unresponsive_delay =
+      GetTimeDeltaForConnectionTypeFromFieldTrialOrDefault(
+          "DnsUnresponsiveDelayMsByConnectionType",
+          base::TimeDelta::FromMilliseconds(kDnsDefaultUnresponsiveDelayMs),
+          type);
+}
+
 void HostResolverImpl::OnInitialDNSConfigRead() {
   UpdateDNSConfig(false);
 }