Home | History | Annotate | Download | only in base
      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.
     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.
    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 
    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