Chromium Code Reviews| 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 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 | 11 |
| 12 #if defined(OS_WIN) | 12 #if defined(OS_WIN) |
| 13 #include <Winsock2.h> | 13 #include <Winsock2.h> |
| 14 #elif defined(OS_POSIX) | 14 #elif defined(OS_POSIX) |
| 15 #include <netdb.h> | 15 #include <netdb.h> |
| 16 #endif | 16 #endif |
| 17 | 17 |
| 18 #include <cmath> | 18 #include <cmath> |
| 19 #include <utility> | 19 #include <utility> |
| 20 #include <vector> | 20 #include <vector> |
| 21 | 21 |
| 22 #include "base/bind.h" | 22 #include "base/bind.h" |
| 23 #include "base/bind_helpers.h" | 23 #include "base/bind_helpers.h" |
| 24 #include "base/callback.h" | 24 #include "base/callback.h" |
| 25 #include "base/compiler_specific.h" | 25 #include "base/compiler_specific.h" |
| 26 #include "base/debug/debugger.h" | 26 #include "base/debug/debugger.h" |
| 27 #include "base/debug/leak_annotations.h" | |
| 27 #include "base/debug/stack_trace.h" | 28 #include "base/debug/stack_trace.h" |
| 28 #include "base/macros.h" | 29 #include "base/macros.h" |
| 30 #include "base/memory/ptr_util.h" | |
| 29 #include "base/metrics/field_trial.h" | 31 #include "base/metrics/field_trial.h" |
| 30 #include "base/metrics/histogram_macros.h" | 32 #include "base/metrics/histogram_macros.h" |
| 31 #include "base/metrics/sparse_histogram.h" | 33 #include "base/metrics/sparse_histogram.h" |
| 32 #include "base/profiler/scoped_tracker.h" | 34 #include "base/profiler/scoped_tracker.h" |
| 33 #include "base/single_thread_task_runner.h" | 35 #include "base/single_thread_task_runner.h" |
| 34 #include "base/stl_util.h" | 36 #include "base/stl_util.h" |
| 35 #include "base/strings/string_util.h" | 37 #include "base/strings/string_util.h" |
| 36 #include "base/strings/utf_string_conversions.h" | 38 #include "base/strings/utf_string_conversions.h" |
| 37 #include "base/threading/thread_task_runner_handle.h" | 39 #include "base/threading/thread_task_runner_handle.h" |
| 38 #include "base/threading/worker_pool.h" | 40 #include "base/threading/worker_pool.h" |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 // The address list to save result into. | 597 // The address list to save result into. |
| 596 AddressList* addresses_; | 598 AddressList* addresses_; |
| 597 | 599 |
| 598 const base::TimeTicks request_time_; | 600 const base::TimeTicks request_time_; |
| 599 | 601 |
| 600 DISALLOW_COPY_AND_ASSIGN(Request); | 602 DISALLOW_COPY_AND_ASSIGN(Request); |
| 601 }; | 603 }; |
| 602 | 604 |
| 603 //------------------------------------------------------------------------------ | 605 //------------------------------------------------------------------------------ |
| 604 | 606 |
| 605 // Calls HostResolverProc on the WorkerPool. Performs retries if necessary. | 607 // Calls HostResolverProc using a worker task runner. Performs retries if |
| 608 // necessary. | |
| 606 // | 609 // |
| 607 // Whenever we try to resolve the host, we post a delayed task to check if host | 610 // Whenever we try to resolve the host, we post a delayed task to check if host |
| 608 // resolution (OnLookupComplete) is completed or not. If the original attempt | 611 // resolution (OnLookupComplete) is completed or not. If the original attempt |
| 609 // hasn't completed, then we start another attempt for host resolution. We take | 612 // hasn't completed, then we start another attempt for host resolution. We take |
| 610 // the results from the first attempt that finishes and ignore the results from | 613 // the results from the first attempt that finishes and ignore the results from |
| 611 // all other attempts. | 614 // all other attempts. |
| 612 // | 615 // |
| 613 // TODO(szym): Move to separate source file for testing and mocking. | 616 // TODO(szym): Move to separate source file for testing and mocking. |
| 614 // | 617 // |
| 615 class HostResolverImpl::ProcTask | 618 class HostResolverImpl::ProcTask |
| 616 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> { | 619 : public base::RefCountedThreadSafe<HostResolverImpl::ProcTask> { |
| 617 public: | 620 public: |
| 618 typedef base::Callback<void(int net_error, | 621 typedef base::Callback<void(int net_error, |
| 619 const AddressList& addr_list)> Callback; | 622 const AddressList& addr_list)> Callback; |
| 620 | 623 |
| 621 ProcTask(const Key& key, | 624 ProcTask(const Key& key, |
| 622 const ProcTaskParams& params, | 625 const ProcTaskParams& params, |
| 623 const Callback& callback, | 626 const Callback& callback, |
| 627 scoped_refptr<base::TaskRunner> worker_task_runner, | |
| 624 const BoundNetLog& job_net_log) | 628 const BoundNetLog& job_net_log) |
| 625 : key_(key), | 629 : key_(key), |
| 626 params_(params), | 630 params_(params), |
| 627 callback_(callback), | 631 callback_(callback), |
| 628 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 632 worker_task_runner_(std::move(worker_task_runner)), |
| 633 network_task_runner_(base::ThreadTaskRunnerHandle::Get()), | |
| 629 attempt_number_(0), | 634 attempt_number_(0), |
| 630 completed_attempt_number_(0), | 635 completed_attempt_number_(0), |
| 631 completed_attempt_error_(ERR_UNEXPECTED), | 636 completed_attempt_error_(ERR_UNEXPECTED), |
| 632 had_non_speculative_request_(false), | 637 had_non_speculative_request_(false), |
| 633 net_log_(job_net_log) { | 638 net_log_(job_net_log) { |
| 634 if (!params_.resolver_proc.get()) | 639 if (!params_.resolver_proc.get()) |
| 635 params_.resolver_proc = HostResolverProc::GetDefault(); | 640 params_.resolver_proc = HostResolverProc::GetDefault(); |
| 636 // If default is unset, use the system proc. | 641 // If default is unset, use the system proc. |
| 637 if (!params_.resolver_proc.get()) | 642 if (!params_.resolver_proc.get()) |
| 638 params_.resolver_proc = new SystemHostResolverProc(); | 643 params_.resolver_proc = new SystemHostResolverProc(); |
| 639 } | 644 } |
| 640 | 645 |
| 641 void Start() { | 646 void Start() { |
| 642 DCHECK(task_runner_->BelongsToCurrentThread()); | 647 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 643 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); | 648 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
| 644 StartLookupAttempt(); | 649 StartLookupAttempt(); |
| 645 } | 650 } |
| 646 | 651 |
| 647 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve | 652 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve |
| 648 // attempts running on worker threads will continue running. Only once all the | 653 // attempts running on worker thread will continue running. Only once all the |
| 649 // attempts complete will the final reference to this ProcTask be released. | 654 // attempts complete will the final reference to this ProcTask be released. |
| 650 void Cancel() { | 655 void Cancel() { |
| 651 DCHECK(task_runner_->BelongsToCurrentThread()); | 656 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 652 | 657 |
| 653 if (was_canceled() || was_completed()) | 658 if (was_canceled() || was_completed()) |
| 654 return; | 659 return; |
| 655 | 660 |
| 656 callback_.Reset(); | 661 callback_.Reset(); |
| 657 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); | 662 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
| 658 } | 663 } |
| 659 | 664 |
| 660 void set_had_non_speculative_request() { | 665 void set_had_non_speculative_request() { |
| 661 DCHECK(task_runner_->BelongsToCurrentThread()); | 666 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 662 had_non_speculative_request_ = true; | 667 had_non_speculative_request_ = true; |
| 663 } | 668 } |
| 664 | 669 |
| 665 bool was_canceled() const { | 670 bool was_canceled() const { |
| 666 DCHECK(task_runner_->BelongsToCurrentThread()); | 671 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 667 return callback_.is_null(); | 672 return callback_.is_null(); |
| 668 } | 673 } |
| 669 | 674 |
| 670 bool was_completed() const { | 675 bool was_completed() const { |
| 671 DCHECK(task_runner_->BelongsToCurrentThread()); | 676 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 672 return completed_attempt_number_ > 0; | 677 return completed_attempt_number_ > 0; |
| 673 } | 678 } |
| 674 | 679 |
| 675 private: | 680 private: |
| 676 friend class base::RefCountedThreadSafe<ProcTask>; | 681 friend class base::RefCountedThreadSafe<ProcTask>; |
| 677 ~ProcTask() {} | 682 ~ProcTask() {} |
| 678 | 683 |
| 679 void StartLookupAttempt() { | 684 void StartLookupAttempt() { |
| 680 DCHECK(task_runner_->BelongsToCurrentThread()); | 685 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 681 base::TimeTicks start_time = base::TimeTicks::Now(); | 686 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 682 ++attempt_number_; | 687 ++attempt_number_; |
| 683 // Dispatch the lookup attempt to a worker thread. | 688 // Dispatch the lookup attempt to a worker thread. |
| 684 if (!base::WorkerPool::PostTask( | 689 if (!worker_task_runner_->PostTask( |
| 685 FROM_HERE, | 690 FROM_HERE, base::Bind(&ProcTask::DoLookup, this, start_time, |
| 686 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), | 691 attempt_number_))) { |
| 687 true)) { | |
| 688 NOTREACHED(); | 692 NOTREACHED(); |
| 689 | 693 |
| 690 // Since we could be running within Resolve() right now, we can't just | 694 // Since this method may have been called from Resolve(), can't just call |
| 691 // call OnLookupComplete(). Instead we must wait until Resolve() has | 695 // OnLookupComplete(). Instead, must wait until Resolve() has returned |
| 692 // returned (IO_PENDING). | 696 // (IO_PENDING). |
| 693 task_runner_->PostTask(FROM_HERE, | 697 network_task_runner_->PostTask( |
| 694 base::Bind(&ProcTask::OnLookupComplete, | 698 FROM_HERE, |
| 695 this, | 699 base::Bind(&ProcTask::OnLookupComplete, this, AddressList(), |
| 696 AddressList(), | 700 start_time, attempt_number_, ERR_UNEXPECTED, 0)); |
| 697 start_time, | |
| 698 attempt_number_, | |
| 699 ERR_UNEXPECTED, | |
| 700 0)); | |
| 701 return; | 701 return; |
| 702 } | 702 } |
| 703 | 703 |
| 704 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, | 704 net_log_.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, |
| 705 NetLog::IntCallback("attempt_number", attempt_number_)); | 705 NetLog::IntCallback("attempt_number", attempt_number_)); |
| 706 | 706 |
| 707 // If we don't get the results within a given time, RetryIfNotComplete | 707 // If the results aren't received within a given time, RetryIfNotComplete |
| 708 // will start a new attempt on a different worker thread if none of our | 708 // will start a new attempt if none of the outstanding attempts have |
| 709 // outstanding attempts have completed yet. | 709 // completed yet. |
| 710 if (attempt_number_ <= params_.max_retry_attempts) { | 710 if (attempt_number_ <= params_.max_retry_attempts) { |
| 711 task_runner_->PostDelayedTask( | 711 network_task_runner_->PostDelayedTask( |
| 712 FROM_HERE, | 712 FROM_HERE, base::Bind(&ProcTask::RetryIfNotComplete, this), |
| 713 base::Bind(&ProcTask::RetryIfNotComplete, this), | |
| 714 params_.unresponsive_delay); | 713 params_.unresponsive_delay); |
| 715 } | 714 } |
| 716 } | 715 } |
| 717 | 716 |
| 718 // WARNING: This code runs inside a worker pool. The shutdown code cannot | 717 // WARNING: In production, this code runs on a worker pool. The shutdown code |
| 719 // wait for it to finish, so we must be very careful here about using other | 718 // cannot wait for it to finish, so this code must ve very careful about using |
|
eroman
2016/06/01 01:47:21
ve --> be
mmenke
2016/06/01 21:28:47
Done.
| |
| 720 // objects (like MessageLoops, Singletons, etc). During shutdown these objects | 719 // other objects (like MessageLoops, Singletons, etc). During shutdown these |
| 721 // may no longer exist. Multiple DoLookups() could be running in parallel, so | 720 // objects may no longer exist. Multiple DoLookups() could be running in |
| 722 // any state inside of |this| must not mutate . | 721 // parallel, so any state inside of |this| must not mutate . |
| 723 void DoLookup(const base::TimeTicks& start_time, | 722 void DoLookup(const base::TimeTicks& start_time, |
| 724 const uint32_t attempt_number) { | 723 const uint32_t attempt_number) { |
| 725 AddressList results; | 724 AddressList results; |
| 726 int os_error = 0; | 725 int os_error = 0; |
| 727 // Running on the worker thread | 726 // Running on a worker task runner. |
| 728 int error = params_.resolver_proc->Resolve(key_.hostname, | 727 int error = params_.resolver_proc->Resolve(key_.hostname, |
| 729 key_.address_family, | 728 key_.address_family, |
| 730 key_.host_resolver_flags, | 729 key_.host_resolver_flags, |
| 731 &results, | 730 &results, |
| 732 &os_error); | 731 &os_error); |
| 733 | 732 |
| 734 // Fail the resolution if the result contains 127.0.53.53. See the comment | 733 // Fail the resolution if the result contains 127.0.53.53. See the comment |
| 735 // block of kIcanNameCollisionIp for details on why. | 734 // block of kIcanNameCollisionIp for details on why. |
| 736 for (const auto& it : results) { | 735 for (const auto& it : results) { |
| 737 const IPAddress& cur = it.address(); | 736 const IPAddress& cur = it.address(); |
| 738 if (cur.IsIPv4() && IPAddressStartsWith(cur, kIcanNameCollisionIp)) { | 737 if (cur.IsIPv4() && IPAddressStartsWith(cur, kIcanNameCollisionIp)) { |
| 739 error = ERR_ICANN_NAME_COLLISION; | 738 error = ERR_ICANN_NAME_COLLISION; |
| 740 break; | 739 break; |
| 741 } | 740 } |
| 742 } | 741 } |
| 743 | 742 |
| 744 task_runner_->PostTask(FROM_HERE, | 743 network_task_runner_->PostTask( |
| 745 base::Bind(&ProcTask::OnLookupComplete, | 744 FROM_HERE, base::Bind(&ProcTask::OnLookupComplete, this, results, |
| 746 this, | 745 start_time, attempt_number, error, os_error)); |
| 747 results, | |
| 748 start_time, | |
| 749 attempt_number, | |
| 750 error, | |
| 751 os_error)); | |
| 752 } | 746 } |
| 753 | 747 |
| 754 // Makes next attempt if DoLookup() has not finished (runs on task runner | 748 // Makes next attempt if DoLookup() has not finished. |
| 755 // thread). | |
| 756 void RetryIfNotComplete() { | 749 void RetryIfNotComplete() { |
| 757 DCHECK(task_runner_->BelongsToCurrentThread()); | 750 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 758 | 751 |
| 759 if (was_completed() || was_canceled()) | 752 if (was_completed() || was_canceled()) |
| 760 return; | 753 return; |
| 761 | 754 |
| 762 params_.unresponsive_delay *= params_.retry_factor; | 755 params_.unresponsive_delay *= params_.retry_factor; |
| 763 StartLookupAttempt(); | 756 StartLookupAttempt(); |
| 764 } | 757 } |
| 765 | 758 |
| 766 // Callback for when DoLookup() completes (runs on task runner thread). | 759 // Callback for when DoLookup() completes (runs on task runner thread). |
| 767 void OnLookupComplete(const AddressList& results, | 760 void OnLookupComplete(const AddressList& results, |
| 768 const base::TimeTicks& start_time, | 761 const base::TimeTicks& start_time, |
| 769 const uint32_t attempt_number, | 762 const uint32_t attempt_number, |
| 770 int error, | 763 int error, |
| 771 const int os_error) { | 764 const int os_error) { |
| 772 TRACE_EVENT0("net", "ProcTask::OnLookupComplete"); | 765 TRACE_EVENT0("net", "ProcTask::OnLookupComplete"); |
| 773 DCHECK(task_runner_->BelongsToCurrentThread()); | 766 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 774 // If results are empty, we should return an error. | 767 // If results are empty, we should return an error. |
| 775 bool empty_list_on_ok = (error == OK && results.empty()); | 768 bool empty_list_on_ok = (error == OK && results.empty()); |
| 776 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); | 769 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); |
| 777 if (empty_list_on_ok) | 770 if (empty_list_on_ok) |
| 778 error = ERR_NAME_NOT_RESOLVED; | 771 error = ERR_NAME_NOT_RESOLVED; |
| 779 | 772 |
| 780 bool was_retry_attempt = attempt_number > 1; | 773 bool was_retry_attempt = attempt_number > 1; |
| 781 | 774 |
| 782 // Ideally the following code would be part of host_resolver_proc.cc, | 775 // Ideally the following code would be part of host_resolver_proc.cc, |
| 783 // however it isn't safe to call NetworkChangeNotifier from worker threads. | 776 // however it isn't safe to call NetworkChangeNotifier from worker threads. |
| 784 // So we do it here on the IO thread instead. | 777 // So do it here on the IO thread instead. |
| 785 if (error != OK && NetworkChangeNotifier::IsOffline()) | 778 if (error != OK && NetworkChangeNotifier::IsOffline()) |
| 786 error = ERR_INTERNET_DISCONNECTED; | 779 error = ERR_INTERNET_DISCONNECTED; |
| 787 | 780 |
| 788 // If this is the first attempt that is finishing later, then record data | 781 // If this is the first attempt that is finishing later, then record data |
| 789 // for the first attempt. Won't contaminate with retry attempt's data. | 782 // for the first attempt. Won't contaminate with retry attempt's data. |
| 790 if (!was_retry_attempt) | 783 if (!was_retry_attempt) |
| 791 RecordPerformanceHistograms(start_time, error, os_error); | 784 RecordPerformanceHistograms(start_time, error, os_error); |
| 792 | 785 |
| 793 RecordAttemptHistograms(start_time, attempt_number, error, os_error); | 786 RecordAttemptHistograms(start_time, attempt_number, error, os_error); |
| 794 | 787 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 } | 822 } |
| 830 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, | 823 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, |
| 831 net_log_callback); | 824 net_log_callback); |
| 832 | 825 |
| 833 callback_.Run(error, results_); | 826 callback_.Run(error, results_); |
| 834 } | 827 } |
| 835 | 828 |
| 836 void RecordPerformanceHistograms(const base::TimeTicks& start_time, | 829 void RecordPerformanceHistograms(const base::TimeTicks& start_time, |
| 837 const int error, | 830 const int error, |
| 838 const int os_error) const { | 831 const int os_error) const { |
| 839 DCHECK(task_runner_->BelongsToCurrentThread()); | 832 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 840 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. | 833 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. |
| 841 RESOLVE_SUCCESS, | 834 RESOLVE_SUCCESS, |
| 842 RESOLVE_FAIL, | 835 RESOLVE_FAIL, |
| 843 RESOLVE_SPECULATIVE_SUCCESS, | 836 RESOLVE_SPECULATIVE_SUCCESS, |
| 844 RESOLVE_SPECULATIVE_FAIL, | 837 RESOLVE_SPECULATIVE_FAIL, |
| 845 RESOLVE_MAX, // Bounding value. | 838 RESOLVE_MAX, // Bounding value. |
| 846 }; | 839 }; |
| 847 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. | 840 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. |
| 848 | 841 |
| 849 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 842 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 896 } | 889 } |
| 897 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. | 890 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. |
| 898 | 891 |
| 899 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); | 892 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); |
| 900 } | 893 } |
| 901 | 894 |
| 902 void RecordAttemptHistograms(const base::TimeTicks& start_time, | 895 void RecordAttemptHistograms(const base::TimeTicks& start_time, |
| 903 const uint32_t attempt_number, | 896 const uint32_t attempt_number, |
| 904 const int error, | 897 const int error, |
| 905 const int os_error) const { | 898 const int os_error) const { |
| 906 DCHECK(task_runner_->BelongsToCurrentThread()); | 899 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 907 bool first_attempt_to_complete = | 900 bool first_attempt_to_complete = |
| 908 completed_attempt_number_ == attempt_number; | 901 completed_attempt_number_ == attempt_number; |
| 909 bool is_first_attempt = (attempt_number == 1); | 902 bool is_first_attempt = (attempt_number == 1); |
| 910 | 903 |
| 911 if (first_attempt_to_complete) { | 904 if (first_attempt_to_complete) { |
| 912 // If this was first attempt to complete, then record the resolution | 905 // If this was first attempt to complete, then record the resolution |
| 913 // status of the attempt. | 906 // status of the attempt. |
| 914 if (completed_attempt_error_ == OK) { | 907 if (completed_attempt_error_ == OK) { |
| 915 UMA_HISTOGRAM_ENUMERATION( | 908 UMA_HISTOGRAM_ENUMERATION( |
| 916 "DNS.AttemptFirstSuccess", attempt_number, 100); | 909 "DNS.AttemptFirstSuccess", attempt_number, 100); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 | 948 |
| 956 // Holds an owning reference to the HostResolverProc that we are going to use. | 949 // Holds an owning reference to the HostResolverProc that we are going to use. |
| 957 // This may not be the current resolver procedure by the time we call | 950 // This may not be the current resolver procedure by the time we call |
| 958 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning | 951 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning |
| 959 // reference ensures that it remains valid until we are done. | 952 // reference ensures that it remains valid until we are done. |
| 960 ProcTaskParams params_; | 953 ProcTaskParams params_; |
| 961 | 954 |
| 962 // The listener to the results of this ProcTask. | 955 // The listener to the results of this ProcTask. |
| 963 Callback callback_; | 956 Callback callback_; |
| 964 | 957 |
| 965 // Used to post ourselves onto the task runner thread. | 958 // Task runner for the call to the HostResolverProc. |
| 966 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 959 scoped_refptr<base::TaskRunner> worker_task_runner_; |
| 960 | |
| 961 // Used to post events onto the network thread. | |
| 962 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; | |
| 967 | 963 |
| 968 // Keeps track of the number of attempts we have made so far to resolve the | 964 // Keeps track of the number of attempts we have made so far to resolve the |
| 969 // host. Whenever we start an attempt to resolve the host, we increase this | 965 // host. Whenever we start an attempt to resolve the host, we increase this |
| 970 // number. | 966 // number. |
| 971 uint32_t attempt_number_; | 967 uint32_t attempt_number_; |
| 972 | 968 |
| 973 // The index of the attempt which finished first (or 0 if the job is still in | 969 // The index of the attempt which finished first (or 0 if the job is still in |
| 974 // progress). | 970 // progress). |
| 975 uint32_t completed_attempt_number_; | 971 uint32_t completed_attempt_number_; |
| 976 | 972 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 988 | 984 |
| 989 AddressList results_; | 985 AddressList results_; |
| 990 | 986 |
| 991 BoundNetLog net_log_; | 987 BoundNetLog net_log_; |
| 992 | 988 |
| 993 DISALLOW_COPY_AND_ASSIGN(ProcTask); | 989 DISALLOW_COPY_AND_ASSIGN(ProcTask); |
| 994 }; | 990 }; |
| 995 | 991 |
| 996 //----------------------------------------------------------------------------- | 992 //----------------------------------------------------------------------------- |
| 997 | 993 |
| 998 // Wraps a call to HaveOnlyLoopbackAddresses to be executed on the WorkerPool as | 994 // Wraps a call to HaveOnlyLoopbackAddresses to be executed on a |
| 999 // it takes 40-100ms and should not block initialization. | 995 // |worker_task_runner|, as it takes 40-100ms and should not block |
| 996 // initialization. | |
| 1000 class HostResolverImpl::LoopbackProbeJob { | 997 class HostResolverImpl::LoopbackProbeJob { |
| 1001 public: | 998 public: |
| 1002 explicit LoopbackProbeJob(const base::WeakPtr<HostResolverImpl>& resolver) | 999 LoopbackProbeJob(const base::WeakPtr<HostResolverImpl>& resolver, |
| 1003 : resolver_(resolver), | 1000 base::TaskRunner* worker_task_runner) |
| 1004 result_(false) { | 1001 : resolver_(resolver), result_(false) { |
| 1005 DCHECK(resolver.get()); | 1002 DCHECK(resolver.get()); |
| 1006 const bool kIsSlow = true; | 1003 |
| 1007 base::WorkerPool::PostTaskAndReply( | 1004 // |worker_task_runner| may posts tasks to the WorkerPool, so need this to |
| 1005 // avoid reporting worker pool leaks in tests. The WorkerPool doesn't have a | |
| 1006 // flushing API, so can't do anything about them, other than using another | |
| 1007 // task runner. | |
| 1008 // http://crbug.com/248513 | |
| 1009 ANNOTATE_SCOPED_MEMORY_LEAK; | |
| 1010 | |
| 1011 worker_task_runner->PostTaskAndReply( | |
| 1008 FROM_HERE, | 1012 FROM_HERE, |
| 1009 base::Bind(&LoopbackProbeJob::DoProbe, base::Unretained(this)), | 1013 base::Bind(&LoopbackProbeJob::DoProbe, base::Unretained(this)), |
| 1010 base::Bind(&LoopbackProbeJob::OnProbeComplete, base::Owned(this)), | 1014 base::Bind(&LoopbackProbeJob::OnProbeComplete, base::Owned(this))); |
| 1011 kIsSlow); | |
| 1012 } | 1015 } |
| 1013 | 1016 |
| 1014 virtual ~LoopbackProbeJob() {} | 1017 virtual ~LoopbackProbeJob() {} |
| 1015 | 1018 |
| 1016 private: | 1019 private: |
| 1017 // Runs on worker thread. | 1020 // Runs on worker thread. |
| 1018 void DoProbe() { | 1021 void DoProbe() { |
| 1019 result_ = HaveOnlyLoopbackAddresses(); | 1022 result_ = HaveOnlyLoopbackAddresses(); |
| 1020 } | 1023 } |
| 1021 | 1024 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1263 | 1266 |
| 1264 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. | 1267 // Aggregates all Requests for the same Key. Dispatched via PriorityDispatch. |
| 1265 class HostResolverImpl::Job : public PrioritizedDispatcher::Job, | 1268 class HostResolverImpl::Job : public PrioritizedDispatcher::Job, |
| 1266 public HostResolverImpl::DnsTask::Delegate { | 1269 public HostResolverImpl::DnsTask::Delegate { |
| 1267 public: | 1270 public: |
| 1268 // Creates new job for |key| where |request_net_log| is bound to the | 1271 // Creates new job for |key| where |request_net_log| is bound to the |
| 1269 // request that spawned it. | 1272 // request that spawned it. |
| 1270 Job(const base::WeakPtr<HostResolverImpl>& resolver, | 1273 Job(const base::WeakPtr<HostResolverImpl>& resolver, |
| 1271 const Key& key, | 1274 const Key& key, |
| 1272 RequestPriority priority, | 1275 RequestPriority priority, |
| 1276 scoped_refptr<base::TaskRunner> worker_task_runner, | |
| 1273 const BoundNetLog& source_net_log) | 1277 const BoundNetLog& source_net_log) |
| 1274 : resolver_(resolver), | 1278 : resolver_(resolver), |
| 1275 key_(key), | 1279 key_(key), |
| 1276 priority_tracker_(priority), | 1280 priority_tracker_(priority), |
| 1281 worker_task_runner_(std::move(worker_task_runner)), | |
| 1277 had_non_speculative_request_(false), | 1282 had_non_speculative_request_(false), |
| 1278 had_dns_config_(false), | 1283 had_dns_config_(false), |
| 1279 num_occupied_job_slots_(0), | 1284 num_occupied_job_slots_(0), |
| 1280 dns_task_error_(OK), | 1285 dns_task_error_(OK), |
| 1281 creation_time_(base::TimeTicks::Now()), | 1286 creation_time_(base::TimeTicks::Now()), |
| 1282 priority_change_time_(creation_time_), | 1287 priority_change_time_(creation_time_), |
| 1283 net_log_(BoundNetLog::Make(source_net_log.net_log(), | 1288 net_log_(BoundNetLog::Make(source_net_log.net_log(), |
| 1284 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { | 1289 NetLog::SOURCE_HOST_RESOLVER_IMPL_JOB)) { |
| 1285 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); | 1290 source_net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_CREATE_JOB); |
| 1286 | 1291 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1542 StartProcTask(); | 1547 StartProcTask(); |
| 1543 } | 1548 } |
| 1544 } | 1549 } |
| 1545 | 1550 |
| 1546 // TODO(szym): Since DnsTransaction does not consume threads, we can increase | 1551 // TODO(szym): Since DnsTransaction does not consume threads, we can increase |
| 1547 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool | 1552 // the limits on |dispatcher_|. But in order to keep the number of WorkerPool |
| 1548 // threads low, we will need to use an "inner" PrioritizedDispatcher with | 1553 // threads low, we will need to use an "inner" PrioritizedDispatcher with |
| 1549 // tighter limits. | 1554 // tighter limits. |
| 1550 void StartProcTask() { | 1555 void StartProcTask() { |
| 1551 DCHECK(!is_dns_running()); | 1556 DCHECK(!is_dns_running()); |
| 1552 proc_task_ = new ProcTask( | 1557 proc_task_ = |
| 1553 key_, | 1558 new ProcTask(key_, resolver_->proc_params_, |
| 1554 resolver_->proc_params_, | 1559 base::Bind(&Job::OnProcTaskComplete, |
| 1555 base::Bind(&Job::OnProcTaskComplete, base::Unretained(this), | 1560 base::Unretained(this), base::TimeTicks::Now()), |
| 1556 base::TimeTicks::Now()), | 1561 worker_task_runner_, net_log_); |
| 1557 net_log_); | |
| 1558 | 1562 |
| 1559 if (had_non_speculative_request_) | 1563 if (had_non_speculative_request_) |
| 1560 proc_task_->set_had_non_speculative_request(); | 1564 proc_task_->set_had_non_speculative_request(); |
| 1561 // Start() could be called from within Resolve(), hence it must NOT directly | 1565 // Start() could be called from within Resolve(), hence it must NOT directly |
| 1562 // call OnProcTaskComplete, for example, on synchronous failure. | 1566 // call OnProcTaskComplete, for example, on synchronous failure. |
| 1563 proc_task_->Start(); | 1567 proc_task_->Start(); |
| 1564 } | 1568 } |
| 1565 | 1569 |
| 1566 // Called by ProcTask when it completes. | 1570 // Called by ProcTask when it completes. |
| 1567 void OnProcTaskComplete(base::TimeTicks start_time, | 1571 void OnProcTaskComplete(base::TimeTicks start_time, |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1809 return proc_task_.get() != NULL; | 1813 return proc_task_.get() != NULL; |
| 1810 } | 1814 } |
| 1811 | 1815 |
| 1812 base::WeakPtr<HostResolverImpl> resolver_; | 1816 base::WeakPtr<HostResolverImpl> resolver_; |
| 1813 | 1817 |
| 1814 Key key_; | 1818 Key key_; |
| 1815 | 1819 |
| 1816 // Tracks the highest priority across |requests_|. | 1820 // Tracks the highest priority across |requests_|. |
| 1817 PriorityTracker priority_tracker_; | 1821 PriorityTracker priority_tracker_; |
| 1818 | 1822 |
| 1823 // Task runner where the HostResolverProc is invoked. | |
| 1824 scoped_refptr<base::TaskRunner> worker_task_runner_; | |
| 1825 | |
| 1819 bool had_non_speculative_request_; | 1826 bool had_non_speculative_request_; |
| 1820 | 1827 |
| 1821 // Distinguishes measurements taken while DnsClient was fully configured. | 1828 // Distinguishes measurements taken while DnsClient was fully configured. |
| 1822 bool had_dns_config_; | 1829 bool had_dns_config_; |
| 1823 | 1830 |
| 1824 // Number of slots occupied by this Job in resolver's PrioritizedDispatcher. | 1831 // Number of slots occupied by this Job in resolver's PrioritizedDispatcher. |
| 1825 unsigned num_occupied_job_slots_; | 1832 unsigned num_occupied_job_slots_; |
| 1826 | 1833 |
| 1827 // Result of DnsTask. | 1834 // Result of DnsTask. |
| 1828 int dns_task_error_; | 1835 int dns_task_error_; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1860 if (max_retry_attempts == HostResolver::kDefaultRetryAttempts) | 1867 if (max_retry_attempts == HostResolver::kDefaultRetryAttempts) |
| 1861 max_retry_attempts = kDefaultMaxRetryAttempts; | 1868 max_retry_attempts = kDefaultMaxRetryAttempts; |
| 1862 } | 1869 } |
| 1863 | 1870 |
| 1864 HostResolverImpl::ProcTaskParams::ProcTaskParams(const ProcTaskParams& other) = | 1871 HostResolverImpl::ProcTaskParams::ProcTaskParams(const ProcTaskParams& other) = |
| 1865 default; | 1872 default; |
| 1866 | 1873 |
| 1867 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {} | 1874 HostResolverImpl::ProcTaskParams::~ProcTaskParams() {} |
| 1868 | 1875 |
| 1869 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) | 1876 HostResolverImpl::HostResolverImpl(const Options& options, NetLog* net_log) |
| 1870 : max_queued_jobs_(0), | 1877 : HostResolverImpl( |
| 1871 proc_params_(NULL, options.max_retry_attempts), | 1878 options, |
| 1872 net_log_(net_log), | 1879 net_log, |
| 1873 received_dns_config_(false), | 1880 base::WorkerPool::GetTaskRunner(true /* task_is_slow */)) {} |
| 1874 num_dns_failures_(0), | |
| 1875 use_local_ipv6_(false), | |
| 1876 last_ipv6_probe_result_(true), | |
| 1877 resolved_known_ipv6_hostname_(false), | |
| 1878 additional_resolver_flags_(0), | |
| 1879 fallback_to_proctask_(true), | |
| 1880 weak_ptr_factory_(this), | |
| 1881 probe_weak_ptr_factory_(this) { | |
| 1882 if (options.enable_caching) | |
| 1883 cache_ = HostCache::CreateDefaultCache(); | |
| 1884 | |
| 1885 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits(); | |
|
eroman
2016/06/01 01:47:21
This would be easier to review if it had not moved
| |
| 1886 dispatcher_.reset(new PrioritizedDispatcher(job_limits)); | |
| 1887 max_queued_jobs_ = job_limits.total_jobs * 100u; | |
| 1888 | |
| 1889 DCHECK_GE(dispatcher_->num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); | |
| 1890 | |
| 1891 #if defined(OS_WIN) | |
| 1892 EnsureWinsockInit(); | |
| 1893 #endif | |
| 1894 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 1895 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr()); | |
| 1896 #endif | |
| 1897 NetworkChangeNotifier::AddIPAddressObserver(this); | |
| 1898 NetworkChangeNotifier::AddConnectionTypeObserver(this); | |
| 1899 NetworkChangeNotifier::AddDNSObserver(this); | |
| 1900 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \ | |
| 1901 !defined(OS_ANDROID) | |
| 1902 EnsureDnsReloaderInit(); | |
| 1903 #endif | |
| 1904 | |
| 1905 OnConnectionTypeChanged(NetworkChangeNotifier::GetConnectionType()); | |
| 1906 | |
| 1907 { | |
| 1908 DnsConfig dns_config; | |
| 1909 NetworkChangeNotifier::GetDnsConfig(&dns_config); | |
| 1910 received_dns_config_ = dns_config.IsValid(); | |
| 1911 // Conservatively assume local IPv6 is needed when DnsConfig is not valid. | |
| 1912 use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6; | |
| 1913 } | |
| 1914 | |
| 1915 fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial(); | |
| 1916 } | |
| 1917 | 1881 |
| 1918 HostResolverImpl::~HostResolverImpl() { | 1882 HostResolverImpl::~HostResolverImpl() { |
| 1919 // Prevent the dispatcher from starting new jobs. | 1883 // Prevent the dispatcher from starting new jobs. |
| 1920 dispatcher_->SetLimitsToZero(); | 1884 dispatcher_->SetLimitsToZero(); |
| 1921 // It's now safe for Jobs to call KillDsnTask on destruction, because | 1885 // It's now safe for Jobs to call KillDsnTask on destruction, because |
| 1922 // OnJobComplete will not start any new jobs. | 1886 // OnJobComplete will not start any new jobs. |
| 1923 STLDeleteValues(&jobs_); | 1887 STLDeleteValues(&jobs_); |
| 1924 | 1888 |
| 1925 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 1889 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 1926 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); | 1890 NetworkChangeNotifier::RemoveConnectionTypeObserver(this); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1965 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); | 1929 RecordTotalTime(HaveDnsConfig(), info.is_speculative(), base::TimeDelta()); |
| 1966 return rv; | 1930 return rv; |
| 1967 } | 1931 } |
| 1968 | 1932 |
| 1969 // Next we need to attach our request to a "job". This job is responsible for | 1933 // Next we need to attach our request to a "job". This job is responsible for |
| 1970 // calling "getaddrinfo(hostname)" on a worker thread. | 1934 // calling "getaddrinfo(hostname)" on a worker thread. |
| 1971 | 1935 |
| 1972 JobMap::iterator jobit = jobs_.find(key); | 1936 JobMap::iterator jobit = jobs_.find(key); |
| 1973 Job* job; | 1937 Job* job; |
| 1974 if (jobit == jobs_.end()) { | 1938 if (jobit == jobs_.end()) { |
| 1975 job = | 1939 job = new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, |
| 1976 new Job(weak_ptr_factory_.GetWeakPtr(), key, priority, source_net_log); | 1940 worker_task_runner_, source_net_log); |
| 1977 job->Schedule(false); | 1941 job->Schedule(false); |
| 1978 | 1942 |
| 1979 // Check for queue overflow. | 1943 // Check for queue overflow. |
| 1980 if (dispatcher_->num_queued_jobs() > max_queued_jobs_) { | 1944 if (dispatcher_->num_queued_jobs() > max_queued_jobs_) { |
| 1981 Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest()); | 1945 Job* evicted = static_cast<Job*>(dispatcher_->EvictOldestLowest()); |
| 1982 DCHECK(evicted); | 1946 DCHECK(evicted); |
| 1983 evicted->OnEvicted(); // Deletes |evicted|. | 1947 evicted->OnEvicted(); // Deletes |evicted|. |
| 1984 if (evicted == job) { | 1948 if (evicted == job) { |
| 1985 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; | 1949 rv = ERR_HOST_RESOLVER_QUEUE_TOO_LARGE; |
| 1986 LogFinishRequest(source_net_log, info, rv); | 1950 LogFinishRequest(source_net_log, info, rv); |
| 1987 return rv; | 1951 return rv; |
| 1988 } | 1952 } |
| 1989 } | 1953 } |
| 1990 jobs_.insert(jobit, std::make_pair(key, job)); | 1954 jobs_.insert(jobit, std::make_pair(key, job)); |
| 1991 } else { | 1955 } else { |
| 1992 job = jobit->second; | 1956 job = jobit->second; |
| 1993 } | 1957 } |
| 1994 | 1958 |
| 1995 // Can't complete synchronously. Create and attach request. | 1959 // Can't complete synchronously. Create and attach request. |
| 1996 std::unique_ptr<Request> req( | 1960 std::unique_ptr<Request> req( |
| 1997 new Request(source_net_log, info, priority, callback, addresses)); | 1961 new Request(source_net_log, info, priority, callback, addresses)); |
| 1998 if (out_req) | 1962 if (out_req) |
| 1999 *out_req = reinterpret_cast<RequestHandle>(req.get()); | 1963 *out_req = reinterpret_cast<RequestHandle>(req.get()); |
| 2000 | 1964 |
| 2001 job->AddRequest(std::move(req)); | 1965 job->AddRequest(std::move(req)); |
| 2002 // Completion happens during Job::CompleteRequests(). | 1966 // Completion happens during Job::CompleteRequests(). |
| 2003 return ERR_IO_PENDING; | 1967 return ERR_IO_PENDING; |
| 2004 } | 1968 } |
| 2005 | 1969 |
| 1970 HostResolverImpl::HostResolverImpl( | |
| 1971 const Options& options, | |
| 1972 NetLog* net_log, | |
| 1973 scoped_refptr<base::TaskRunner> worker_task_runner) | |
| 1974 : max_queued_jobs_(0), | |
| 1975 proc_params_(NULL, options.max_retry_attempts), | |
| 1976 net_log_(net_log), | |
| 1977 received_dns_config_(false), | |
| 1978 num_dns_failures_(0), | |
| 1979 use_local_ipv6_(false), | |
| 1980 last_ipv6_probe_result_(true), | |
| 1981 resolved_known_ipv6_hostname_(false), | |
| 1982 additional_resolver_flags_(0), | |
| 1983 fallback_to_proctask_(true), | |
| 1984 worker_task_runner_(std::move(worker_task_runner)), | |
| 1985 weak_ptr_factory_(this), | |
| 1986 probe_weak_ptr_factory_(this) { | |
| 1987 if (options.enable_caching) | |
| 1988 cache_ = HostCache::CreateDefaultCache(); | |
| 1989 | |
| 1990 PrioritizedDispatcher::Limits job_limits = options.GetDispatcherLimits(); | |
| 1991 dispatcher_.reset(new PrioritizedDispatcher(job_limits)); | |
| 1992 max_queued_jobs_ = job_limits.total_jobs * 100u; | |
| 1993 | |
| 1994 DCHECK_GE(dispatcher_->num_priorities(), static_cast<size_t>(NUM_PRIORITIES)); | |
| 1995 | |
| 1996 #if defined(OS_WIN) | |
| 1997 EnsureWinsockInit(); | |
| 1998 #endif | |
| 1999 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | |
| 2000 RunLoopbackProbeJob(); | |
| 2001 #endif | |
| 2002 NetworkChangeNotifier::AddIPAddressObserver(this); | |
| 2003 NetworkChangeNotifier::AddConnectionTypeObserver(this); | |
| 2004 NetworkChangeNotifier::AddDNSObserver(this); | |
| 2005 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) && \ | |
| 2006 !defined(OS_ANDROID) | |
| 2007 EnsureDnsReloaderInit(); | |
| 2008 #endif | |
| 2009 | |
| 2010 OnConnectionTypeChanged(NetworkChangeNotifier::GetConnectionType()); | |
| 2011 | |
| 2012 { | |
| 2013 DnsConfig dns_config; | |
| 2014 NetworkChangeNotifier::GetDnsConfig(&dns_config); | |
| 2015 received_dns_config_ = dns_config.IsValid(); | |
| 2016 // Conservatively assume local IPv6 is needed when DnsConfig is not valid. | |
| 2017 use_local_ipv6_ = !dns_config.IsValid() || dns_config.use_local_ipv6; | |
| 2018 } | |
| 2019 | |
| 2020 fallback_to_proctask_ = !ConfigureAsyncDnsNoFallbackFieldTrial(); | |
| 2021 } | |
| 2022 | |
| 2023 void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { | |
| 2024 if (result) { | |
| 2025 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | |
| 2026 } else { | |
| 2027 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | |
| 2028 } | |
| 2029 } | |
| 2030 | |
| 2006 int HostResolverImpl::ResolveHelper(const Key& key, | 2031 int HostResolverImpl::ResolveHelper(const Key& key, |
| 2007 const RequestInfo& info, | 2032 const RequestInfo& info, |
| 2008 const IPAddress* ip_address, | 2033 const IPAddress* ip_address, |
| 2009 AddressList* addresses, | 2034 AddressList* addresses, |
| 2010 const BoundNetLog& source_net_log) { | 2035 const BoundNetLog& source_net_log) { |
| 2011 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. | 2036 // The result of |getaddrinfo| for empty hosts is inconsistent across systems. |
| 2012 // On Windows it gives the default interface's address, whereas on Linux it | 2037 // On Windows it gives the default interface's address, whereas on Linux it |
| 2013 // gives an error. We will make it fail on all platforms for consistency. | 2038 // gives an error. We will make it fail on all platforms for consistency. |
| 2014 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) | 2039 if (info.hostname().empty() || info.hostname().size() > kMaxHostLength) |
| 2015 return ERR_NAME_NOT_RESOLVED; | 2040 return ERR_NAME_NOT_RESOLVED; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2234 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); | 2259 cache_->Set(key, entry, base::TimeTicks::Now(), ttl); |
| 2235 } | 2260 } |
| 2236 | 2261 |
| 2237 void HostResolverImpl::RemoveJob(Job* job) { | 2262 void HostResolverImpl::RemoveJob(Job* job) { |
| 2238 DCHECK(job); | 2263 DCHECK(job); |
| 2239 JobMap::iterator it = jobs_.find(job->key()); | 2264 JobMap::iterator it = jobs_.find(job->key()); |
| 2240 if (it != jobs_.end() && it->second == job) | 2265 if (it != jobs_.end() && it->second == job) |
| 2241 jobs_.erase(it); | 2266 jobs_.erase(it); |
| 2242 } | 2267 } |
| 2243 | 2268 |
| 2244 void HostResolverImpl::SetHaveOnlyLoopbackAddresses(bool result) { | |
| 2245 if (result) { | |
| 2246 additional_resolver_flags_ |= HOST_RESOLVER_LOOPBACK_ONLY; | |
| 2247 } else { | |
| 2248 additional_resolver_flags_ &= ~HOST_RESOLVER_LOOPBACK_ONLY; | |
| 2249 } | |
| 2250 } | |
| 2251 | |
| 2252 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( | 2269 HostResolverImpl::Key HostResolverImpl::GetEffectiveKeyForRequest( |
| 2253 const RequestInfo& info, | 2270 const RequestInfo& info, |
| 2254 const IPAddress* ip_address, | 2271 const IPAddress* ip_address, |
| 2255 const BoundNetLog& net_log) { | 2272 const BoundNetLog& net_log) { |
| 2256 HostResolverFlags effective_flags = | 2273 HostResolverFlags effective_flags = |
| 2257 info.host_resolver_flags() | additional_resolver_flags_; | 2274 info.host_resolver_flags() | additional_resolver_flags_; |
| 2258 AddressFamily effective_address_family = info.address_family(); | 2275 AddressFamily effective_address_family = info.address_family(); |
| 2259 | 2276 |
| 2260 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { | 2277 if (info.address_family() == ADDRESS_FAMILY_UNSPECIFIED) { |
| 2261 if (!use_local_ipv6_ && | 2278 if (!use_local_ipv6_ && |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2284 IsGloballyReachable(IPAddress(kIPv6ProbeAddress), net_log); | 2301 IsGloballyReachable(IPAddress(kIPv6ProbeAddress), net_log); |
| 2285 last_ipv6_probe_time_ = now; | 2302 last_ipv6_probe_time_ = now; |
| 2286 cached = false; | 2303 cached = false; |
| 2287 } | 2304 } |
| 2288 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, | 2305 net_log.AddEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_IPV6_REACHABILITY_CHECK, |
| 2289 base::Bind(&NetLogIPv6AvailableCallback, | 2306 base::Bind(&NetLogIPv6AvailableCallback, |
| 2290 last_ipv6_probe_result_, cached)); | 2307 last_ipv6_probe_result_, cached)); |
| 2291 return last_ipv6_probe_result_; | 2308 return last_ipv6_probe_result_; |
| 2292 } | 2309 } |
| 2293 | 2310 |
| 2311 void HostResolverImpl::RunLoopbackProbeJob() { | |
| 2312 new LoopbackProbeJob(weak_ptr_factory_.GetWeakPtr(), | |
| 2313 worker_task_runner_.get()); | |
| 2314 } | |
| 2315 | |
| 2294 void HostResolverImpl::AbortAllInProgressJobs() { | 2316 void HostResolverImpl::AbortAllInProgressJobs() { |
| 2295 // In Abort, a Request callback could spawn new Jobs with matching keys, so | 2317 // In Abort, a Request callback could spawn new Jobs with matching keys, so |
| 2296 // first collect and remove all running jobs from |jobs_|. | 2318 // first collect and remove all running jobs from |jobs_|. |
| 2297 std::vector<std::unique_ptr<Job>> jobs_to_abort; | 2319 std::vector<std::unique_ptr<Job>> jobs_to_abort; |
| 2298 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { | 2320 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ) { |
| 2299 Job* job = it->second; | 2321 Job* job = it->second; |
| 2300 if (job->is_running()) { | 2322 if (job->is_running()) { |
| 2301 jobs_to_abort.push_back(base::WrapUnique(job)); | 2323 jobs_to_abort.push_back(base::WrapUnique(job)); |
| 2302 jobs_.erase(it++); | 2324 jobs_.erase(it++); |
| 2303 } else { | 2325 } else { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2359 } | 2381 } |
| 2360 | 2382 |
| 2361 void HostResolverImpl::OnIPAddressChanged() { | 2383 void HostResolverImpl::OnIPAddressChanged() { |
| 2362 resolved_known_ipv6_hostname_ = false; | 2384 resolved_known_ipv6_hostname_ = false; |
| 2363 last_ipv6_probe_time_ = base::TimeTicks(); | 2385 last_ipv6_probe_time_ = base::TimeTicks(); |
| 2364 // Abandon all ProbeJobs. | 2386 // Abandon all ProbeJobs. |
| 2365 probe_weak_ptr_factory_.InvalidateWeakPtrs(); | 2387 probe_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 2366 if (cache_.get()) | 2388 if (cache_.get()) |
| 2367 cache_->clear(); | 2389 cache_->clear(); |
| 2368 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 2390 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 2369 new LoopbackProbeJob(probe_weak_ptr_factory_.GetWeakPtr()); | 2391 RunLoopbackProbeJob(); |
| 2370 #endif | 2392 #endif |
| 2371 AbortAllInProgressJobs(); | 2393 AbortAllInProgressJobs(); |
| 2372 // |this| may be deleted inside AbortAllInProgressJobs(). | 2394 // |this| may be deleted inside AbortAllInProgressJobs(). |
| 2373 } | 2395 } |
| 2374 | 2396 |
| 2375 void HostResolverImpl::OnConnectionTypeChanged( | 2397 void HostResolverImpl::OnConnectionTypeChanged( |
| 2376 NetworkChangeNotifier::ConnectionType type) { | 2398 NetworkChangeNotifier::ConnectionType type) { |
| 2377 proc_params_.unresponsive_delay = | 2399 proc_params_.unresponsive_delay = |
| 2378 GetTimeDeltaForConnectionTypeFromFieldTrialOrDefault( | 2400 GetTimeDeltaForConnectionTypeFromFieldTrialOrDefault( |
| 2379 "DnsUnresponsiveDelayMsByConnectionType", | 2401 "DnsUnresponsiveDelayMsByConnectionType", |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2482 dns_client_->SetConfig(dns_config); | 2504 dns_client_->SetConfig(dns_config); |
| 2483 num_dns_failures_ = 0; | 2505 num_dns_failures_ = 0; |
| 2484 if (dns_client_->GetConfig()) | 2506 if (dns_client_->GetConfig()) |
| 2485 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2507 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
| 2486 } | 2508 } |
| 2487 | 2509 |
| 2488 AbortDnsTasks(); | 2510 AbortDnsTasks(); |
| 2489 } | 2511 } |
| 2490 | 2512 |
| 2491 } // namespace net | 2513 } // namespace net |
| OLD | NEW |