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 12 matching lines...) Expand all Loading... |
23 #include "base/debug/debugger.h" | 23 #include "base/debug/debugger.h" |
24 #include "base/debug/leak_annotations.h" | 24 #include "base/debug/leak_annotations.h" |
25 #include "base/debug/stack_trace.h" | 25 #include "base/debug/stack_trace.h" |
26 #include "base/macros.h" | 26 #include "base/macros.h" |
27 #include "base/memory/ptr_util.h" | 27 #include "base/memory/ptr_util.h" |
28 #include "base/metrics/field_trial.h" | 28 #include "base/metrics/field_trial.h" |
29 #include "base/metrics/histogram_macros.h" | 29 #include "base/metrics/histogram_macros.h" |
30 #include "base/metrics/sparse_histogram.h" | 30 #include "base/metrics/sparse_histogram.h" |
31 #include "base/profiler/scoped_tracker.h" | 31 #include "base/profiler/scoped_tracker.h" |
32 #include "base/single_thread_task_runner.h" | 32 #include "base/single_thread_task_runner.h" |
33 #include "base/stl_util.h" | |
34 #include "base/strings/string_util.h" | 33 #include "base/strings/string_util.h" |
35 #include "base/strings/utf_string_conversions.h" | 34 #include "base/strings/utf_string_conversions.h" |
36 #include "base/threading/thread_task_runner_handle.h" | 35 #include "base/threading/thread_task_runner_handle.h" |
37 #include "base/threading/worker_pool.h" | 36 #include "base/threading/worker_pool.h" |
38 #include "base/time/time.h" | 37 #include "base/time/time.h" |
39 #include "base/trace_event/trace_event.h" | 38 #include "base/trace_event/trace_event.h" |
40 #include "base/values.h" | 39 #include "base/values.h" |
41 #include "net/base/address_family.h" | 40 #include "net/base/address_family.h" |
42 #include "net/base/address_list.h" | 41 #include "net/base/address_list.h" |
43 #include "net/base/host_port_pair.h" | 42 #include "net/base/host_port_pair.h" |
(...skipping 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1888 | 1887 |
1889 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) | 1888 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) |
1890 : HostResolverImpl( | 1889 : HostResolverImpl( |
1891 options, | 1890 options, |
1892 net_log, | 1891 net_log, |
1893 base::WorkerPool::GetTaskRunner(true /* task_is_slow */)) {} | 1892 base::WorkerPool::GetTaskRunner(true /* task_is_slow */)) {} |
1894 | 1893 |
1895 HostResolverImpl::~HostResolverImpl() { | 1894 HostResolverImpl::~HostResolverImpl() { |
1896 // Prevent the dispatcher from starting new jobs. | 1895 // Prevent the dispatcher from starting new jobs. |
1897 dispatcher_->SetLimitsToZero(); | 1896 dispatcher_->SetLimitsToZero(); |
1898 // It's now safe for Jobs to call KillDsnTask on destruction, because | 1897 // It's now safe for Jobs to call KillDnsTask on destruction, because |
1899 // OnJobComplete will not start any new jobs. | 1898 // OnJobComplete will not start any new jobs. |
1900 base::STLDeleteValues(&jobs_); | 1899 jobs_.clear(); |
1901 | 1900 |
1902 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 1901 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
1903 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 1902 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
1904 NetworkChangeNotifier::RemoveDNSObserver(this); | 1903 NetworkChangeNotifier::RemoveDNSObserver(this); |
1905 } | 1904 } |
1906 | 1905 |
1907 void HostResolverImpl::SetMaxQueuedJobs(size_t value) { | 1906 void HostResolverImpl::SetMaxQueuedJobs(size_t value) { |
1908 DCHECK_EQ(0u, dispatcher_->num_queued_jobs()); | 1907 DCHECK_EQ(0u, dispatcher_->num_queued_jobs()); |
1909 DCHECK_GT(value, 0u); | 1908 DCHECK_GT(value, 0u); |
1910 max_queued_jobs_ = value; | 1909 max_queued_jobs_ = value; |
(...skipping 30 matching lines...) Expand all Loading... |
1941 if (rv != ERR_DNS_CACHE_MISS) { | 1940 if (rv != ERR_DNS_CACHE_MISS) { |
1942 MaybeAddCacheHitCallback(key, info); | 1941 MaybeAddCacheHitCallback(key, info); |
1943 LogFinishRequest(source_net_log, info, rv); | 1942 LogFinishRequest(source_net_log, info, rv); |
1944 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); | 1943 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); |
1945 return rv; | 1944 return rv; |
1946 } | 1945 } |
1947 | 1946 |
1948 // 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 |
1949 // calling "getaddrinfo(hostname)" on a worker thread. | 1948 // calling "getaddrinfo(hostname)" on a worker thread. |
1950 | 1949 |
1951 JobMap::iterator jobit = jobs_.find(key); | 1950 auto jobit = jobs_.find(key); |
1952 Job* job; | 1951 Job* job; |
1953 if (jobit == jobs_.end()) { | 1952 if (jobit == jobs_.end()) { |
1954 job = new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, | 1953 job = new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, |
1955 worker_task_runner_, source_net_log); | 1954 worker_task_runner_, source_net_log); |
1956 job->Schedule(false); | 1955 job->Schedule(false); |
1957 | 1956 |
1958 // Check for queue overflow. | 1957 // Check for queue overflow. |
1959 if (dispatcher_->num_queued_jobs() > max_queued_jobs_) { | 1958 if (dispatcher_->num_queued_jobs() > max_queued_jobs_) { |
1960 Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest()); | 1959 Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest()); |
1961 DCHECK(evicted); | 1960 DCHECK(evicted); |
1962 evicted->OnEvicted(); // Deletes |evicted|. | 1961 evicted->OnEvicted(); // Deletes |evicted|. |
1963 if (evicted == job) { | 1962 if (evicted == job) { |
1964 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; | 1963 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
1965 LogFinishRequest(source_net_log, info, rv); | 1964 LogFinishRequest(source_net_log, info, rv); |
1966 return rv; | 1965 return rv; |
1967 } | 1966 } |
1968 } | 1967 } |
1969 jobs_.insert(jobit, std::make_pair(key, job)); | 1968 jobs_[key] = base::WrapUnique(job); |
1970 } else { | 1969 } else { |
1971 job = jobit->second; | 1970 job = jobit->second.get(); |
1972 } | 1971 } |
1973 | 1972 |
1974 // Can't complete synchronously. Create and attach request. | 1973 // Can't complete synchronously. Create and attach request. |
1975 std::unique_ptr<RequestImpl> req(new RequestImpl( | 1974 auto req = base::MakeUnique<RequestImpl>(source_net_log, info, priority, |
1976 source_net_log, info, priority, callback, addresses, job)); | 1975 callback, addresses, job); |
1977 job->AddRequest(req.get()); | 1976 job->AddRequest(req.get()); |
1978 *out_req = std::move(req); | 1977 *out_req = std::move(req); |
1979 | 1978 |
1980 // Completion happens during Job::CompleteRequests(). | 1979 // Completion happens during Job::CompleteRequests(). |
1981 return ERR_IO_PENDING; | 1980 return ERR_IO_PENDING; |
1982 } | 1981 } |
1983 | 1982 |
1984 HostResolverImpl::HostResolverImpl( | 1983 HostResolverImpl::HostResolverImpl( |
1985 const Options& options, | 1984 const Options& options, |
1986 NetLog* net_log, | 1985 NetLog* net_log, |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 | 2294 |
2296 void HostResolverImpl::CacheResult(const Key& key, | 2295 void HostResolverImpl::CacheResult(const Key& key, |
2297 const HostCache::Entry& entry, | 2296 const HostCache::Entry& entry, |
2298 base::TimeDelta ttl) { | 2297 base::TimeDelta ttl) { |
2299 if (cache_.get()) | 2298 if (cache_.get()) |
2300 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); | 2299 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); |
2301 } | 2300 } |
2302 | 2301 |
2303 void HostResolverImpl::RemoveJob(Job* job) { | 2302 void HostResolverImpl::RemoveJob(Job* job) { |
2304 DCHECK(job); | 2303 DCHECK(job); |
2305 JobMap::iterator it = jobs_.find(job->key()); | 2304 auto it = jobs_.find(job->key()); |
2306 if (it != jobs_.end() && it->second == job) | 2305 if (it != jobs_.end() && it->second.get() == job) { |
| 2306 it->second.release(); |
2307 jobs_.erase(it); | 2307 jobs_.erase(it); |
| 2308 } |
2308 } | 2309 } |
2309 | 2310 |
2310 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( | 2311 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
2311 const RequestInfo& info, | 2312 const RequestInfo& info, |
2312 const IPAddress* ip_address, | 2313 const IPAddress* ip_address, |
2313 const NetLogWithSource& net_log) { | 2314 const NetLogWithSource& net_log) { |
2314 HostResolverFlags effective_flags = | 2315 HostResolverFlags effective_flags = |
2315 info.host_resolver_flags() | additional_resolver_flags_; | 2316 info.host_resolver_flags() | additional_resolver_flags_; |
2316 AddressFamily effective_address_family = info.address_family(); | 2317 AddressFamily effective_address_family = info.address_family(); |
2317 | 2318 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2351 | 2352 |
2352 void HostResolverImpl::RunLoopbackProbeJob() { | 2353 void HostResolverImpl::RunLoopbackProbeJob() { |
2353 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr(), | 2354 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr(), |
2354 worker_task_runner_.get()); | 2355 worker_task_runner_.get()); |
2355 } | 2356 } |
2356 | 2357 |
2357 void HostResolverImpl::AbortAllInProgressJobs() { | 2358 void HostResolverImpl::AbortAllInProgressJobs() { |
2358 // In Abort, a Request callback could spawn new Jobs with matching keys, so | 2359 // In Abort, a Request callback could spawn new Jobs with matching keys, so |
2359 // first collect and remove all running jobs from |jobs_|. | 2360 // first collect and remove all running jobs from |jobs_|. |
2360 std::vector<std::unique_ptr<Job>> jobs_to_abort; | 2361 std::vector<std::unique_ptr<Job>> jobs_to_abort; |
2361 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { | 2362 for (auto it = jobs_.begin(); it != jobs_.end();) { |
2362 Job* job = it->second; | 2363 Job* job = it->second.get(); |
2363 if (job->is_running()) { | 2364 if (job->is_running()) { |
2364 jobs_to_abort.push_back(base::WrapUnique(job)); | 2365 jobs_to_abort.push_back(std::move(it->second)); |
2365 jobs_.erase(it++); | 2366 jobs_.erase(it++); |
2366 } else { | 2367 } else { |
2367 DCHECK(job->is_queued()); | 2368 DCHECK(job->is_queued()); |
2368 ++it; | 2369 ++it; |
2369 } | 2370 } |
2370 } | 2371 } |
2371 | 2372 |
2372 // Pause the dispatcher so it won't start any new dispatcher jobs while | 2373 // Pause the dispatcher so it won't start any new dispatcher jobs while |
2373 // aborting the old ones. This is needed so that it won't start the second | 2374 // aborting the old ones. This is needed so that it won't start the second |
2374 // DnsTransaction for a job in |jobs_to_abort| if the DnsConfig just became | 2375 // DnsTransaction for a job in |jobs_to_abort| if the DnsConfig just became |
(...skipping 16 matching lines...) Expand all Loading... |
2391 } | 2392 } |
2392 | 2393 |
2393 void HostResolverImpl::AbortDnsTasks() { | 2394 void HostResolverImpl::AbortDnsTasks() { |
2394 // Pause the dispatcher so it won't start any new dispatcher jobs while | 2395 // Pause the dispatcher so it won't start any new dispatcher jobs while |
2395 // aborting the old ones. This is needed so that it won't start the second | 2396 // aborting the old ones. This is needed so that it won't start the second |
2396 // DnsTransaction for a job if the DnsConfig just changed. | 2397 // DnsTransaction for a job if the DnsConfig just changed. |
2397 PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits(); | 2398 PrioritizedDispatcher::Limits limits = dispatcher_->GetLimits(); |
2398 dispatcher_->SetLimits( | 2399 dispatcher_->SetLimits( |
2399 PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0)); | 2400 PrioritizedDispatcher::Limits(limits.reserved_slots.size(), 0)); |
2400 | 2401 |
2401 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) | 2402 for (auto it = jobs_.begin(); it != jobs_.end(); ++it) |
2402 it->second->AbortDnsTask(); | 2403 it->second->AbortDnsTask(); |
2403 dispatcher_->SetLimits(limits); | 2404 dispatcher_->SetLimits(limits); |
2404 } | 2405 } |
2405 | 2406 |
2406 void HostResolverImpl::TryServingAllJobsFromHosts() { | 2407 void HostResolverImpl::TryServingAllJobsFromHosts() { |
2407 if (!HaveDnsConfig()) | 2408 if (!HaveDnsConfig()) |
2408 return; | 2409 return; |
2409 | 2410 |
2410 // TODO(szym): Do not do this if nsswitch.conf instructs not to. | 2411 // TODO(szym): Do not do this if nsswitch.conf instructs not to. |
2411 // http://crbug.com/117655 | 2412 // http://crbug.com/117655 |
2412 | 2413 |
2413 // Life check to bail once |this| is deleted. | 2414 // Life check to bail once |this| is deleted. |
2414 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); | 2415 base::WeakPtr<HostResolverImpl> self = weak_ptr_factory_.GetWeakPtr(); |
2415 | 2416 |
2416 for (JobMap::iterator it = jobs_.begin(); self.get() && it != jobs_.end();) { | 2417 for (auto it = jobs_.begin(); self.get() && it != jobs_.end();) { |
2417 Job* job = it->second; | 2418 Job* job = it->second.get(); |
2418 ++it; | 2419 ++it; |
2419 // This could remove |job| from |jobs_|, but iterator will remain valid. | 2420 // This could remove |job| from |jobs_|, but iterator will remain valid. |
2420 job->ServeFromHosts(); | 2421 job->ServeFromHosts(); |
2421 } | 2422 } |
2422 } | 2423 } |
2423 | 2424 |
2424 void HostResolverImpl::OnIPAddressChanged() { | 2425 void HostResolverImpl::OnIPAddressChanged() { |
2425 resolved_known_ipv6_hostname_ = false; | 2426 resolved_known_ipv6_hostname_ = false; |
2426 last_ipv6_probe_time_ = base::TimeTicks(); | 2427 last_ipv6_probe_time_ = base::TimeTicks(); |
2427 // Abandon all ProbeJobs. | 2428 // Abandon all ProbeJobs. |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2609 if (job_) | 2610 if (job_) |
2610 job_->CancelRequest(this); | 2611 job_->CancelRequest(this); |
2611 } | 2612 } |
2612 | 2613 |
2613 void HostResolverImpl::RequestImpl::ChangeRequestPriority( | 2614 void HostResolverImpl::RequestImpl::ChangeRequestPriority( |
2614 RequestPriority priority) { | 2615 RequestPriority priority) { |
2615 job_->ChangeRequestPriority(this, priority); | 2616 job_->ChangeRequestPriority(this, priority); |
2616 } | 2617 } |
2617 | 2618 |
2618 } // namespace net | 2619 } // namespace net |
OLD | NEW |