| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/base/host_resolver_impl.h" | 5 #include "net/base/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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 base::TimeDelta::FromMinutes(1), | 90 base::TimeDelta::FromMinutes(1), |
| 91 base::TimeDelta::FromSeconds(0)); // Disable caching of failed DNS. | 91 base::TimeDelta::FromSeconds(0)); // Disable caching of failed DNS. |
| 92 | 92 |
| 93 return cache; | 93 return cache; |
| 94 } | 94 } |
| 95 | 95 |
| 96 } // anonymous namespace | 96 } // anonymous namespace |
| 97 | 97 |
| 98 // static | 98 // static |
| 99 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, | 99 HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves, |
| 100 size_t max_retry_attempts, |
| 100 NetLog* net_log) { | 101 NetLog* net_log) { |
| 101 // Maximum of 8 concurrent resolver threads. | 102 // Maximum of 8 concurrent resolver threads. |
| 102 // Some routers (or resolvers) appear to start to provide host-not-found if | 103 // Some routers (or resolvers) appear to start to provide host-not-found if |
| 103 // too many simultaneous resolutions are pending. This number needs to be | 104 // too many simultaneous resolutions are pending. This number needs to be |
| 104 // further optimized, but 8 is what FF currently does. | 105 // further optimized, but 8 is what FF currently does. |
| 105 static const size_t kDefaultMaxJobs = 8u; | 106 static const size_t kDefaultMaxJobs = 8u; |
| 106 | 107 |
| 107 if (max_concurrent_resolves == HostResolver::kDefaultParallelism) | 108 if (max_concurrent_resolves == HostResolver::kDefaultParallelism) |
| 108 max_concurrent_resolves = kDefaultMaxJobs; | 109 max_concurrent_resolves = kDefaultMaxJobs; |
| 109 | 110 |
| 110 HostResolverImpl* resolver = | 111 HostResolverImpl* resolver = |
| 111 new HostResolverImpl(NULL, CreateDefaultCache(), | 112 new HostResolverImpl(NULL, CreateDefaultCache(), max_concurrent_resolves, |
| 112 max_concurrent_resolves, net_log); | 113 max_retry_attempts, net_log); |
| 113 | 114 |
| 114 return resolver; | 115 return resolver; |
| 115 } | 116 } |
| 116 | 117 |
| 117 static int ResolveAddrInfo(HostResolverProc* resolver_proc, | 118 static int ResolveAddrInfo(HostResolverProc* resolver_proc, |
| 118 const std::string& host, | 119 const std::string& host, |
| 119 AddressFamily address_family, | 120 AddressFamily address_family, |
| 120 HostResolverFlags host_resolver_flags, | 121 HostResolverFlags host_resolver_flags, |
| 121 AddressList* out, | 122 AddressList* out, |
| 122 int* os_error) { | 123 int* os_error) { |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 origin_loop_->PostTask( | 431 origin_loop_->PostTask( |
| 431 FROM_HERE, | 432 FROM_HERE, |
| 432 NewRunnableMethod(this, &Job::OnLookupComplete, AddressList(), | 433 NewRunnableMethod(this, &Job::OnLookupComplete, AddressList(), |
| 433 start_time, attempt_number_, ERR_UNEXPECTED, 0)); | 434 start_time, attempt_number_, ERR_UNEXPECTED, 0)); |
| 434 return; | 435 return; |
| 435 } | 436 } |
| 436 // Post a task to check if we get the results within a given time. | 437 // Post a task to check if we get the results within a given time. |
| 437 // OnCheckForComplete has the potential for starting a new attempt on a | 438 // OnCheckForComplete has the potential for starting a new attempt on a |
| 438 // different worker thread if none of our outstanding attempts have | 439 // different worker thread if none of our outstanding attempts have |
| 439 // completed yet. | 440 // completed yet. |
| 440 origin_loop_->PostDelayedTask( | 441 if (attempt_number_ <= resolver_->max_retry_attempts()) { |
| 441 FROM_HERE, | 442 origin_loop_->PostDelayedTask( |
| 442 NewRunnableMethod(this, &Job::OnCheckForComplete), | 443 FROM_HERE, |
| 443 unresponsive_delay_.InMilliseconds()); | 444 NewRunnableMethod(this, &Job::OnCheckForComplete), |
| 445 unresponsive_delay_.InMilliseconds()); |
| 446 } |
| 444 } | 447 } |
| 445 | 448 |
| 446 // Cancels the current job. The Job will be orphaned. Any outstanding resolve | 449 // Cancels the current job. The Job will be orphaned. Any outstanding resolve |
| 447 // attempts running on worker threads will continue running. Only once all the | 450 // attempts running on worker threads will continue running. Only once all the |
| 448 // attempts complete will the final reference to this Job be released. | 451 // attempts complete will the final reference to this Job be released. |
| 449 void Cancel() { | 452 void Cancel() { |
| 450 DCHECK(origin_loop_->BelongsToCurrentThread()); | 453 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 451 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); | 454 net_log_.AddEvent(NetLog::TYPE_CANCELLED, NULL); |
| 452 | 455 |
| 453 HostResolver* resolver = resolver_; | 456 HostResolver* resolver = resolver_; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 origin_loop_->PostTask( | 536 origin_loop_->PostTask( |
| 534 FROM_HERE, | 537 FROM_HERE, |
| 535 NewRunnableMethod(this, &Job::OnLookupComplete, results, start_time, | 538 NewRunnableMethod(this, &Job::OnLookupComplete, results, start_time, |
| 536 attempt_number, error, os_error)); | 539 attempt_number, error, os_error)); |
| 537 } | 540 } |
| 538 | 541 |
| 539 // Callback to see if DoLookup() has finished or not (runs on origin thread). | 542 // Callback to see if DoLookup() has finished or not (runs on origin thread). |
| 540 void OnCheckForComplete() { | 543 void OnCheckForComplete() { |
| 541 DCHECK(origin_loop_->BelongsToCurrentThread()); | 544 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| 542 | 545 |
| 543 if (was_cancelled() || was_completed()) | 546 if (was_completed() || was_cancelled()) |
| 544 return; | 547 return; |
| 545 | 548 |
| 546 DCHECK(resolver_); | 549 DCHECK(resolver_); |
| 547 base::TimeDelta unresponsive_delay = | 550 unresponsive_delay_ *= resolver_->retry_factor(); |
| 548 unresponsive_delay_ * resolver_->retry_factor(); | |
| 549 if (unresponsive_delay >= resolver_->maximum_unresponsive_delay()) | |
| 550 return; | |
| 551 | |
| 552 unresponsive_delay_ = unresponsive_delay; | |
| 553 StartLookupAttempt(); | 551 StartLookupAttempt(); |
| 554 } | 552 } |
| 555 | 553 |
| 556 // Callback for when DoLookup() completes (runs on origin thread). | 554 // Callback for when DoLookup() completes (runs on origin thread). |
| 557 void OnLookupComplete(const AddressList& results, | 555 void OnLookupComplete(const AddressList& results, |
| 558 const base::TimeTicks& start_time, | 556 const base::TimeTicks& start_time, |
| 559 const uint32 attempt_number, | 557 const uint32 attempt_number, |
| 560 int error, | 558 int error, |
| 561 const int os_error) { | 559 const int os_error) { |
| 562 DCHECK(origin_loop_->BelongsToCurrentThread()); | 560 DCHECK(origin_loop_->BelongsToCurrentThread()); |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1004 // The requests which are waiting to be started for this pool. | 1002 // The requests which are waiting to be started for this pool. |
| 1005 PendingRequestsQueue pending_requests_[NUM_PRIORITIES]; | 1003 PendingRequestsQueue pending_requests_[NUM_PRIORITIES]; |
| 1006 }; | 1004 }; |
| 1007 | 1005 |
| 1008 //----------------------------------------------------------------------------- | 1006 //----------------------------------------------------------------------------- |
| 1009 | 1007 |
| 1010 HostResolverImpl::HostResolverImpl( | 1008 HostResolverImpl::HostResolverImpl( |
| 1011 HostResolverProc* resolver_proc, | 1009 HostResolverProc* resolver_proc, |
| 1012 HostCache* cache, | 1010 HostCache* cache, |
| 1013 size_t max_jobs, | 1011 size_t max_jobs, |
| 1012 size_t max_retry_attempts, |
| 1014 NetLog* net_log) | 1013 NetLog* net_log) |
| 1015 : cache_(cache), | 1014 : cache_(cache), |
| 1016 max_jobs_(max_jobs), | 1015 max_jobs_(max_jobs), |
| 1016 max_retry_attempts_(max_retry_attempts), |
| 1017 unresponsive_delay_(base::TimeDelta::FromMilliseconds(6000)), | 1017 unresponsive_delay_(base::TimeDelta::FromMilliseconds(6000)), |
| 1018 retry_factor_(2), | 1018 retry_factor_(2), |
| 1019 maximum_unresponsive_delay_(base::TimeDelta::FromMilliseconds(60000)), | |
| 1020 next_request_id_(0), | 1019 next_request_id_(0), |
| 1021 next_job_id_(0), | 1020 next_job_id_(0), |
| 1022 resolver_proc_(resolver_proc), | 1021 resolver_proc_(resolver_proc), |
| 1023 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), | 1022 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), |
| 1024 shutdown_(false), | 1023 shutdown_(false), |
| 1025 ipv6_probe_monitoring_(false), | 1024 ipv6_probe_monitoring_(false), |
| 1026 additional_resolver_flags_(0), | 1025 additional_resolver_flags_(0), |
| 1027 net_log_(net_log) { | 1026 net_log_(net_log) { |
| 1028 DCHECK_GT(max_jobs, 0u); | 1027 DCHECK_GT(max_jobs, 0u); |
| 1029 | 1028 |
| 1029 // Maximum of 4 retry attempts for host resolution. |
| 1030 static const size_t kDefaultMaxRetryAttempts = 4u; |
| 1031 |
| 1032 if (max_retry_attempts_ == HostResolver::kDefaultRetryAttempts) |
| 1033 max_retry_attempts_ = kDefaultMaxRetryAttempts; |
| 1034 |
| 1030 // It is cumbersome to expose all of the constraints in the constructor, | 1035 // It is cumbersome to expose all of the constraints in the constructor, |
| 1031 // so we choose some defaults, which users can override later. | 1036 // so we choose some defaults, which users can override later. |
| 1032 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); | 1037 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); |
| 1033 | 1038 |
| 1034 #if defined(OS_WIN) | 1039 #if defined(OS_WIN) |
| 1035 EnsureWinsockInit(); | 1040 EnsureWinsockInit(); |
| 1036 #endif | 1041 #endif |
| 1037 #if defined(OS_LINUX) | 1042 #if defined(OS_LINUX) |
| 1038 if (HaveOnlyLoopbackAddresses()) | 1043 if (HaveOnlyLoopbackAddresses()) |
| 1039 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 1044 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 } | 1513 } |
| 1509 | 1514 |
| 1510 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { | 1515 HostResolverImpl::Job* HostResolverImpl::CreateAndStartJob(Request* req) { |
| 1511 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); | 1516 DCHECK(CanCreateJobForPool(*GetPoolForRequest(req))); |
| 1512 Key key = GetEffectiveKeyForRequest(req->info()); | 1517 Key key = GetEffectiveKeyForRequest(req->info()); |
| 1513 | 1518 |
| 1514 req->request_net_log().AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, | 1519 req->request_net_log().AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB, |
| 1515 NULL); | 1520 NULL); |
| 1516 | 1521 |
| 1517 scoped_refptr<Job> job(new Job(next_job_id_++, this, key, | 1522 scoped_refptr<Job> job(new Job(next_job_id_++, this, key, |
| 1518 req->request_net_log(), net_log_)); | 1523 req->request_net_log(), net_log_)); |
| 1519 job->AddRequest(req); | 1524 job->AddRequest(req); |
| 1520 AddOutstandingJob(job); | 1525 AddOutstandingJob(job); |
| 1521 job->Start(); | 1526 job->Start(); |
| 1522 | 1527 |
| 1523 return job.get(); | 1528 return job.get(); |
| 1524 } | 1529 } |
| 1525 | 1530 |
| 1526 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { | 1531 int HostResolverImpl::EnqueueRequest(JobPool* pool, Request* req) { |
| 1527 scoped_ptr<Request> req_evicted_from_queue( | 1532 scoped_ptr<Request> req_evicted_from_queue( |
| 1528 pool->InsertPendingRequest(req)); | 1533 pool->InsertPendingRequest(req)); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | 1584 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; |
| 1580 } else { | 1585 } else { |
| 1581 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | 1586 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; |
| 1582 } | 1587 } |
| 1583 #endif | 1588 #endif |
| 1584 AbortAllInProgressJobs(); | 1589 AbortAllInProgressJobs(); |
| 1585 // |this| may be deleted inside AbortAllInProgressJobs(). | 1590 // |this| may be deleted inside AbortAllInProgressJobs(). |
| 1586 } | 1591 } |
| 1587 | 1592 |
| 1588 } // namespace net | 1593 } // namespace net |
| OLD | NEW |