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 |