OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |