Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: net/dns/host_resolver_impl.cc

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

Powered by Google App Engine
This is Rietveld 408576698