• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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