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

Side by Side Diff: net/dns/host_resolver_impl.cc

Issue 1138833003: Reduce frequency of IPv6 probes in HostResolverImpl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « net/dns/host_resolver_impl.h ('k') | net/dns/host_resolver_impl_unittest.cc » ('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/dns/host_resolver_impl.h" 5 #include "net/dns/host_resolver_impl.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <Winsock2.h> 8 #include <Winsock2.h>
9 #elif defined(OS_POSIX) 9 #elif defined(OS_POSIX)
10 #include <netdb.h> 10 #include <netdb.h>
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 const unsigned kCacheEntryTTLSeconds = 60; 67 const unsigned kCacheEntryTTLSeconds = 60;
68 68
69 // Default TTL for unsuccessful resolutions with ProcTask. 69 // Default TTL for unsuccessful resolutions with ProcTask.
70 const unsigned kNegativeCacheEntryTTLSeconds = 0; 70 const unsigned kNegativeCacheEntryTTLSeconds = 0;
71 71
72 // Minimum TTL for successful resolutions with DnsTask. 72 // Minimum TTL for successful resolutions with DnsTask.
73 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds; 73 const unsigned kMinimumTTLSeconds = kCacheEntryTTLSeconds;
74 74
75 const char kLocalhost[] = "localhost."; 75 const char kLocalhost[] = "localhost.";
76 76
77 // Time between IPv6 probes, i.e. for how long results of each IPv6 probe are
78 // cached.
79 const int kIPv6ProbePeriodMs = 1000;
80
81 // Google DNS address used for IPv6 probes.
82 const uint8_t kIPv6ProbeAddress[] =
83 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 };
85
77 // We use a separate histogram name for each platform to facilitate the 86 // We use a separate histogram name for each platform to facilitate the
78 // display of error codes by their symbolic name (since each platform has 87 // display of error codes by their symbolic name (since each platform has
79 // different mappings). 88 // different mappings).
80 const char kOSErrorsForGetAddrinfoHistogramName[] = 89 const char kOSErrorsForGetAddrinfoHistogramName[] =
81 #if defined(OS_WIN) 90 #if defined(OS_WIN)
82 "Net.OSErrorsForGetAddrinfo_Win"; 91 "Net.OSErrorsForGetAddrinfo_Win";
83 #elif defined(OS_MACOSX) 92 #elif defined(OS_MACOSX)
84 "Net.OSErrorsForGetAddrinfo_Mac"; 93 "Net.OSErrorsForGetAddrinfo_Mac";
85 #elif defined(OS_LINUX) 94 #elif defined(OS_LINUX)
86 "Net.OSErrorsForGetAddrinfo_Linux"; 95 "Net.OSErrorsForGetAddrinfo_Linux";
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 dict->SetString("priority", RequestPriorityToString(priority)); 388 dict->SetString("priority", RequestPriorityToString(priority));
380 return dict; 389 return dict;
381 } 390 }
382 391
383 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event. 392 // Creates NetLog parameters for the DNS_CONFIG_CHANGED event.
384 base::Value* NetLogDnsConfigCallback(const DnsConfig* config, 393 base::Value* NetLogDnsConfigCallback(const DnsConfig* config,
385 NetLogCaptureMode /* capture_mode */) { 394 NetLogCaptureMode /* capture_mode */) {
386 return config->ToValue(); 395 return config->ToValue();
387 } 396 }
388 397
398 base::Value* NetLogIPv6AvailableCallback(bool ipv6_available,
399 bool cached,
400 NetLogCaptureMode /* capture_mode */) {
401 base::DictionaryValue* dict = new base::DictionaryValue();
402 dict->SetBoolean("ipv6_available", ipv6_available);
403 dict->SetBoolean("cached", cached);
404 return dict;
405 }
406
389 // The logging routines are defined here because some requests are resolved 407 // The logging routines are defined here because some requests are resolved
390 // without a Request object. 408 // without a Request object.
391 409
392 // Logs when a request has just been started. 410 // Logs when a request has just been started.
393 void LogStartRequest(const BoundNetLog& source_net_log, 411 void LogStartRequest(const BoundNetLog& source_net_log,
394 const HostResolver::RequestInfo& info) { 412 const HostResolver::RequestInfo& info) {
395 source_net_log.BeginEvent( 413 source_net_log.BeginEvent(
396 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST, 414 NetLog::TYPE_HOST_RESOLVER_IMPL_REQUEST,
397 base::Bind(&NetLogRequestInfoCallback, &info)); 415 base::Bind(&NetLogRequestInfoCallback, &info));
398 } 416 }
(...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 1826
1809 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) 1827 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log)
1810 : max_queued_jobs_(0), 1828 : max_queued_jobs_(0),
1811 proc_params_(NULL, options.max_retry_attempts), 1829 proc_params_(NULL, options.max_retry_attempts),
1812 net_log_(net_log), 1830 net_log_(net_log),
1813 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), 1831 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
1814 received_dns_config_(false), 1832 received_dns_config_(false),
1815 num_dns_failures_(0), 1833 num_dns_failures_(0),
1816 probe_ipv6_support_(true), 1834 probe_ipv6_support_(true),
1817 use_local_ipv6_(false), 1835 use_local_ipv6_(false),
1836 last_ipv6_probe_result_(true),
1818 resolved_known_ipv6_hostname_(false), 1837 resolved_known_ipv6_hostname_(false),
1819 additional_resolver_flags_(0), 1838 additional_resolver_flags_(0),
1820 fallback_to_proctask_(true), 1839 fallback_to_proctask_(true),
1821 weak_ptr_factory_(this), 1840 weak_ptr_factory_(this),
1822 probe_weak_ptr_factory_(this) { 1841 probe_weak_ptr_factory_(this) {
1823 if (options.enable_caching) 1842 if (options.enable_caching)
1824 cache_ = HostCache::CreateDefaultCache(); 1843 cache_ = HostCache::CreateDefaultCache();
1825 1844
1826 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits(); 1845 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits();
1827 dispatcher_.reset(new PrioritizedDispatcher(job_limits)); 1846 dispatcher_.reset(new PrioritizedDispatcher(job_limits));
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 if (result) { 2179 if (result) {
2161 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; 2180 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY;
2162 } else { 2181 } else {
2163 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; 2182 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY;
2164 } 2183 }
2165 } 2184 }
2166 2185
2167 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( 2186 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
2168 const RequestInfo& info, 2187 const RequestInfo& info,
2169 const IPAddressNumber* ip_number, 2188 const IPAddressNumber* ip_number,
2170 const BoundNetLog& net_log) const { 2189 const BoundNetLog& net_log) {
2171 HostResolverFlags effective_flags = 2190 HostResolverFlags effective_flags =
2172 info.host_resolver_flags() | additional_resolver_flags_; 2191 info.host_resolver_flags() | additional_resolver_flags_;
2173 AddressFamily effective_address_family = info.address_family(); 2192 AddressFamily effective_address_family = info.address_family();
2174 2193
2175 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { 2194 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) {
2176 if (probe_ipv6_support_ && !use_local_ipv6_ && 2195 if (probe_ipv6_support_ && !use_local_ipv6_ &&
2177 // When resolving IPv4 literals, there's no need to probe for IPv6. 2196 // When resolving IPv4 literals, there's no need to probe for IPv6.
2178 // When resolving IPv6 literals, there's no benefit to artificially 2197 // When resolving IPv6 literals, there's no benefit to artificially
2179 // limiting our resolution based on a probe. Prior logic ensures 2198 // limiting our resolution based on a probe. Prior logic ensures
2180 // that this query is UNSPECIFIED (see info.address_family() 2199 // that this query is UNSPECIFIED (see info.address_family()
2181 // check above) and that |default_address_family_| is UNSPECIFIED 2200 // check above) and that |default_address_family_| is UNSPECIFIED
2182 // (|prove_ipv6_support_| is false if |default_address_family_| is 2201 // (|prove_ipv6_support_| is false if |default_address_family_| is
2183 // set) so the code requesting the resolution should be amenable to 2202 // set) so the code requesting the resolution should be amenable to
2184 // receiving a IPv6 resolution. 2203 // receiving a IPv6 resolution.
2185 ip_number == nullptr) { 2204 ip_number == nullptr) {
2186 // Google DNS address. 2205 if (!IsIPv6Reachable(net_log)) {
2187 const uint8 kIPv6Address[] =
2188 { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
2189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 };
2190 IPAddressNumber address(kIPv6Address,
2191 kIPv6Address + arraysize(kIPv6Address));
2192 bool rv6 = IsGloballyReachable(address, net_log);
2193 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK,
2194 NetLog::BoolCallback("ipv6_available", rv6));
2195 if (!rv6) {
2196 effective_address_family = ADDRESS_FAMILY_IPV4; 2206 effective_address_family = ADDRESS_FAMILY_IPV4;
2197 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6; 2207 effective_flags |= HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
2198 } 2208 }
2199 } else { 2209 } else {
2200 effective_address_family = default_address_family_; 2210 effective_address_family = default_address_family_;
2201 } 2211 }
2202 } 2212 }
2203 2213
2204 std::string hostname = info.hostname(); 2214 std::string hostname = info.hostname();
2205 // Redirect .localhost queries to "localhost." to make sure that they 2215 // Redirect .localhost queries to "localhost." to make sure that they
2206 // are never sent out on the network, per RFC 6761. 2216 // are never sent out on the network, per RFC 6761.
2207 if (IsLocalhostTLD(info.hostname())) 2217 if (IsLocalhostTLD(info.hostname()))
2208 hostname = kLocalhost; 2218 hostname = kLocalhost;
2209 2219
2210 return Key(hostname, effective_address_family, effective_flags); 2220 return Key(hostname, effective_address_family, effective_flags);
2211 } 2221 }
2212 2222
2223 bool HostResolverImpl::IsIPv6Reachable(const BoundNetLog& net_log) {
2224 base::TimeTicks now = base::TimeTicks::Now();
2225 bool cached = true;
2226 if ((now - last_ipv6_probe_time_).InMilliseconds() > kIPv6ProbePeriodMs) {
2227 IPAddressNumber address(kIPv6ProbeAddress,
2228 kIPv6ProbeAddress + arraysize(kIPv6ProbeAddress));
2229 last_ipv6_probe_result_ = IsGloballyReachable(address, net_log);
2230 last_ipv6_probe_time_ = now;
2231 cached = false;
2232 }
2233 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK,
2234 base::Bind(&NetLogIPv6AvailableCallback,
2235 last_ipv6_probe_result_, cached));
2236 return last_ipv6_probe_result_;
2237 }
2238
2213 void HostResolverImpl::AbortAllInProgressJobs() { 2239 void HostResolverImpl::AbortAllInProgressJobs() {
2214 // In Abort, a Request callback could spawn new Jobs with matching keys, so 2240 // In Abort, a Request callback could spawn new Jobs with matching keys, so
2215 // first collect and remove all running jobs from |jobs_|. 2241 // first collect and remove all running jobs from |jobs_|.
2216 ScopedVector<Job> jobs_to_abort; 2242 ScopedVector<Job> jobs_to_abort;
2217 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { 2243 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) {
2218 Job* job = it->second; 2244 Job* job = it->second;
2219 if (job->is_running()) { 2245 if (job->is_running()) {
2220 jobs_to_abort.push_back(job); 2246 jobs_to_abort.push_back(job);
2221 jobs_.erase(it++); 2247 jobs_.erase(it++);
2222 } else { 2248 } else {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) { 2298 for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) {
2273 Job* job = it->second; 2299 Job* job = it->second;
2274 ++it; 2300 ++it;
2275 // This could remove |job| from |jobs_|, but iterator will remain valid. 2301 // This could remove |job| from |jobs_|, but iterator will remain valid.
2276 job->ServeFromHosts(); 2302 job->ServeFromHosts();
2277 } 2303 }
2278 } 2304 }
2279 2305
2280 void HostResolverImpl::OnIPAddressChanged() { 2306 void HostResolverImpl::OnIPAddressChanged() {
2281 resolved_known_ipv6_hostname_ = false; 2307 resolved_known_ipv6_hostname_ = false;
2308 last_ipv6_probe_time_ = base::TimeTicks();
2282 // Abandon all ProbeJobs. 2309 // Abandon all ProbeJobs.
2283 probe_weak_ptr_factory_.InvalidateWeakPtrs(); 2310 probe_weak_ptr_factory_.InvalidateWeakPtrs();
2284 if (cache_.get()) 2311 if (cache_.get())
2285 cache_->clear(); 2312 cache_->clear();
2286 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 2313 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2287 new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr()); 2314 new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr());
2288 #endif 2315 #endif
2289 AbortAllInProgressJobs(); 2316 AbortAllInProgressJobs();
2290 // |this| may be deleted inside AbortAllInProgressJobs(). 2317 // |this| may be deleted inside AbortAllInProgressJobs().
2291 } 2318 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 dns_client_->SetConfig(dns_config); 2419 dns_client_->SetConfig(dns_config);
2393 num_dns_failures_ = 0; 2420 num_dns_failures_ = 0;
2394 if (dns_client_->GetConfig()) 2421 if (dns_client_->GetConfig())
2395 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2422 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2396 } 2423 }
2397 2424
2398 AbortDnsTasks(); 2425 AbortDnsTasks();
2399 } 2426 }
2400 2427
2401 } // namespace net 2428 } // namespace net
OLDNEW
« no previous file with comments | « net/dns/host_resolver_impl.h ('k') | net/dns/host_resolver_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698