1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_HOST_RESOLVER_IMPL_H_ 6 #define NET_BASE_HOST_RESOLVER_IMPL_H_ 7 #pragma once 8 9 #include <vector> 10 11 #include "base/memory/scoped_ptr.h" 12 #include "base/threading/non_thread_safe.h" 13 #include "net/base/capturing_net_log.h" 14 #include "net/base/host_cache.h" 15 #include "net/base/host_resolver.h" 16 #include "net/base/host_resolver_proc.h" 17 #include "net/base/net_log.h" 18 #include "net/base/network_change_notifier.h" 19 20 namespace net { 21 22 // For each hostname that is requested, HostResolver creates a 23 // HostResolverImpl::Job. This job gets dispatched to a thread in the global 24 // WorkerPool, where it runs SystemHostResolverProc(). If requests for that same 25 // host are made while the job is already outstanding, then they are attached 26 // to the existing job rather than creating a new one. This avoids doing 27 // parallel resolves for the same host. 28 // 29 // The way these classes fit together is illustrated by: 30 // 31 // 32 // +----------- HostResolverImpl -------------+ 33 // | | | 34 // Job Job Job 35 // (for host1, fam1) (for host2, fam2) (for hostx, famx) 36 // / | | / | | / | | 37 // Request ... Request Request ... Request Request ... Request 38 // (port1) (port2) (port3) (port4) (port5) (portX) 39 // 40 // 41 // When a HostResolverImpl::Job finishes its work in the threadpool, the 42 // callbacks of each waiting request are run on the origin thread. 43 // 44 // Thread safety: This class is not threadsafe, and must only be called 45 // from one thread! 46 // 47 // The HostResolverImpl enforces |max_jobs_| as the maximum number of concurrent 48 // threads. 49 // 50 // Requests are ordered in the queue based on their priority. 51 52 class HostResolverImpl : public HostResolver, 53 public base::NonThreadSafe, 54 public NetworkChangeNotifier::IPAddressObserver { 55 public: 56 // The index into |job_pools_| for the various job pools. Pools with a higher 57 // index have lower priority. 58 // 59 // Note: This is currently unused, since there is a single pool 60 // for all requests. 61 enum JobPoolIndex { 62 POOL_NORMAL = 0, 63 POOL_COUNT, 64 }; 65 66 // Creates a HostResolver that first uses the local cache |cache|, and then 67 // falls back to |resolver_proc|. 68 // 69 // If |cache| is NULL, then no caching is used. Otherwise we take 70 // ownership of the |cache| pointer, and will free it during destructor. 71 // 72 // |resolver_proc| is used to perform the actual resolves; it must be 73 // thread-safe since it is run from multiple worker threads. If 74 // |resolver_proc| is NULL then the default host resolver procedure is 75 // used (which is SystemHostResolverProc except if overridden). 76 // |max_jobs| specifies the maximum number of threads that the host resolver 77 // will use. Use SetPoolConstraints() to specify finer-grain settings. 78 // 79 // |net_log| must remain valid for the life of the HostResolverImpl. 80 HostResolverImpl(HostResolverProc* resolver_proc, 81 HostCache* cache, 82 size_t max_jobs, 83 NetLog* net_log); 84 85 // If any completion callbacks are pending when the resolver is destroyed, 86 // the host resolutions are cancelled, and the completion callbacks will not 87 // be called. 88 virtual ~HostResolverImpl(); 89 90 // Continuously observe whether IPv6 is supported, and set the allowable 91 // address family to IPv4 iff IPv6 is not supported. 92 void ProbeIPv6Support(); 93 94 // Returns the cache this resolver uses, or NULL if caching is disabled. cache()95 HostCache* cache() { return cache_.get(); } 96 97 // Applies a set of constraints for requests that belong to the specified 98 // pool. NOTE: Don't call this after requests have been already been started. 99 // 100 // |pool_index| -- Specifies which pool these constraints should be applied 101 // to. 102 // |max_outstanding_jobs| -- How many concurrent jobs are allowed for this 103 // pool. 104 // |max_pending_requests| -- How many requests can be enqueued for this pool 105 // before we start dropping requests. Dropped 106 // requests fail with 107 // ERR_HOST_RESOLVER_QUEUE_TOO_LARGE. 108 void SetPoolConstraints(JobPoolIndex pool_index, 109 size_t max_outstanding_jobs, 110 size_t max_pending_requests); 111 112 // HostResolver methods: 113 virtual int Resolve(const RequestInfo& info, 114 AddressList* addresses, 115 CompletionCallback* callback, 116 RequestHandle* out_req, 117 const BoundNetLog& source_net_log); 118 virtual void CancelRequest(RequestHandle req); 119 virtual void AddObserver(HostResolver::Observer* observer); 120 virtual void RemoveObserver(HostResolver::Observer* observer); 121 122 // Set address family, and disable IPv6 probe support. 123 virtual void SetDefaultAddressFamily(AddressFamily address_family); 124 virtual AddressFamily GetDefaultAddressFamily() const; 125 126 virtual HostResolverImpl* GetAsHostResolverImpl(); 127 128 // TODO(eroman): hack for http://crbug.com/15513 129 virtual void Shutdown(); 130 131 private: 132 class Job; 133 class JobPool; 134 class IPv6ProbeJob; 135 class Request; 136 typedef std::vector<Request*> RequestsList; 137 typedef HostCache::Key Key; 138 typedef std::map<Key, scoped_refptr<Job> > JobMap; 139 typedef std::vector<HostResolver::Observer*> ObserversList; 140 141 // Returns the HostResolverProc to use for this instance. effective_resolver_proc()142 HostResolverProc* effective_resolver_proc() const { 143 return resolver_proc_ ? 144 resolver_proc_.get() : HostResolverProc::GetDefault(); 145 } 146 147 // Adds a job to outstanding jobs list. 148 void AddOutstandingJob(Job* job); 149 150 // Returns the outstanding job for |key|, or NULL if there is none. 151 Job* FindOutstandingJob(const Key& key); 152 153 // Removes |job| from the outstanding jobs list. 154 void RemoveOutstandingJob(Job* job); 155 156 // Callback for when |job| has completed with |net_error| and |addrlist|. 157 void OnJobComplete(Job* job, int net_error, int os_error, 158 const AddressList& addrlist); 159 160 // Aborts |job|. Same as OnJobComplete() except does not remove |job| 161 // from |jobs_| and does not cache the result (ERR_ABORTED). 162 void AbortJob(Job* job); 163 164 // Used by both OnJobComplete() and AbortJob(); 165 void OnJobCompleteInternal(Job* job, int net_error, int os_error, 166 const AddressList& addrlist); 167 168 // Called when a request has just been started. 169 void OnStartRequest(const BoundNetLog& source_net_log, 170 const BoundNetLog& request_net_log, 171 int request_id, 172 const RequestInfo& info); 173 174 // Called when a request has just completed (before its callback is run). 175 void OnFinishRequest(const BoundNetLog& source_net_log, 176 const BoundNetLog& request_net_log, 177 int request_id, 178 const RequestInfo& info, 179 int net_error, 180 int os_error); 181 182 // Called when a request has been cancelled. 183 void OnCancelRequest(const BoundNetLog& source_net_log, 184 const BoundNetLog& request_net_log, 185 int request_id, 186 const RequestInfo& info); 187 188 // Notify IPv6ProbeJob not to call back, and discard reference to the job. 189 void DiscardIPv6ProbeJob(); 190 191 // Callback from IPv6 probe activity. 192 void IPv6ProbeSetDefaultAddressFamily(AddressFamily address_family); 193 194 // Returns true if the constraints for |pool| are met, and a new job can be 195 // created for this pool. 196 bool CanCreateJobForPool(const JobPool& pool) const; 197 198 // Returns the index of the pool that request |req| maps to. 199 static JobPoolIndex GetJobPoolIndexForRequest(const Request* req); 200 GetPoolForRequest(const Request * req)201 JobPool* GetPoolForRequest(const Request* req) { 202 return job_pools_[GetJobPoolIndexForRequest(req)]; 203 } 204 205 // Starts up to 1 job given the current pool constraints. This job 206 // may have multiple requests attached to it. 207 void ProcessQueuedRequests(); 208 209 // Returns the (hostname, address_family) key to use for |info|, choosing an 210 // "effective" address family by inheriting the resolver's default address 211 // family when the request leaves it unspecified. 212 Key GetEffectiveKeyForRequest(const RequestInfo& info) const; 213 214 // Attaches |req| to a new job, and starts it. Returns that job. 215 Job* CreateAndStartJob(Request* req); 216 217 // Adds a pending request |req| to |pool|. 218 int EnqueueRequest(JobPool* pool, Request* req); 219 220 // Cancels all jobs. 221 void CancelAllJobs(); 222 223 // Aborts all in progress jobs (but might start new ones). 224 void AbortAllInProgressJobs(); 225 226 // NetworkChangeNotifier::IPAddressObserver methods: 227 virtual void OnIPAddressChanged(); 228 229 // Cache of host resolution results. 230 scoped_ptr<HostCache> cache_; 231 232 // Map from hostname to outstanding job. 233 JobMap jobs_; 234 235 // Maximum number of concurrent jobs allowed, across all pools. 236 size_t max_jobs_; 237 238 // The information to track pending requests for a JobPool, as well as 239 // how many outstanding jobs the pool already has, and its constraints. 240 JobPool* job_pools_[POOL_COUNT]; 241 242 // The job that OnJobComplete() is currently processing (needed in case 243 // HostResolver gets deleted from within the callback). 244 scoped_refptr<Job> cur_completing_job_; 245 246 // The observers to notify when a request starts/ends. 247 ObserversList observers_; 248 249 // Monotonically increasing ID number to assign to the next request. 250 // Observers are the only consumers of this ID number. 251 int next_request_id_; 252 253 // Monotonically increasing ID number to assign to the next job. 254 // The only consumer of this ID is the requests tracing code. 255 int next_job_id_; 256 257 // The procedure to use for resolving host names. This will be NULL, except 258 // in the case of unit-tests which inject custom host resolving behaviors. 259 scoped_refptr<HostResolverProc> resolver_proc_; 260 261 // Address family to use when the request doesn't specify one. 262 AddressFamily default_address_family_; 263 264 // TODO(eroman): hack for http://crbug.com/15513 265 bool shutdown_; 266 267 // Indicate if probing is done after each network change event to set address 268 // family. 269 // When false, explicit setting of address family is used. 270 bool ipv6_probe_monitoring_; 271 272 // The last un-cancelled IPv6ProbeJob (if any). 273 scoped_refptr<IPv6ProbeJob> ipv6_probe_job_; 274 275 // Any resolver flags that should be added to a request by default. 276 HostResolverFlags additional_resolver_flags_; 277 278 NetLog* net_log_; 279 280 DISALLOW_COPY_AND_ASSIGN(HostResolverImpl); 281 }; 282 283 } // namespace net 284 285 #endif // NET_BASE_HOST_RESOLVER_IMPL_H_ 286