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

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

Issue 1006001: Refine IPv6 probe to require that the client has an IPv6 address on an interf... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_util.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/host_resolver_impl.h" 5 #include "net/base/host_resolver_impl.h"
6 #include "net/base/net_log.h" 6 #include "net/base/net_log.h"
7 7
8 #include <cmath> 8 #include <cmath>
9 #include <deque> 9 #include <deque>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/debug_util.h" 13 #include "base/debug_util.h"
14 #include "base/lock.h" 14 #include "base/lock.h"
15 #include "base/message_loop.h" 15 #include "base/message_loop.h"
16 #include "base/stl_util-inl.h" 16 #include "base/stl_util-inl.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 #include "base/time.h" 18 #include "base/time.h"
19 #include "base/worker_pool.h" 19 #include "base/worker_pool.h"
20 #include "net/base/address_list.h" 20 #include "net/base/address_list.h"
21 #include "net/base/host_resolver_proc.h" 21 #include "net/base/host_resolver_proc.h"
22 #include "net/base/net_log.h" 22 #include "net/base/net_log.h"
23 #include "net/base/net_errors.h" 23 #include "net/base/net_errors.h"
24 #include "net/base/net_util.h"
24 #include "net/base/network_change_notifier.h" 25 #include "net/base/network_change_notifier.h"
25 26
26 #if defined(OS_WIN) 27 #if defined(OS_WIN)
27 #include "net/base/winsock_init.h" 28 #include "net/base/winsock_init.h"
28 #endif 29 #endif
29 30
30 namespace net { 31 namespace net {
31 32
32 namespace { 33 namespace {
33 34
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 186
186 //----------------------------------------------------------------------------- 187 //-----------------------------------------------------------------------------
187 188
188 // This class represents a request to the worker pool for a "getaddrinfo()" 189 // This class represents a request to the worker pool for a "getaddrinfo()"
189 // call. 190 // call.
190 class HostResolverImpl::Job 191 class HostResolverImpl::Job
191 : public base::RefCountedThreadSafe<HostResolverImpl::Job> { 192 : public base::RefCountedThreadSafe<HostResolverImpl::Job> {
192 public: 193 public:
193 Job(int id, HostResolverImpl* resolver, const Key& key, 194 Job(int id, HostResolverImpl* resolver, const Key& key,
194 RequestsTrace* requests_trace) 195 RequestsTrace* requests_trace)
195 : id_(id), key_(key), 196 : id_(id),
197 key_(key),
196 resolver_(resolver), 198 resolver_(resolver),
197 origin_loop_(MessageLoop::current()), 199 origin_loop_(MessageLoop::current()),
198 resolver_proc_(resolver->effective_resolver_proc()), 200 resolver_proc_(resolver->effective_resolver_proc()),
199 requests_trace_(requests_trace), 201 requests_trace_(requests_trace),
200 error_(OK), 202 error_(OK),
201 had_non_speculative_request_(false) { 203 had_non_speculative_request_(false) {
202 if (requests_trace_) { 204 if (requests_trace_) {
203 requests_trace_->Add(StringPrintf( 205 requests_trace_->Add(StringPrintf(
204 "Created job j%d for {hostname='%s', address_family=%d}", 206 "Created job j%d for {hostname='%s', address_family=%d}",
205 id_, key.hostname.c_str(), 207 id_, key.hostname.c_str(),
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 AddressList results_; 416 AddressList results_;
415 417
416 // The time when the job was started. 418 // The time when the job was started.
417 base::TimeTicks start_time_; 419 base::TimeTicks start_time_;
418 420
419 DISALLOW_COPY_AND_ASSIGN(Job); 421 DISALLOW_COPY_AND_ASSIGN(Job);
420 }; 422 };
421 423
422 //----------------------------------------------------------------------------- 424 //-----------------------------------------------------------------------------
423 425
426 // This class represents a request to the worker pool for a "probe for IPv6
427 // support" call.
428 class HostResolverImpl::IPv6ProbeJob
429 : public base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob> {
430 public:
431 explicit IPv6ProbeJob(HostResolverImpl* resolver)
432 : resolver_(resolver),
433 origin_loop_(MessageLoop::current()) {
434 }
435
436 void Start() {
437 DCHECK(IsOnOriginThread());
438 const bool IS_SLOW = true;
439 WorkerPool::PostTask(
440 FROM_HERE, NewRunnableMethod(this, &IPv6ProbeJob::DoProbe), IS_SLOW);
441 }
442
443 // Cancels the current job.
444 void Cancel() {
445 DCHECK(IsOnOriginThread());
446 resolver_ = NULL; // Read/write ONLY on origin thread.
447 {
448 AutoLock locked(origin_loop_lock_);
449 // Origin loop may be destroyed before we can use it!
450 origin_loop_ = NULL;
451 }
452 }
453
454 bool was_cancelled() const {
455 DCHECK(IsOnOriginThread());
456 return resolver_ == NULL;
457 }
458
459 private:
460 friend class base::RefCountedThreadSafe<HostResolverImpl::IPv6ProbeJob>;
461
462 ~IPv6ProbeJob() {
463 }
464
465 // Run on worker thread.
466 void DoProbe() {
467 // Do actual testing on this thread, as it takes 40-100ms.
468 AddressFamily family = IPv6Supported() ? ADDRESS_FAMILY_UNSPECIFIED
469 : ADDRESS_FAMILY_IPV4;
470
471 Task* reply = NewRunnableMethod(this, &IPv6ProbeJob::OnProbeComplete,
472 family);
473
474 // The origin loop could go away while we are trying to post to it, so we
475 // need to call its PostTask method inside a lock. See ~HostResolver.
476 {
477 AutoLock locked(origin_loop_lock_);
478 if (origin_loop_) {
479 origin_loop_->PostTask(FROM_HERE, reply);
480 return;
481 }
482 }
483
484 // We didn't post, so delete the reply.
485 delete reply;
486 }
487
488 // Callback for when DoProbe() completes (runs on origin thread).
489 void OnProbeComplete(AddressFamily address_family) {
490 DCHECK(IsOnOriginThread());
491 if (!was_cancelled())
492 resolver_->IPv6ProbeSetDefaultAddressFamily(address_family);
493 }
494
495 bool IsOnOriginThread() const {
496 return !MessageLoop::current() || origin_loop_ == MessageLoop::current();
497 }
498
499 // Used/set only on origin thread.
500 HostResolverImpl* resolver_;
501
502 // Used to post ourselves onto the origin thread.
503 Lock origin_loop_lock_;
504 MessageLoop* origin_loop_;
505
506 DISALLOW_COPY_AND_ASSIGN(IPv6ProbeJob);
507 };
508
509 //-----------------------------------------------------------------------------
510
424 // We rely on the priority enum values being sequential having starting at 0, 511 // We rely on the priority enum values being sequential having starting at 0,
425 // and increasing for lower priorities. 512 // and increasing for lower priorities.
426 COMPILE_ASSERT(HIGHEST == 0u && 513 COMPILE_ASSERT(HIGHEST == 0u &&
427 LOWEST > HIGHEST && 514 LOWEST > HIGHEST &&
428 NUM_PRIORITIES > LOWEST, 515 NUM_PRIORITIES > LOWEST,
429 priority_indexes_incompatible); 516 priority_indexes_incompatible);
430 517
431 // JobPool contains all the information relating to queued requests, including 518 // JobPool contains all the information relating to queued requests, including
432 // the limits on how many jobs are allowed to be used for this category of 519 // the limits on how many jobs are allowed to be used for this category of
433 // requests. 520 // requests.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 HostCache* cache, 661 HostCache* cache,
575 NetworkChangeNotifier* network_change_notifier, 662 NetworkChangeNotifier* network_change_notifier,
576 size_t max_jobs) 663 size_t max_jobs)
577 : cache_(cache), 664 : cache_(cache),
578 max_jobs_(max_jobs), 665 max_jobs_(max_jobs),
579 next_request_id_(0), 666 next_request_id_(0),
580 next_job_id_(0), 667 next_job_id_(0),
581 resolver_proc_(resolver_proc), 668 resolver_proc_(resolver_proc),
582 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED), 669 default_address_family_(ADDRESS_FAMILY_UNSPECIFIED),
583 shutdown_(false), 670 shutdown_(false),
584 network_change_notifier_(network_change_notifier) { 671 network_change_notifier_(network_change_notifier),
672 ipv6_probe_monitoring_(false) {
585 DCHECK_GT(max_jobs, 0u); 673 DCHECK_GT(max_jobs, 0u);
586 674
587 // It is cumbersome to expose all of the constraints in the constructor, 675 // It is cumbersome to expose all of the constraints in the constructor,
588 // so we choose some defaults, which users can override later. 676 // so we choose some defaults, which users can override later.
589 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs); 677 job_pools_[POOL_NORMAL] = new JobPool(max_jobs, 100u * max_jobs);
590 678
591 #if defined(OS_WIN) 679 #if defined(OS_WIN)
592 EnsureWinsockInit(); 680 EnsureWinsockInit();
593 #endif 681 #endif
594 if (network_change_notifier_) 682 if (network_change_notifier_)
595 network_change_notifier_->AddObserver(this); 683 network_change_notifier_->AddObserver(this);
596 } 684 }
597 685
598 HostResolverImpl::~HostResolverImpl() { 686 HostResolverImpl::~HostResolverImpl() {
599 // Cancel the outstanding jobs. Those jobs may contain several attached 687 // Cancel the outstanding jobs. Those jobs may contain several attached
600 // requests, which will also be cancelled. 688 // requests, which will also be cancelled.
689 DiscardIPv6ProbeJob();
690
601 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) 691 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
602 it->second->Cancel(); 692 it->second->Cancel();
603 693
604 // In case we are being deleted during the processing of a callback. 694 // In case we are being deleted during the processing of a callback.
605 if (cur_completing_job_) 695 if (cur_completing_job_)
606 cur_completing_job_->Cancel(); 696 cur_completing_job_->Cancel();
607 697
608 if (network_change_notifier_) 698 if (network_change_notifier_)
609 network_change_notifier_->RemoveObserver(this); 699 network_change_notifier_->RemoveObserver(this);
610 700
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) { 825 void HostResolverImpl::RemoveObserver(HostResolver::Observer* observer) {
736 ObserversList::iterator it = 826 ObserversList::iterator it =
737 std::find(observers_.begin(), observers_.end(), observer); 827 std::find(observers_.begin(), observers_.end(), observer);
738 828
739 // Observer must exist. 829 // Observer must exist.
740 DCHECK(it != observers_.end()); 830 DCHECK(it != observers_.end());
741 831
742 observers_.erase(it); 832 observers_.erase(it);
743 } 833 }
744 834
835 void HostResolverImpl::SetDefaultAddressFamily(AddressFamily address_family) {
836 ipv6_probe_monitoring_ = false;
837 DiscardIPv6ProbeJob();
838 default_address_family_ = address_family;
839 }
840
841 void HostResolverImpl::ProbeIPv6Support() {
842 DCHECK(!ipv6_probe_monitoring_);
843 ipv6_probe_monitoring_ = true;
844 OnIPAddressChanged(); // Give initial setup call.
845 }
846
745 void HostResolverImpl::Shutdown() { 847 void HostResolverImpl::Shutdown() {
746 shutdown_ = true; 848 shutdown_ = true;
747 849
748 // Cancel the outstanding jobs. 850 // Cancel the outstanding jobs.
749 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it) 851 for (JobMap::iterator it = jobs_.begin(); it != jobs_.end(); ++it)
750 it->second->Cancel(); 852 it->second->Cancel();
751 jobs_.clear(); 853 jobs_.clear();
752 } 854 }
753 855
754 void HostResolverImpl::ClearRequestsTrace() { 856 void HostResolverImpl::ClearRequestsTrace() {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 1070
969 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL); 1071 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL_OBSERVER_ONCANCEL);
970 } 1072 }
971 1073
972 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL); 1074 net_log.EndEvent(NetLog::TYPE_HOST_RESOLVER_IMPL);
973 } 1075 }
974 1076
975 void HostResolverImpl::OnIPAddressChanged() { 1077 void HostResolverImpl::OnIPAddressChanged() {
976 if (cache_.get()) 1078 if (cache_.get())
977 cache_->clear(); 1079 cache_->clear();
1080 if (ipv6_probe_monitoring_) {
1081 DiscardIPv6ProbeJob();
1082 ipv6_probe_job_ = new IPv6ProbeJob(this);
1083 ipv6_probe_job_->Start();
1084 }
1085 }
1086
1087 void HostResolverImpl::DiscardIPv6ProbeJob() {
1088 if (ipv6_probe_job_.get()) {
1089 ipv6_probe_job_->Cancel();
1090 ipv6_probe_job_ = NULL;
1091 }
1092 }
1093
1094 void HostResolverImpl::IPv6ProbeSetDefaultAddressFamily(
1095 AddressFamily address_family) {
1096 DCHECK(address_family == ADDRESS_FAMILY_UNSPECIFIED ||
1097 address_family == ADDRESS_FAMILY_IPV4);
1098 if (default_address_family_ != address_family)
1099 LOG(INFO) << "IPv6Probe forced AddressFamily setting to "
1100 << ((address_family == ADDRESS_FAMILY_UNSPECIFIED)
1101 ? "ADDRESS_FAMILY_UNSPECIFIED"
1102 : "ADDRESS_FAMILY_IPV4");
1103 default_address_family_ = address_family;
1104 // Drop reference since the job has called us back.
1105 DiscardIPv6ProbeJob();
978 } 1106 }
979 1107
980 // static 1108 // static
981 HostResolverImpl::JobPoolIndex HostResolverImpl::GetJobPoolIndexForRequest( 1109 HostResolverImpl::JobPoolIndex HostResolverImpl::GetJobPoolIndexForRequest(
982 const Request* req) { 1110 const Request* req) {
983 return POOL_NORMAL; 1111 return POOL_NORMAL;
984 } 1112 }
985 1113
986 bool HostResolverImpl::CanCreateJobForPool(const JobPool& pool) const { 1114 bool HostResolverImpl::CanCreateJobForPool(const JobPool& pool) const {
987 DCHECK_LE(jobs_.size(), max_jobs_); 1115 DCHECK_LE(jobs_.size(), max_jobs_);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 if (r == req) 1183 if (r == req)
1056 return error; 1184 return error;
1057 1185
1058 r->OnComplete(error, AddressList()); 1186 r->OnComplete(error, AddressList());
1059 } 1187 }
1060 1188
1061 return ERR_IO_PENDING; 1189 return ERR_IO_PENDING;
1062 } 1190 }
1063 1191
1064 } // namespace net 1192 } // namespace net
OLDNEW
« no previous file with comments | « net/base/host_resolver_impl.h ('k') | net/base/net_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698