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

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

Issue 2083643003: DNS: Let requests specify a callback for future cache hits (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 4 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
« net/dns/host_resolver.cc ('K') | « net/dns/host_resolver_impl.h ('k') | no next file » | 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 1764 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 1775
1776 // Complete all of the requests that were attached to the job. 1776 // Complete all of the requests that were attached to the job.
1777 for (const std::unique_ptr<Request>& req : requests_) { 1777 for (const std::unique_ptr<Request>& req : requests_) {
1778 if (req->was_canceled()) 1778 if (req->was_canceled())
1779 continue; 1779 continue;
1780 1780
1781 DCHECK_EQ(this, req->job()); 1781 DCHECK_EQ(this, req->job());
1782 // Update the net log and notify registered observers. 1782 // Update the net log and notify registered observers.
1783 LogFinishRequest(req->source_net_log(), req->info(), entry.error()); 1783 LogFinishRequest(req->source_net_log(), req->info(), entry.error());
1784 if (did_complete) { 1784 if (did_complete) {
1785 resolver_->MaybeAddCacheHitCallback(key_, req->info());
1785 // Record effective total time from creation to completion. 1786 // Record effective total time from creation to completion.
1786 RecordTotalTime(had_dns_config_, req->info().is_speculative(), 1787 RecordTotalTime(had_dns_config_, req->info().is_speculative(),
1787 base::TimeTicks::Now() - req->request_time()); 1788 base::TimeTicks::Now() - req->request_time());
1788 } 1789 }
1789 req->OnComplete(entry.error(), entry.addresses()); 1790 req->OnComplete(entry.error(), entry.addresses());
1790 1791
1791 // Check if the resolver was destroyed as a result of running the 1792 // Check if the resolver was destroyed as a result of running the
1792 // callback. If it was, we could continue, but we choose to bail. 1793 // callback. If it was, we could continue, but we choose to bail.
1793 if (!resolver_.get()) 1794 if (!resolver_.get())
1794 return; 1795 return;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 if (ip_address.AssignFromIPLiteral(info.hostname())) 1921 if (ip_address.AssignFromIPLiteral(info.hostname()))
1921 ip_address_ptr = &ip_address; 1922 ip_address_ptr = &ip_address;
1922 1923
1923 // Build a key that identifies the request in the cache and in the 1924 // Build a key that identifies the request in the cache and in the
1924 // outstanding jobs map. 1925 // outstanding jobs map.
1925 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); 1926 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log);
1926 1927
1927 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, 1928 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr,
1928 source_net_log); 1929 source_net_log);
1929 if (rv != ERR_DNS_CACHE_MISS) { 1930 if (rv != ERR_DNS_CACHE_MISS) {
1931 MaybeAddCacheHitCallback(key, info);
1930 LogFinishRequest(source_net_log, info, rv); 1932 LogFinishRequest(source_net_log, info, rv);
1931 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); 1933 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta());
1932 return rv; 1934 return rv;
1933 } 1935 }
1934 1936
1935 // Next we need to attach our request to a "job". This job is responsible for 1937 // Next we need to attach our request to a "job". This job is responsible for
1936 // calling "getaddrinfo(hostname)" on a worker thread. 1938 // calling "getaddrinfo(hostname)" on a worker thread.
1937 1939
1938 JobMap::iterator jobit = jobs_.find(key); 1940 JobMap::iterator jobit = jobs_.find(key);
1939 Job* job; 1941 Job* job;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 2050
2049 int net_error = ERR_UNEXPECTED; 2051 int net_error = ERR_UNEXPECTED;
2050 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) { 2052 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) {
2051 MakeNotStale(stale_info); 2053 MakeNotStale(stale_info);
2052 return net_error; 2054 return net_error;
2053 } 2055 }
2054 if (ServeFromCache(key, info, &net_error, addresses, allow_stale, 2056 if (ServeFromCache(key, info, &net_error, addresses, allow_stale,
2055 stale_info)) { 2057 stale_info)) {
2056 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); 2058 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT);
2057 // |ServeFromCache()| will set |*stale_info| as needed. 2059 // |ServeFromCache()| will set |*stale_info| as needed.
2060 RunCacheHitCallbacks(key, info);
2058 return net_error; 2061 return net_error;
2059 } 2062 }
2060 // TODO(szym): Do not do this if nsswitch.conf instructs not to. 2063 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
2061 // http://crbug.com/117655 2064 // http://crbug.com/117655
2062 if (ServeFromHosts(key, info, addresses)) { 2065 if (ServeFromHosts(key, info, addresses)) {
2063 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); 2066 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT);
2064 MakeNotStale(stale_info); 2067 MakeNotStale(stale_info);
2065 return OK; 2068 return OK;
2066 } 2069 }
2067 2070
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 } 2299 }
2297 2300
2298 return true; 2301 return true;
2299 } 2302 }
2300 2303
2301 void HostResolverImpl::CacheResult(const Key& key, 2304 void HostResolverImpl::CacheResult(const Key& key,
2302 const HostCache::Entry& entry, 2305 const HostCache::Entry& entry,
2303 base::TimeDelta ttl) { 2306 base::TimeDelta ttl) {
2304 if (cache_.get()) 2307 if (cache_.get())
2305 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); 2308 cache_->Set(key, entry, base::TimeTicks::Now(), ttl);
2309 ClearCacheHitCallbacks(key);
Charlie Harrison 2016/07/26 13:41:13 It is not quite clear why we clear the cache hit c
Julia Tuttle 2016/07/26 17:51:24 Done.
2306 } 2310 }
2307 2311
2308 void HostResolverImpl::RemoveJob(Job* job) { 2312 void HostResolverImpl::RemoveJob(Job* job) {
2309 DCHECK(job); 2313 DCHECK(job);
2310 JobMap::iterator it = jobs_.find(job->key()); 2314 JobMap::iterator it = jobs_.find(job->key());
2311 if (it != jobs_.end() && it->second == job) 2315 if (it != jobs_.end() && it->second == job)
2312 jobs_.erase(it); 2316 jobs_.erase(it);
2313 } 2317 }
2314 2318
2315 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( 2319 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest(
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 // This could remove |job| from |jobs_|, but iterator will remain valid. 2428 // This could remove |job| from |jobs_|, but iterator will remain valid.
2425 job->ServeFromHosts(); 2429 job->ServeFromHosts();
2426 } 2430 }
2427 } 2431 }
2428 2432
2429 void HostResolverImpl::OnIPAddressChanged() { 2433 void HostResolverImpl::OnIPAddressChanged() {
2430 resolved_known_ipv6_hostname_ = false; 2434 resolved_known_ipv6_hostname_ = false;
2431 last_ipv6_probe_time_ = base::TimeTicks(); 2435 last_ipv6_probe_time_ = base::TimeTicks();
2432 // Abandon all ProbeJobs. 2436 // Abandon all ProbeJobs.
2433 probe_weak_ptr_factory_.InvalidateWeakPtrs(); 2437 probe_weak_ptr_factory_.InvalidateWeakPtrs();
2434 if (cache_.get()) 2438 if (cache_.get()) {
2435 cache_->clear(); 2439 cache_->clear();
2440 cache_hit_callbacks_.clear();
2441 }
2436 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 2442 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2437 RunLoopbackProbeJob(); 2443 RunLoopbackProbeJob();
2438 #endif 2444 #endif
2439 AbortAllInProgressJobs(); 2445 AbortAllInProgressJobs();
2440 // |this| may be deleted inside AbortAllInProgressJobs(). 2446 // |this| may be deleted inside AbortAllInProgressJobs().
2441 } 2447 }
2442 2448
2443 void HostResolverImpl::OnConnectionTypeChanged( 2449 void HostResolverImpl::OnConnectionTypeChanged(
2444 NetworkChangeNotifier::ConnectionType type) { 2450 NetworkChangeNotifier::ConnectionType type) {
2445 proc_params_.unresponsive_delay = 2451 proc_params_.unresponsive_delay =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 // TODO(pauljensen): Is this necessary? 2490 // TODO(pauljensen): Is this necessary?
2485 config_changed = true; 2491 config_changed = true;
2486 } 2492 }
2487 } 2493 }
2488 2494
2489 if (config_changed) { 2495 if (config_changed) {
2490 // If the DNS server has changed, existing cached info could be wrong so we 2496 // If the DNS server has changed, existing cached info could be wrong so we
2491 // have to drop our internal cache :( Note that OS level DNS caches, such 2497 // have to drop our internal cache :( Note that OS level DNS caches, such
2492 // as NSCD's cache should be dropped automatically by the OS when 2498 // as NSCD's cache should be dropped automatically by the OS when
2493 // resolv.conf changes so we don't need to do anything to clear that cache. 2499 // resolv.conf changes so we don't need to do anything to clear that cache.
2494 if (cache_.get()) 2500 if (cache_.get()) {
2495 cache_->clear(); 2501 cache_->clear();
2502 cache_hit_callbacks_.clear();
2503 }
2496 2504
2497 // Life check to bail once |this| is deleted. 2505 // Life check to bail once |this| is deleted.
2498 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); 2506 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
2499 2507
2500 // Existing jobs will have been sent to the original server so they need to 2508 // Existing jobs will have been sent to the original server so they need to
2501 // be aborted. 2509 // be aborted.
2502 AbortAllInProgressJobs(); 2510 AbortAllInProgressJobs();
2503 2511
2504 // |this| may be deleted inside AbortAllInProgressJobs(). 2512 // |this| may be deleted inside AbortAllInProgressJobs().
2505 if (self.get()) 2513 if (self.get())
(...skipping 25 matching lines...) Expand all
2531 dns_client_->SetConfig(DnsConfig()); 2539 dns_client_->SetConfig(DnsConfig());
2532 2540
2533 // Switch jobs with active DnsTasks over to using ProcTasks. 2541 // Switch jobs with active DnsTasks over to using ProcTasks.
2534 AbortDnsTasks(); 2542 AbortDnsTasks();
2535 2543
2536 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false); 2544 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false);
2537 UMA_HISTOGRAM_SPARSE_SLOWLY("AsyncDNS.DnsClientDisabledReason", 2545 UMA_HISTOGRAM_SPARSE_SLOWLY("AsyncDNS.DnsClientDisabledReason",
2538 std::abs(net_error)); 2546 std::abs(net_error));
2539 } 2547 }
2540 2548
2549 void HostResolverImpl::OnCacheEntryEvicted(const HostCache::Key& key,
2550 const HostCache::Entry& entry) {
2551 ClearCacheHitCallbacks(key);
2552 }
2553
2554 void HostResolverImpl::ClearCacheHitCallbacks(const HostCache::Key& key) {
Charlie Harrison 2016/07/26 13:41:13 I don't think this method is really necessary.
Julia Tuttle 2016/07/26 17:51:24 Done.
2555 cache_hit_callbacks_.erase(key);
2556 }
2557
2558 void HostResolverImpl::MaybeAddCacheHitCallback(const HostCache::Key& key,
2559 const RequestInfo& info) {
2560 const RequestInfo::CacheHitCallback& callback = info.cache_hit_callback();
2561 if (callback.is_null())
2562 return;
2563 cache_hit_callbacks_[key].push_back(callback);
2564 }
2565
2566 void HostResolverImpl::RunCacheHitCallbacks(const HostCache::Key& key,
2567 const RequestInfo& info) {
2568 if (cache_hit_callbacks_.count(key) == 0u)
Charlie Harrison 2016/07/26 13:41:13 I think using find(key) is clearer here, and only
Julia Tuttle 2016/07/26 17:51:24 Done.
2569 return;
2570 for (auto& callback : cache_hit_callbacks_[key])
2571 callback.Run(info);
2572 }
2573
2541 void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) { 2574 void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
2542 // DnsClient and config must be updated before aborting DnsTasks, since doing 2575 // DnsClient and config must be updated before aborting DnsTasks, since doing
2543 // so may start new jobs. 2576 // so may start new jobs.
2544 dns_client_ = std::move(dns_client); 2577 dns_client_ = std::move(dns_client);
2545 if (dns_client_ && !dns_client_->GetConfig() && 2578 if (dns_client_ && !dns_client_->GetConfig() &&
2546 num_dns_failures_ < kMaximumDnsFailures) { 2579 num_dns_failures_ < kMaximumDnsFailures) {
2547 DnsConfig dns_config; 2580 DnsConfig dns_config;
2548 NetworkChangeNotifier::GetDnsConfig(&dns_config); 2581 NetworkChangeNotifier::GetDnsConfig(&dns_config);
2549 dns_client_->SetConfig(dns_config); 2582 dns_client_->SetConfig(dns_config);
2550 num_dns_failures_ = 0; 2583 num_dns_failures_ = 0;
2551 if (dns_client_->GetConfig()) 2584 if (dns_client_->GetConfig())
2552 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2585 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2553 } 2586 }
2554 2587
2555 AbortDnsTasks(); 2588 AbortDnsTasks();
2556 } 2589 }
2557 2590
2558 } // namespace net 2591 } // namespace net
OLDNEW
« net/dns/host_resolver.cc ('K') | « net/dns/host_resolver_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698