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

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: Clarify a couple comments. 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
« 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 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 1768
1769 if (entry.error() == OK) { 1769 if (entry.error() == OK) {
1770 // Record this histogram here, when we know the system has a valid DNS 1770 // Record this histogram here, when we know the system has a valid DNS
1771 // configuration. 1771 // configuration.
1772 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig", 1772 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.HaveDnsConfig",
1773 resolver_->received_dns_config_); 1773 resolver_->received_dns_config_);
1774 } 1774 }
1775 1775
1776 bool did_complete = (entry.error() != ERR_NETWORK_CHANGED) && 1776 bool did_complete = (entry.error() != ERR_NETWORK_CHANGED) &&
1777 (entry.error() != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE); 1777 (entry.error() != ERR_HOST_RESOLVER_QUEUE_TOO_LARGE);
1778 if (did_complete) 1778 if (did_complete) {
1779 resolver_->CacheResult(key_, entry, ttl); 1779 resolver_->CacheResult(key_, entry, ttl);
1780 // Erase any previous cache hit callbacks, since a new DNS request went
1781 // out since they were set.
1782 resolver_->cache_hit_callbacks_.erase(key_);
1783 }
1780 1784
1781 // Complete all of the requests that were attached to the job and 1785 // Complete all of the requests that were attached to the job and
1782 // detach them. 1786 // detach them.
1783 while (!requests_.empty()) { 1787 while (!requests_.empty()) {
1784 RequestImpl* req = requests_.front(); 1788 RequestImpl* req = requests_.front();
1785 requests_.pop_front(); 1789 requests_.pop_front();
1786 DCHECK_EQ(this, req->job()); 1790 DCHECK_EQ(this, req->job());
1787 // Update the net log and notify registered observers. 1791 // Update the net log and notify registered observers.
1788 LogFinishRequest(req->source_net_log(), req->info(), entry.error()); 1792 LogFinishRequest(req->source_net_log(), req->info(), entry.error());
1789 if (did_complete) { 1793 if (did_complete) {
1794 resolver_->MaybeAddCacheHitCallback(key_, req->info());
1790 // Record effective total time from creation to completion. 1795 // Record effective total time from creation to completion.
1791 RecordTotalTime(had_dns_config_, req->info().is_speculative(), 1796 RecordTotalTime(had_dns_config_, req->info().is_speculative(),
1792 base::TimeTicks::Now() - req->request_time()); 1797 base::TimeTicks::Now() - req->request_time());
1793 } 1798 }
1794 req->OnJobCompleted(this, entry.error(), entry.addresses()); 1799 req->OnJobCompleted(this, entry.error(), entry.addresses());
1795 1800
1796 // Check if the resolver was destroyed as a result of running the 1801 // Check if the resolver was destroyed as a result of running the
1797 // callback. If it was, we could continue, but we choose to bail. 1802 // callback. If it was, we could continue, but we choose to bail.
1798 if (!resolver_.get()) 1803 if (!resolver_.get())
1799 return; 1804 return;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 if (ip_address.AssignFromIPLiteral(info.hostname())) 1931 if (ip_address.AssignFromIPLiteral(info.hostname()))
1927 ip_address_ptr = &ip_address; 1932 ip_address_ptr = &ip_address;
1928 1933
1929 // Build a key that identifies the request in the cache and in the 1934 // Build a key that identifies the request in the cache and in the
1930 // outstanding jobs map. 1935 // outstanding jobs map.
1931 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log); 1936 Key key = GetEffectiveKeyForRequest(info, ip_address_ptr, source_net_log);
1932 1937
1933 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr, 1938 int rv = ResolveHelper(key, info, ip_address_ptr, addresses, false, nullptr,
1934 source_net_log); 1939 source_net_log);
1935 if (rv != ERR_DNS_CACHE_MISS) { 1940 if (rv != ERR_DNS_CACHE_MISS) {
1941 MaybeAddCacheHitCallback(key, info);
1936 LogFinishRequest(source_net_log, info, rv); 1942 LogFinishRequest(source_net_log, info, rv);
1937 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); 1943 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta());
1938 return rv; 1944 return rv;
1939 } 1945 }
1940 1946
1941 // Next we need to attach our request to a "job". This job is responsible for 1947 // Next we need to attach our request to a "job". This job is responsible for
1942 // calling "getaddrinfo(hostname)" on a worker thread. 1948 // calling "getaddrinfo(hostname)" on a worker thread.
1943 1949
1944 JobMap::iterator jobit = jobs_.find(key); 1950 JobMap::iterator jobit = jobs_.find(key);
1945 Job* job; 1951 Job* job;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2054 2060
2055 int net_error = ERR_UNEXPECTED; 2061 int net_error = ERR_UNEXPECTED;
2056 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) { 2062 if (ResolveAsIP(key, info, ip_address, &net_error, addresses)) {
2057 MakeNotStale(stale_info); 2063 MakeNotStale(stale_info);
2058 return net_error; 2064 return net_error;
2059 } 2065 }
2060 if (ServeFromCache(key, info, &net_error, addresses, allow_stale, 2066 if (ServeFromCache(key, info, &net_error, addresses, allow_stale,
2061 stale_info)) { 2067 stale_info)) {
2062 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT); 2068 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CACHE_HIT);
2063 // |ServeFromCache()| will set |*stale_info| as needed. 2069 // |ServeFromCache()| will set |*stale_info| as needed.
2070 RunCacheHitCallbacks(key, info);
2064 return net_error; 2071 return net_error;
2065 } 2072 }
2066 // TODO(szym): Do not do this if nsswitch.conf instructs not to. 2073 // TODO(szym): Do not do this if nsswitch.conf instructs not to.
2067 // http://crbug.com/117655 2074 // http://crbug.com/117655
2068 if (ServeFromHosts(key, info, addresses)) { 2075 if (ServeFromHosts(key, info, addresses)) {
2069 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT); 2076 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_HOSTS_HIT);
2070 MakeNotStale(stale_info); 2077 MakeNotStale(stale_info);
2071 return OK; 2078 return OK;
2072 } 2079 }
2073 2080
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2411 // This could remove |job| from |jobs_|, but iterator will remain valid. 2418 // This could remove |job| from |jobs_|, but iterator will remain valid.
2412 job->ServeFromHosts(); 2419 job->ServeFromHosts();
2413 } 2420 }
2414 } 2421 }
2415 2422
2416 void HostResolverImpl::OnIPAddressChanged() { 2423 void HostResolverImpl::OnIPAddressChanged() {
2417 resolved_known_ipv6_hostname_ = false; 2424 resolved_known_ipv6_hostname_ = false;
2418 last_ipv6_probe_time_ = base::TimeTicks(); 2425 last_ipv6_probe_time_ = base::TimeTicks();
2419 // Abandon all ProbeJobs. 2426 // Abandon all ProbeJobs.
2420 probe_weak_ptr_factory_.InvalidateWeakPtrs(); 2427 probe_weak_ptr_factory_.InvalidateWeakPtrs();
2421 if (cache_.get()) 2428 if (cache_.get()) {
2422 cache_->clear(); 2429 cache_->clear();
2430 cache_hit_callbacks_.clear();
2431 }
2423 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 2432 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2424 RunLoopbackProbeJob(); 2433 RunLoopbackProbeJob();
2425 #endif 2434 #endif
2426 AbortAllInProgressJobs(); 2435 AbortAllInProgressJobs();
2427 // |this| may be deleted inside AbortAllInProgressJobs(). 2436 // |this| may be deleted inside AbortAllInProgressJobs().
2428 } 2437 }
2429 2438
2430 void HostResolverImpl::OnConnectionTypeChanged( 2439 void HostResolverImpl::OnConnectionTypeChanged(
2431 NetworkChangeNotifier::ConnectionType type) { 2440 NetworkChangeNotifier::ConnectionType type) {
2432 proc_params_.unresponsive_delay = 2441 proc_params_.unresponsive_delay =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 // TODO(pauljensen): Is this necessary? 2480 // TODO(pauljensen): Is this necessary?
2472 config_changed = true; 2481 config_changed = true;
2473 } 2482 }
2474 } 2483 }
2475 2484
2476 if (config_changed) { 2485 if (config_changed) {
2477 // If the DNS server has changed, existing cached info could be wrong so we 2486 // If the DNS server has changed, existing cached info could be wrong so we
2478 // have to drop our internal cache :( Note that OS level DNS caches, such 2487 // have to drop our internal cache :( Note that OS level DNS caches, such
2479 // as NSCD's cache should be dropped automatically by the OS when 2488 // as NSCD's cache should be dropped automatically by the OS when
2480 // resolv.conf changes so we don't need to do anything to clear that cache. 2489 // resolv.conf changes so we don't need to do anything to clear that cache.
2481 if (cache_.get()) 2490 if (cache_.get()) {
2482 cache_->clear(); 2491 cache_->clear();
2492 cache_hit_callbacks_.clear();
2493 }
2483 2494
2484 // Life check to bail once |this| is deleted. 2495 // Life check to bail once |this| is deleted.
2485 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); 2496 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr();
2486 2497
2487 // Existing jobs will have been sent to the original server so they need to 2498 // Existing jobs will have been sent to the original server so they need to
2488 // be aborted. 2499 // be aborted.
2489 AbortAllInProgressJobs(); 2500 AbortAllInProgressJobs();
2490 2501
2491 // |this| may be deleted inside AbortAllInProgressJobs(). 2502 // |this| may be deleted inside AbortAllInProgressJobs().
2492 if (self.get()) 2503 if (self.get())
(...skipping 25 matching lines...) Expand all
2518 dns_client_->SetConfig(DnsConfig()); 2529 dns_client_->SetConfig(DnsConfig());
2519 2530
2520 // Switch jobs with active DnsTasks over to using ProcTasks. 2531 // Switch jobs with active DnsTasks over to using ProcTasks.
2521 AbortDnsTasks(); 2532 AbortDnsTasks();
2522 2533
2523 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false); 2534 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", false);
2524 UMA_HISTOGRAM_SPARSE_SLOWLY("AsyncDNS.DnsClientDisabledReason", 2535 UMA_HISTOGRAM_SPARSE_SLOWLY("AsyncDNS.DnsClientDisabledReason",
2525 std::abs(net_error)); 2536 std::abs(net_error));
2526 } 2537 }
2527 2538
2539 void HostResolverImpl::OnCacheEntryEvicted(const HostCache::Key& key,
2540 const HostCache::Entry& entry) {
2541 cache_hit_callbacks_.erase(key);
2542 }
2543
2544 void HostResolverImpl::MaybeAddCacheHitCallback(const HostCache::Key& key,
2545 const RequestInfo& info) {
2546 const RequestInfo::CacheHitCallback& callback = info.cache_hit_callback();
2547 if (callback.is_null())
2548 return;
2549 cache_hit_callbacks_[key].push_back(callback);
2550 }
2551
2552 void HostResolverImpl::RunCacheHitCallbacks(const HostCache::Key& key,
2553 const RequestInfo& info) {
2554 auto it = cache_hit_callbacks_.find(key);
2555 if (it == cache_hit_callbacks_.end())
2556 return;
2557 for (auto& callback : it->second)
2558 callback.Run(info);
2559 }
2560
2528 void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) { 2561 void HostResolverImpl::SetDnsClient(std::unique_ptr<DnsClient> dns_client) {
2529 // DnsClient and config must be updated before aborting DnsTasks, since doing 2562 // DnsClient and config must be updated before aborting DnsTasks, since doing
2530 // so may start new jobs. 2563 // so may start new jobs.
2531 dns_client_ = std::move(dns_client); 2564 dns_client_ = std::move(dns_client);
2532 if (dns_client_ && !dns_client_->GetConfig() && 2565 if (dns_client_ && !dns_client_->GetConfig() &&
2533 num_dns_failures_ < kMaximumDnsFailures) { 2566 num_dns_failures_ < kMaximumDnsFailures) {
2534 DnsConfig dns_config; 2567 DnsConfig dns_config;
2535 NetworkChangeNotifier::GetDnsConfig(&dns_config); 2568 NetworkChangeNotifier::GetDnsConfig(&dns_config);
2536 dns_client_->SetConfig(dns_config); 2569 dns_client_->SetConfig(dns_config);
2537 num_dns_failures_ = 0; 2570 num_dns_failures_ = 0;
2538 if (dns_client_->GetConfig()) 2571 if (dns_client_->GetConfig())
2539 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); 2572 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true);
2540 } 2573 }
2541 2574
2542 AbortDnsTasks(); 2575 AbortDnsTasks();
2543 } 2576 }
2544 2577
2545 void HostResolverImpl::InitializePersistence( 2578 void HostResolverImpl::InitializePersistence(
2546 const PersistCallback& persist_callback, 2579 const PersistCallback& persist_callback,
2547 std::unique_ptr<const base::Value> old_data) { 2580 std::unique_ptr<const base::Value> old_data) {
2548 DCHECK(!persist_initialized_); 2581 DCHECK(!persist_initialized_);
2549 persist_callback_ = persist_callback; 2582 persist_callback_ = persist_callback;
2550 persist_initialized_ = true; 2583 persist_initialized_ = true;
2551 if (old_data) 2584 if (old_data)
2552 ApplyPersistentData(std::move(old_data)); 2585 ApplyPersistentData(std::move(old_data));
2553 } 2586 }
2554 2587
2588 void HostResolverImpl::ApplyPersistentData(
2589 std::unique_ptr<const base::Value> data) {}
2590
2591 std::unique_ptr<const base::Value> HostResolverImpl::GetPersistentData() {
2592 return std::unique_ptr<const base::Value>();
2593 }
2594
2555 void HostResolverImpl::SchedulePersist() { 2595 void HostResolverImpl::SchedulePersist() {
2556 if (!persist_initialized_ || persist_timer_.IsRunning()) 2596 if (!persist_initialized_ || persist_timer_.IsRunning())
2557 return; 2597 return;
2558 persist_timer_.Start( 2598 persist_timer_.Start(
2559 FROM_HERE, base::TimeDelta::FromSeconds(kPersistDelaySec), 2599 FROM_HERE, base::TimeDelta::FromSeconds(kPersistDelaySec),
2560 base::Bind(&HostResolverImpl::DoPersist, weak_ptr_factory_.GetWeakPtr())); 2600 base::Bind(&HostResolverImpl::DoPersist, weak_ptr_factory_.GetWeakPtr()));
2561 } 2601 }
2562 2602
2563 void HostResolverImpl::DoPersist() { 2603 void HostResolverImpl::DoPersist() {
2564 DCHECK(persist_initialized_); 2604 DCHECK(persist_initialized_);
2565 persist_callback_.Run(GetPersistentData()); 2605 persist_callback_.Run(GetPersistentData());
2566 } 2606 }
2567 2607
2568 void HostResolverImpl::ApplyPersistentData(
2569 std::unique_ptr<const base::Value> data) {}
2570
2571 std::unique_ptr<const base::Value> HostResolverImpl::GetPersistentData() {
2572 return std::unique_ptr<const base::Value>();
2573 }
2574
2575 HostResolverImpl::RequestImpl::~RequestImpl() { 2608 HostResolverImpl::RequestImpl::~RequestImpl() {
2576 if (job_) 2609 if (job_)
2577 job_->CancelRequest(this); 2610 job_->CancelRequest(this);
2578 } 2611 }
2579 2612
2580 void HostResolverImpl::RequestImpl::ChangeRequestPriority( 2613 void HostResolverImpl::RequestImpl::ChangeRequestPriority(
2581 RequestPriority priority) { 2614 RequestPriority priority) {
2582 job_->ChangeRequestPriority(this, priority); 2615 job_->ChangeRequestPriority(this, priority);
2583 } 2616 }
2584 2617
2585 } // namespace net 2618 } // 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