OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/dns/host_resolver_impl.h" | 5 #include "net/dns/host_resolver_impl.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <Winsock2.h> | 8 #include <Winsock2.h> |
9 #elif defined(OS_POSIX) | 9 #elif defined(OS_POSIX) |
10 #include <netdb.h> | 10 #include <netdb.h> |
11 #endif | 11 #endif |
12 | 12 |
13 #include <cmath> | 13 #include <cmath> |
14 #include <utility> | 14 #include <utility> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/basictypes.h" | 17 #include "base/basictypes.h" |
18 #include "base/bind.h" | 18 #include "base/bind.h" |
19 #include "base/bind_helpers.h" | 19 #include "base/bind_helpers.h" |
20 #include "base/callback.h" | 20 #include "base/callback.h" |
21 #include "base/compiler_specific.h" | 21 #include "base/compiler_specific.h" |
22 #include "base/debug/debugger.h" | 22 #include "base/debug/debugger.h" |
23 #include "base/debug/stack_trace.h" | 23 #include "base/debug/stack_trace.h" |
24 #include "base/message_loop/message_loop_proxy.h" | |
25 #include "base/metrics/field_trial.h" | 24 #include "base/metrics/field_trial.h" |
26 #include "base/metrics/histogram_macros.h" | 25 #include "base/metrics/histogram_macros.h" |
27 #include "base/metrics/sparse_histogram.h" | 26 #include "base/metrics/sparse_histogram.h" |
28 #include "base/profiler/scoped_tracker.h" | 27 #include "base/profiler/scoped_tracker.h" |
| 28 #include "base/single_thread_task_runner.h" |
29 #include "base/stl_util.h" | 29 #include "base/stl_util.h" |
30 #include "base/strings/string_util.h" | 30 #include "base/strings/string_util.h" |
31 #include "base/strings/utf_string_conversions.h" | 31 #include "base/strings/utf_string_conversions.h" |
| 32 #include "base/thread_task_runner_handle.h" |
32 #include "base/threading/worker_pool.h" | 33 #include "base/threading/worker_pool.h" |
33 #include "base/time/time.h" | 34 #include "base/time/time.h" |
34 #include "base/values.h" | 35 #include "base/values.h" |
35 #include "net/base/address_family.h" | 36 #include "net/base/address_family.h" |
36 #include "net/base/address_list.h" | 37 #include "net/base/address_list.h" |
37 #include "net/base/dns_reloader.h" | 38 #include "net/base/dns_reloader.h" |
38 #include "net/base/dns_util.h" | 39 #include "net/base/dns_util.h" |
39 #include "net/base/host_port_pair.h" | 40 #include "net/base/host_port_pair.h" |
40 #include "net/base/ip_endpoint.h" | 41 #include "net/base/ip_endpoint.h" |
41 #include "net/base/net_errors.h" | 42 #include "net/base/net_errors.h" |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 typedef base::Callback<void(int net_error, | 592 typedef base::Callback<void(int net_error, |
592 const AddressList& addr_list)> Callback; | 593 const AddressList& addr_list)> Callback; |
593 | 594 |
594 ProcTask(const Key& key, | 595 ProcTask(const Key& key, |
595 const ProcTaskParams& params, | 596 const ProcTaskParams& params, |
596 const Callback& callback, | 597 const Callback& callback, |
597 const BoundNetLog& job_net_log) | 598 const BoundNetLog& job_net_log) |
598 : key_(key), | 599 : key_(key), |
599 params_(params), | 600 params_(params), |
600 callback_(callback), | 601 callback_(callback), |
601 origin_loop_(base::MessageLoopProxy::current()), | 602 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
602 attempt_number_(0), | 603 attempt_number_(0), |
603 completed_attempt_number_(0), | 604 completed_attempt_number_(0), |
604 completed_attempt_error_(ERR_UNEXPECTED), | 605 completed_attempt_error_(ERR_UNEXPECTED), |
605 had_non_speculative_request_(false), | 606 had_non_speculative_request_(false), |
606 net_log_(job_net_log) { | 607 net_log_(job_net_log) { |
607 if (!params_.resolver_proc.get()) | 608 if (!params_.resolver_proc.get()) |
608 params_.resolver_proc = HostResolverProc::GetDefault(); | 609 params_.resolver_proc = HostResolverProc::GetDefault(); |
609 // If default is unset, use the system proc. | 610 // If default is unset, use the system proc. |
610 if (!params_.resolver_proc.get()) | 611 if (!params_.resolver_proc.get()) |
611 params_.resolver_proc = new SystemHostResolverProc(); | 612 params_.resolver_proc = new SystemHostResolverProc(); |
612 } | 613 } |
613 | 614 |
614 void Start() { | 615 void Start() { |
615 DCHECK(origin_loop_->BelongsToCurrentThread()); | 616 DCHECK(task_runner_->BelongsToCurrentThread()); |
616 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); | 617 net_log_.BeginEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
617 StartLookupAttempt(); | 618 StartLookupAttempt(); |
618 } | 619 } |
619 | 620 |
620 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve | 621 // Cancels this ProcTask. It will be orphaned. Any outstanding resolve |
621 // attempts running on worker threads will continue running. Only once all the | 622 // attempts running on worker threads will continue running. Only once all the |
622 // attempts complete will the final reference to this ProcTask be released. | 623 // attempts complete will the final reference to this ProcTask be released. |
623 void Cancel() { | 624 void Cancel() { |
624 DCHECK(origin_loop_->BelongsToCurrentThread()); | 625 DCHECK(task_runner_->BelongsToCurrentThread()); |
625 | 626 |
626 if (was_canceled() || was_completed()) | 627 if (was_canceled() || was_completed()) |
627 return; | 628 return; |
628 | 629 |
629 callback_.Reset(); | 630 callback_.Reset(); |
630 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); | 631 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK); |
631 } | 632 } |
632 | 633 |
633 void set_had_non_speculative_request() { | 634 void set_had_non_speculative_request() { |
634 DCHECK(origin_loop_->BelongsToCurrentThread()); | 635 DCHECK(task_runner_->BelongsToCurrentThread()); |
635 had_non_speculative_request_ = true; | 636 had_non_speculative_request_ = true; |
636 } | 637 } |
637 | 638 |
638 bool was_canceled() const { | 639 bool was_canceled() const { |
639 DCHECK(origin_loop_->BelongsToCurrentThread()); | 640 DCHECK(task_runner_->BelongsToCurrentThread()); |
640 return callback_.is_null(); | 641 return callback_.is_null(); |
641 } | 642 } |
642 | 643 |
643 bool was_completed() const { | 644 bool was_completed() const { |
644 DCHECK(origin_loop_->BelongsToCurrentThread()); | 645 DCHECK(task_runner_->BelongsToCurrentThread()); |
645 return completed_attempt_number_ > 0; | 646 return completed_attempt_number_ > 0; |
646 } | 647 } |
647 | 648 |
648 private: | 649 private: |
649 friend class base::RefCountedThreadSafe<ProcTask>; | 650 friend class base::RefCountedThreadSafe<ProcTask>; |
650 ~ProcTask() {} | 651 ~ProcTask() {} |
651 | 652 |
652 void StartLookupAttempt() { | 653 void StartLookupAttempt() { |
653 DCHECK(origin_loop_->BelongsToCurrentThread()); | 654 DCHECK(task_runner_->BelongsToCurrentThread()); |
654 base::TimeTicks start_time = base::TimeTicks::Now(); | 655 base::TimeTicks start_time = base::TimeTicks::Now(); |
655 ++attempt_number_; | 656 ++attempt_number_; |
656 // Dispatch the lookup attempt to a worker thread. | 657 // Dispatch the lookup attempt to a worker thread. |
657 if (!base::WorkerPool::PostTask( | 658 if (!base::WorkerPool::PostTask( |
658 FROM_HERE, | 659 FROM_HERE, |
659 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), | 660 base::Bind(&ProcTask::DoLookup, this, start_time, attempt_number_), |
660 true)) { | 661 true)) { |
661 NOTREACHED(); | 662 NOTREACHED(); |
662 | 663 |
663 // Since we could be running within Resolve() right now, we can't just | 664 // Since we could be running within Resolve() right now, we can't just |
664 // call OnLookupComplete(). Instead we must wait until Resolve() has | 665 // call OnLookupComplete(). Instead we must wait until Resolve() has |
665 // returned (IO_PENDING). | 666 // returned (IO_PENDING). |
666 origin_loop_->PostTask( | 667 task_runner_->PostTask(FROM_HERE, |
667 FROM_HERE, | 668 base::Bind(&ProcTask::OnLookupComplete, |
668 base::Bind(&ProcTask::OnLookupComplete, this, AddressList(), | 669 this, |
669 start_time, attempt_number_, ERR_UNEXPECTED, 0)); | 670 AddressList(), |
| 671 start_time, |
| 672 attempt_number_, |
| 673 ERR_UNEXPECTED, |
| 674 0)); |
670 return; | 675 return; |
671 } | 676 } |
672 | 677 |
673 net_log_.AddEvent( | 678 net_log_.AddEvent( |
674 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, | 679 NetLog::TYPE_HOST_RESOLVER_IMPL_ATTEMPT_STARTED, |
675 NetLog::IntegerCallback("attempt_number", attempt_number_)); | 680 NetLog::IntegerCallback("attempt_number", attempt_number_)); |
676 | 681 |
677 // If we don't get the results within a given time, RetryIfNotComplete | 682 // If we don't get the results within a given time, RetryIfNotComplete |
678 // will start a new attempt on a different worker thread if none of our | 683 // will start a new attempt on a different worker thread if none of our |
679 // outstanding attempts have completed yet. | 684 // outstanding attempts have completed yet. |
680 if (attempt_number_ <= params_.max_retry_attempts) { | 685 if (attempt_number_ <= params_.max_retry_attempts) { |
681 origin_loop_->PostDelayedTask( | 686 task_runner_->PostDelayedTask( |
682 FROM_HERE, | 687 FROM_HERE, |
683 base::Bind(&ProcTask::RetryIfNotComplete, this), | 688 base::Bind(&ProcTask::RetryIfNotComplete, this), |
684 params_.unresponsive_delay); | 689 params_.unresponsive_delay); |
685 } | 690 } |
686 } | 691 } |
687 | 692 |
688 // WARNING: This code runs inside a worker pool. The shutdown code cannot | 693 // WARNING: This code runs inside a worker pool. The shutdown code cannot |
689 // wait for it to finish, so we must be very careful here about using other | 694 // wait for it to finish, so we must be very careful here about using other |
690 // objects (like MessageLoops, Singletons, etc). During shutdown these objects | 695 // objects (like MessageLoops, Singletons, etc). During shutdown these objects |
691 // may no longer exist. Multiple DoLookups() could be running in parallel, so | 696 // may no longer exist. Multiple DoLookups() could be running in parallel, so |
(...skipping 13 matching lines...) Expand all Loading... |
705 // block of kIcanNameCollisionIp for details on why. | 710 // block of kIcanNameCollisionIp for details on why. |
706 for (const auto& it : results) { | 711 for (const auto& it : results) { |
707 const IPAddressNumber& cur = it.address(); | 712 const IPAddressNumber& cur = it.address(); |
708 if (cur.size() == arraysize(kIcanNameCollisionIp) && | 713 if (cur.size() == arraysize(kIcanNameCollisionIp) && |
709 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) { | 714 0 == memcmp(&cur.front(), kIcanNameCollisionIp, cur.size())) { |
710 error = ERR_ICANN_NAME_COLLISION; | 715 error = ERR_ICANN_NAME_COLLISION; |
711 break; | 716 break; |
712 } | 717 } |
713 } | 718 } |
714 | 719 |
715 origin_loop_->PostTask( | 720 task_runner_->PostTask(FROM_HERE, |
716 FROM_HERE, | 721 base::Bind(&ProcTask::OnLookupComplete, |
717 base::Bind(&ProcTask::OnLookupComplete, this, results, start_time, | 722 this, |
718 attempt_number, error, os_error)); | 723 results, |
| 724 start_time, |
| 725 attempt_number, |
| 726 error, |
| 727 os_error)); |
719 } | 728 } |
720 | 729 |
721 // Makes next attempt if DoLookup() has not finished (runs on origin thread). | 730 // Makes next attempt if DoLookup() has not finished (runs on task runner |
| 731 // thread). |
722 void RetryIfNotComplete() { | 732 void RetryIfNotComplete() { |
723 DCHECK(origin_loop_->BelongsToCurrentThread()); | 733 DCHECK(task_runner_->BelongsToCurrentThread()); |
724 | 734 |
725 if (was_completed() || was_canceled()) | 735 if (was_completed() || was_canceled()) |
726 return; | 736 return; |
727 | 737 |
728 params_.unresponsive_delay *= params_.retry_factor; | 738 params_.unresponsive_delay *= params_.retry_factor; |
729 StartLookupAttempt(); | 739 StartLookupAttempt(); |
730 } | 740 } |
731 | 741 |
732 // Callback for when DoLookup() completes (runs on origin thread). | 742 // Callback for when DoLookup() completes (runs on task runner thread). |
733 void OnLookupComplete(const AddressList& results, | 743 void OnLookupComplete(const AddressList& results, |
734 const base::TimeTicks& start_time, | 744 const base::TimeTicks& start_time, |
735 const uint32 attempt_number, | 745 const uint32 attempt_number, |
736 int error, | 746 int error, |
737 const int os_error) { | 747 const int os_error) { |
738 DCHECK(origin_loop_->BelongsToCurrentThread()); | 748 DCHECK(task_runner_->BelongsToCurrentThread()); |
739 // If results are empty, we should return an error. | 749 // If results are empty, we should return an error. |
740 bool empty_list_on_ok = (error == OK && results.empty()); | 750 bool empty_list_on_ok = (error == OK && results.empty()); |
741 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); | 751 UMA_HISTOGRAM_BOOLEAN("DNS.EmptyAddressListAndNoError", empty_list_on_ok); |
742 if (empty_list_on_ok) | 752 if (empty_list_on_ok) |
743 error = ERR_NAME_NOT_RESOLVED; | 753 error = ERR_NAME_NOT_RESOLVED; |
744 | 754 |
745 bool was_retry_attempt = attempt_number > 1; | 755 bool was_retry_attempt = attempt_number > 1; |
746 | 756 |
747 // Ideally the following code would be part of host_resolver_proc.cc, | 757 // Ideally the following code would be part of host_resolver_proc.cc, |
748 // however it isn't safe to call NetworkChangeNotifier from worker threads. | 758 // however it isn't safe to call NetworkChangeNotifier from worker threads. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 } | 805 } |
796 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, | 806 net_log_.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_PROC_TASK, |
797 net_log_callback); | 807 net_log_callback); |
798 | 808 |
799 callback_.Run(error, results_); | 809 callback_.Run(error, results_); |
800 } | 810 } |
801 | 811 |
802 void RecordPerformanceHistograms(const base::TimeTicks& start_time, | 812 void RecordPerformanceHistograms(const base::TimeTicks& start_time, |
803 const int error, | 813 const int error, |
804 const int os_error) const { | 814 const int os_error) const { |
805 DCHECK(origin_loop_->BelongsToCurrentThread()); | 815 DCHECK(task_runner_->BelongsToCurrentThread()); |
806 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. | 816 enum Category { // Used in UMA_HISTOGRAM_ENUMERATION. |
807 RESOLVE_SUCCESS, | 817 RESOLVE_SUCCESS, |
808 RESOLVE_FAIL, | 818 RESOLVE_FAIL, |
809 RESOLVE_SPECULATIVE_SUCCESS, | 819 RESOLVE_SPECULATIVE_SUCCESS, |
810 RESOLVE_SPECULATIVE_FAIL, | 820 RESOLVE_SPECULATIVE_FAIL, |
811 RESOLVE_MAX, // Bounding value. | 821 RESOLVE_MAX, // Bounding value. |
812 }; | 822 }; |
813 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. | 823 int category = RESOLVE_MAX; // Illegal value for later DCHECK only. |
814 | 824 |
815 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 825 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 } | 872 } |
863 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. | 873 DCHECK_LT(category, static_cast<int>(RESOLVE_MAX)); // Be sure it was set. |
864 | 874 |
865 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); | 875 UMA_HISTOGRAM_ENUMERATION("DNS.ResolveCategory", category, RESOLVE_MAX); |
866 } | 876 } |
867 | 877 |
868 void RecordAttemptHistograms(const base::TimeTicks& start_time, | 878 void RecordAttemptHistograms(const base::TimeTicks& start_time, |
869 const uint32 attempt_number, | 879 const uint32 attempt_number, |
870 const int error, | 880 const int error, |
871 const int os_error) const { | 881 const int os_error) const { |
872 DCHECK(origin_loop_->BelongsToCurrentThread()); | 882 DCHECK(task_runner_->BelongsToCurrentThread()); |
873 bool first_attempt_to_complete = | 883 bool first_attempt_to_complete = |
874 completed_attempt_number_ == attempt_number; | 884 completed_attempt_number_ == attempt_number; |
875 bool is_first_attempt = (attempt_number == 1); | 885 bool is_first_attempt = (attempt_number == 1); |
876 | 886 |
877 if (first_attempt_to_complete) { | 887 if (first_attempt_to_complete) { |
878 // If this was first attempt to complete, then record the resolution | 888 // If this was first attempt to complete, then record the resolution |
879 // status of the attempt. | 889 // status of the attempt. |
880 if (completed_attempt_error_ == OK) { | 890 if (completed_attempt_error_ == OK) { |
881 UMA_HISTOGRAM_ENUMERATION( | 891 UMA_HISTOGRAM_ENUMERATION( |
882 "DNS.AttemptFirstSuccess", attempt_number, 100); | 892 "DNS.AttemptFirstSuccess", attempt_number, 100); |
(...skipping 26 matching lines...) Expand all Loading... |
909 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100); | 919 UMA_HISTOGRAM_ENUMERATION("DNS.AttemptCancelled", attempt_number, 100); |
910 } | 920 } |
911 | 921 |
912 base::TimeDelta duration = base::TimeTicks::Now() - start_time; | 922 base::TimeDelta duration = base::TimeTicks::Now() - start_time; |
913 if (error == OK) | 923 if (error == OK) |
914 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration); | 924 DNS_HISTOGRAM("DNS.AttemptSuccessDuration", duration); |
915 else | 925 else |
916 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration); | 926 DNS_HISTOGRAM("DNS.AttemptFailDuration", duration); |
917 } | 927 } |
918 | 928 |
919 // Set on the origin thread, read on the worker thread. | 929 // Set on the task runner thread, read on the worker thread. |
920 Key key_; | 930 Key key_; |
921 | 931 |
922 // Holds an owning reference to the HostResolverProc that we are going to use. | 932 // Holds an owning reference to the HostResolverProc that we are going to use. |
923 // This may not be the current resolver procedure by the time we call | 933 // This may not be the current resolver procedure by the time we call |
924 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning | 934 // ResolveAddrInfo, but that's OK... we'll use it anyways, and the owning |
925 // reference ensures that it remains valid until we are done. | 935 // reference ensures that it remains valid until we are done. |
926 ProcTaskParams params_; | 936 ProcTaskParams params_; |
927 | 937 |
928 // The listener to the results of this ProcTask. | 938 // The listener to the results of this ProcTask. |
929 Callback callback_; | 939 Callback callback_; |
930 | 940 |
931 // Used to post ourselves onto the origin thread. | 941 // Used to post ourselves onto the task runner thread. |
932 scoped_refptr<base::MessageLoopProxy> origin_loop_; | 942 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
933 | 943 |
934 // Keeps track of the number of attempts we have made so far to resolve the | 944 // Keeps track of the number of attempts we have made so far to resolve the |
935 // host. Whenever we start an attempt to resolve the host, we increase this | 945 // host. Whenever we start an attempt to resolve the host, we increase this |
936 // number. | 946 // number. |
937 uint32 attempt_number_; | 947 uint32 attempt_number_; |
938 | 948 |
939 // The index of the attempt which finished first (or 0 if the job is still in | 949 // The index of the attempt which finished first (or 0 if the job is still in |
940 // progress). | 950 // progress). |
941 uint32 completed_attempt_number_; | 951 uint32 completed_attempt_number_; |
942 | 952 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 void DoProbe() { | 994 void DoProbe() { |
985 result_ = HaveOnlyLoopbackAddresses(); | 995 result_ = HaveOnlyLoopbackAddresses(); |
986 } | 996 } |
987 | 997 |
988 void OnProbeComplete() { | 998 void OnProbeComplete() { |
989 if (!resolver_.get()) | 999 if (!resolver_.get()) |
990 return; | 1000 return; |
991 resolver_->SetHaveOnlyLoopbackAddresses(result_); | 1001 resolver_->SetHaveOnlyLoopbackAddresses(result_); |
992 } | 1002 } |
993 | 1003 |
994 // Used/set only on origin thread. | 1004 // Used/set only on task runner thread. |
995 base::WeakPtr<HostResolverImpl> resolver_; | 1005 base::WeakPtr<HostResolverImpl> resolver_; |
996 | 1006 |
997 bool result_; | 1007 bool result_; |
998 | 1008 |
999 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); | 1009 DISALLOW_COPY_AND_ASSIGN(LoopbackProbeJob); |
1000 }; | 1010 }; |
1001 | 1011 |
1002 //----------------------------------------------------------------------------- | 1012 //----------------------------------------------------------------------------- |
1003 | 1013 |
1004 // Resolves the hostname using DnsTransaction. | 1014 // Resolves the hostname using DnsTransaction. |
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2424 dns_client_->SetConfig(dns_config); | 2434 dns_client_->SetConfig(dns_config); |
2425 num_dns_failures_ = 0; | 2435 num_dns_failures_ = 0; |
2426 if (dns_client_->GetConfig()) | 2436 if (dns_client_->GetConfig()) |
2427 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); | 2437 UMA_HISTOGRAM_BOOLEAN("AsyncDNS.DnsClientEnabled", true); |
2428 } | 2438 } |
2429 | 2439 |
2430 AbortDnsTasks(); | 2440 AbortDnsTasks(); |
2431 } | 2441 } |
2432 | 2442 |
2433 } // namespace net | 2443 } // namespace net |
OLD | NEW |