| OLD | NEW | 
|---|
| 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 #ifndef NET_BASE_HOST_RESOLVER_H_ | 5 #ifndef NET_BASE_HOST_RESOLVER_IMPL_H_ | 
| 6 #define NET_BASE_HOST_RESOLVER_H_ | 6 #define NET_BASE_HOST_RESOLVER_IMPL_H_ | 
| 7 | 7 | 
| 8 #include <string> | 8 #include <string> | 
| 9 #include <vector> | 9 #include <vector> | 
| 10 | 10 | 
| 11 #include "base/basictypes.h" |  | 
| 12 #include "base/lock.h" |  | 
| 13 #include "base/ref_counted.h" |  | 
| 14 #include "googleurl/src/gurl.h" |  | 
| 15 #include "net/base/completion_callback.h" |  | 
| 16 #include "net/base/host_cache.h" | 11 #include "net/base/host_cache.h" | 
| 17 | 12 #include "net/base/host_resolver.h" | 
| 18 class MessageLoop; | 13 #include "net/base/host_resolver_proc.h" | 
| 19 | 14 | 
| 20 namespace net { | 15 namespace net { | 
| 21 | 16 | 
| 22 class AddressList; |  | 
| 23 class HostMapper; |  | 
| 24 |  | 
| 25 // This class represents the task of resolving hostnames (or IP address |  | 
| 26 // literal) to an AddressList object. |  | 
| 27 // |  | 
| 28 // HostResolver handles multiple requests at a time, so when cancelling a |  | 
| 29 // request the Request* handle that was returned by Resolve() needs to be |  | 
| 30 // given.  A simpler alternative for consumers that only have 1 outstanding |  | 
| 31 // request at a time is to create a SingleRequestHostResolver wrapper around |  | 
| 32 // HostResolver (which will automatically cancel the single request when it |  | 
| 33 // goes out of scope). |  | 
| 34 // |  | 
| 35 // For each hostname that is requested, HostResolver creates a | 17 // For each hostname that is requested, HostResolver creates a | 
| 36 // HostResolver::Job. This job gets dispatched to a thread in the global | 18 // HostResolverImpl::Job. This job gets dispatched to a thread in the global | 
| 37 // WorkerPool, where it runs "getaddrinfo(hostname)". If requests for that same | 19 // WorkerPool, where it runs SystemHostResolverProc(). If requests for that same | 
| 38 // host are made while the job is already outstanding, then they are attached | 20 // host are made while the job is already outstanding, then they are attached | 
| 39 // to the existing job rather than creating a new one. This avoids doing | 21 // to the existing job rather than creating a new one. This avoids doing | 
| 40 // parallel resolves for the same host. | 22 // parallel resolves for the same host. | 
| 41 // | 23 // | 
| 42 // The way these classes fit together is illustrated by: | 24 // The way these classes fit together is illustrated by: | 
| 43 // | 25 // | 
| 44 // | 26 // | 
| 45 //            +------------- HostResolver ---------------+ | 27 //            +----------- HostResolverImpl -------------+ | 
| 46 //            |                    |                     | | 28 //            |                    |                     | | 
| 47 //           Job                  Job                   Job | 29 //           Job                  Job                   Job | 
| 48 //       (for host1)          (for host2)           (for hostX) | 30 //       (for host1)          (for host2)           (for hostX) | 
| 49 //       /    |   |            /   |   |             /   |   | | 31 //       /    |   |            /   |   |             /   |   | | 
| 50 //   Request ... Request  Request ... Request   Request ... Request | 32 //   Request ... Request  Request ... Request   Request ... Request | 
| 51 //  (port1)     (port2)  (port3)      (port4)  (port5)      (portX) | 33 //  (port1)     (port2)  (port3)      (port4)  (port5)      (portX) | 
| 52 // | 34 // | 
| 53 // | 35 // | 
| 54 // When a HostResolver::Job finishes its work in the threadpool, the callbacks | 36 // When a HostResolverImpl::Job finishes its work in the threadpool, the | 
| 55 // of each waiting request are run on the origin thread. | 37 // callbacks of each waiting request are run on the origin thread. | 
| 56 // | 38 // | 
| 57 // Thread safety: This class is not threadsafe, and must only be called | 39 // Thread safety: This class is not threadsafe, and must only be called | 
| 58 // from one thread! | 40 // from one thread! | 
| 59 // | 41 // | 
| 60 class HostResolver : public base::RefCounted<HostResolver> { | 42 class HostResolverImpl : public HostResolver { | 
| 61  public: | 43  public: | 
| 62   // The parameters for doing a Resolve(). |hostname| and |port| are required, |  | 
| 63   // the rest are optional (and have reasonable defaults). |  | 
| 64   class RequestInfo { |  | 
| 65    public: |  | 
| 66     RequestInfo(const std::string& hostname, int port) |  | 
| 67         : hostname_(hostname), |  | 
| 68           port_(port), |  | 
| 69           allow_cached_response_(true), |  | 
| 70           is_speculative_(false) {} |  | 
| 71 |  | 
| 72     const int port() const { return port_; } |  | 
| 73     const std::string& hostname() const { return hostname_; } |  | 
| 74 |  | 
| 75     bool allow_cached_response() const { return allow_cached_response_; } |  | 
| 76     void set_allow_cached_response(bool b) { allow_cached_response_ = b; } |  | 
| 77 |  | 
| 78     bool is_speculative() const { return is_speculative_; } |  | 
| 79     void set_is_speculative(bool b) { is_speculative_ = b; } |  | 
| 80 |  | 
| 81     const GURL& referrer() const { return referrer_; } |  | 
| 82     void set_referrer(const GURL& referrer) { referrer_ = referrer; } |  | 
| 83 |  | 
| 84    private: |  | 
| 85     // The hostname to resolve. |  | 
| 86     std::string hostname_; |  | 
| 87 |  | 
| 88     // The port number to set in the result's sockaddrs. |  | 
| 89     int port_; |  | 
| 90 |  | 
| 91     // Whether it is ok to return a result from the host cache. |  | 
| 92     bool allow_cached_response_; |  | 
| 93 |  | 
| 94     // Whether this request was started by the DNS prefetcher. |  | 
| 95     bool is_speculative_; |  | 
| 96 |  | 
| 97     // Optional data for consumption by observers. This is the URL of the |  | 
| 98     // page that lead us to the navigation, for DNS prefetcher's benefit. |  | 
| 99     GURL referrer_; |  | 
| 100   }; |  | 
| 101 |  | 
| 102   // Interface for observing the requests that flow through a HostResolver. |  | 
| 103   class Observer { |  | 
| 104    public: |  | 
| 105     virtual ~Observer() {} |  | 
| 106 |  | 
| 107     // Called at the start of HostResolver::Resolve(). |id| is a unique number |  | 
| 108     // given to the request, so it can be matched up with a corresponding call |  | 
| 109     // to OnFinishResolutionWithStatus() or OnCancelResolution(). |  | 
| 110     virtual void OnStartResolution(int id, const RequestInfo& info) = 0; |  | 
| 111 |  | 
| 112     // Called on completion of request |id|. Note that if the request was |  | 
| 113     // cancelled, OnCancelResolution() will be called instead. |  | 
| 114     virtual void OnFinishResolutionWithStatus(int id, bool was_resolved, |  | 
| 115                                               const RequestInfo& info) = 0; |  | 
| 116 |  | 
| 117     // Called when request |id| has been cancelled. A request is "cancelled" |  | 
| 118     // if either the HostResolver is destroyed while a resolution is in |  | 
| 119     // progress, or HostResolver::CancelRequest() is called. |  | 
| 120     virtual void OnCancelResolution(int id, const RequestInfo& info) = 0; |  | 
| 121   }; |  | 
| 122 |  | 
| 123   // Creates a HostResolver that caches up to |max_cache_entries| for | 44   // Creates a HostResolver that caches up to |max_cache_entries| for | 
| 124   // |cache_duration_ms| milliseconds. | 45   // |cache_duration_ms| milliseconds. |resolver_proc| is used to perform | 
| 125   // | 46   // the actual resolves; it must be thread-safe since it is run from | 
| 126   // TODO(eroman): Get rid of the default parameters as it violate google | 47   // multiple worker threads. If |resolver_proc| is NULL then the default | 
| 127   // style. This is temporary to help with refactoring. | 48   // host resolver procedure is used (which is SystemHostResolverProc except | 
| 128   HostResolver(int max_cache_entries = 100, int cache_duration_ms = 60000); | 49   // if overridden) | 
|  | 50   HostResolverImpl(HostResolverProc* resolver_proc, | 
|  | 51                    int max_cache_entries, | 
|  | 52                    int cache_duration_ms); | 
| 129 | 53 | 
| 130   // If any completion callbacks are pending when the resolver is destroyed, | 54   // If any completion callbacks are pending when the resolver is destroyed, | 
| 131   // the host resolutions are cancelled, and the completion callbacks will not | 55   // the host resolutions are cancelled, and the completion callbacks will not | 
| 132   // be called. | 56   // be called. | 
| 133   ~HostResolver(); | 57   virtual ~HostResolverImpl(); | 
| 134 | 58 | 
| 135   // Opaque type used to cancel a request. | 59   // HostResolver methods: | 
| 136   class Request; | 60   virtual int Resolve(const RequestInfo& info, AddressList* addresses, | 
| 137 | 61                       CompletionCallback* callback, RequestHandle* out_req); | 
| 138   // Resolves the given hostname (or IP address literal), filling out the | 62   virtual void CancelRequest(RequestHandle req); | 
| 139   // |addresses| object upon success.  The |info.port| parameter will be set as | 63   virtual void AddObserver(Observer* observer); | 
| 140   // the sin(6)_port field of the sockaddr_in{6} struct.  Returns OK if | 64   virtual void RemoveObserver(Observer* observer); | 
| 141   // successful or an error code upon failure. |  | 
| 142   // |  | 
| 143   // When callback is null, the operation completes synchronously. |  | 
| 144   // |  | 
| 145   // When callback is non-null, the operation will be performed asynchronously. |  | 
| 146   // ERR_IO_PENDING is returned if it has been scheduled successfully. Real |  | 
| 147   // result code will be passed to the completion callback. If |req| is |  | 
| 148   // non-NULL, then |*req| will be filled with a handle to the async request. |  | 
| 149   // This handle is not valid after the request has completed. |  | 
| 150   int Resolve(const RequestInfo& info, AddressList* addresses, |  | 
| 151               CompletionCallback* callback, Request** req); |  | 
| 152 |  | 
| 153   // Cancels the specified request. |req| is the handle returned by Resolve(). |  | 
| 154   // After a request is cancelled, its completion callback will not be called. |  | 
| 155   void CancelRequest(Request* req); |  | 
| 156 |  | 
| 157   // Adds an observer to this resolver. The observer will be notified of the |  | 
| 158   // start and completion of all requests (excluding cancellation). |observer| |  | 
| 159   // must remain valid for the duration of this HostResolver's lifetime. |  | 
| 160   void AddObserver(Observer* observer); |  | 
| 161 |  | 
| 162   // Unregisters an observer previously added by AddObserver(). |  | 
| 163   void RemoveObserver(Observer* observer); |  | 
| 164 | 65 | 
| 165   // TODO(eroman): temp hack for http://crbug.com/15513 | 66   // TODO(eroman): temp hack for http://crbug.com/15513 | 
| 166   void Shutdown(); | 67   virtual void Shutdown(); | 
| 167 | 68 | 
| 168  private: | 69  private: | 
| 169   class Job; | 70   class Job; | 
|  | 71   class Request; | 
| 170   typedef std::vector<Request*> RequestsList; | 72   typedef std::vector<Request*> RequestsList; | 
| 171   typedef base::hash_map<std::string, scoped_refptr<Job> > JobMap; | 73   typedef base::hash_map<std::string, scoped_refptr<Job> > JobMap; | 
| 172   typedef std::vector<Observer*> ObserversList; | 74   typedef std::vector<Observer*> ObserversList; | 
| 173 | 75 | 
|  | 76   // Returns the HostResolverProc to use for this instance. | 
|  | 77   HostResolverProc* effective_resolver_proc() const { | 
|  | 78     return resolver_proc_ ? | 
|  | 79         resolver_proc_.get() : HostResolverProc::GetDefault(); | 
|  | 80   } | 
|  | 81 | 
| 174   // Adds a job to outstanding jobs list. | 82   // Adds a job to outstanding jobs list. | 
| 175   void AddOutstandingJob(Job* job); | 83   void AddOutstandingJob(Job* job); | 
| 176 | 84 | 
| 177   // Returns the outstanding job for |hostname|, or NULL if there is none. | 85   // Returns the outstanding job for |hostname|, or NULL if there is none. | 
| 178   Job* FindOutstandingJob(const std::string& hostname); | 86   Job* FindOutstandingJob(const std::string& hostname); | 
| 179 | 87 | 
| 180   // Removes |job| from the outstanding jobs list. | 88   // Removes |job| from the outstanding jobs list. | 
| 181   void RemoveOutstandingJob(Job* job); | 89   void RemoveOutstandingJob(Job* job); | 
| 182 | 90 | 
| 183   // Callback for when |job| has completed with |error| and |addrlist|. | 91   // Callback for when |job| has completed with |error| and |addrlist|. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 206   // HostResolver gets deleted from within the callback). | 114   // HostResolver gets deleted from within the callback). | 
| 207   scoped_refptr<Job> cur_completing_job_; | 115   scoped_refptr<Job> cur_completing_job_; | 
| 208 | 116 | 
| 209   // The observers to notify when a request starts/ends. | 117   // The observers to notify when a request starts/ends. | 
| 210   ObserversList observers_; | 118   ObserversList observers_; | 
| 211 | 119 | 
| 212   // Monotonically increasing ID number to assign to the next request. | 120   // Monotonically increasing ID number to assign to the next request. | 
| 213   // Observers are the only consumers of this ID number. | 121   // Observers are the only consumers of this ID number. | 
| 214   int next_request_id_; | 122   int next_request_id_; | 
| 215 | 123 | 
|  | 124   // The procedure to use for resolving host names. This will be NULL, except | 
|  | 125   // in the case of unit-tests which inject custom host resolving behaviors. | 
|  | 126   scoped_refptr<HostResolverProc> resolver_proc_; | 
|  | 127 | 
| 216   // TODO(eroman): temp hack for http://crbug.com/15513 | 128   // TODO(eroman): temp hack for http://crbug.com/15513 | 
| 217   bool shutdown_; | 129   bool shutdown_; | 
| 218 | 130 | 
| 219   DISALLOW_COPY_AND_ASSIGN(HostResolver); | 131   DISALLOW_COPY_AND_ASSIGN(HostResolverImpl); | 
| 220 }; | 132 }; | 
| 221 | 133 | 
| 222 // This class represents the task of resolving a hostname (or IP address |  | 
| 223 // literal) to an AddressList object.  It wraps HostResolver to resolve only a |  | 
| 224 // single hostname at a time and cancels this request when going out of scope. |  | 
| 225 class SingleRequestHostResolver { |  | 
| 226  public: |  | 
| 227   explicit SingleRequestHostResolver(HostResolver* resolver); |  | 
| 228 |  | 
| 229   // If a completion callback is pending when the resolver is destroyed, the |  | 
| 230   // host resolution is cancelled, and the completion callback will not be |  | 
| 231   // called. |  | 
| 232   ~SingleRequestHostResolver(); |  | 
| 233 |  | 
| 234   // Resolves the given hostname (or IP address literal), filling out the |  | 
| 235   // |addresses| object upon success. See HostResolver::Resolve() for details. |  | 
| 236   int Resolve(const HostResolver::RequestInfo& info, |  | 
| 237               AddressList* addresses, CompletionCallback* callback); |  | 
| 238 |  | 
| 239  private: |  | 
| 240   // Callback for when the request to |resolver_| completes, so we dispatch |  | 
| 241   // to the user's callback. |  | 
| 242   void OnResolveCompletion(int result); |  | 
| 243 |  | 
| 244   // The actual host resolver that will handle the request. |  | 
| 245   scoped_refptr<HostResolver> resolver_; |  | 
| 246 |  | 
| 247   // The current request (if any). |  | 
| 248   HostResolver::Request* cur_request_; |  | 
| 249   CompletionCallback* cur_request_callback_; |  | 
| 250 |  | 
| 251   // Completion callback for when request to |resolver_| completes. |  | 
| 252   net::CompletionCallbackImpl<SingleRequestHostResolver> callback_; |  | 
| 253 |  | 
| 254   DISALLOW_COPY_AND_ASSIGN(SingleRequestHostResolver); |  | 
| 255 }; |  | 
| 256 |  | 
| 257 // A helper class used in unit tests to alter hostname mappings.  See |  | 
| 258 // SetHostMapper for details. |  | 
| 259 class HostMapper : public base::RefCountedThreadSafe<HostMapper> { |  | 
| 260  public: |  | 
| 261   virtual ~HostMapper() {} |  | 
| 262 |  | 
| 263   // Returns possibly altered hostname, or empty string to simulate |  | 
| 264   // a failed lookup. |  | 
| 265   virtual std::string Map(const std::string& host) = 0; |  | 
| 266 |  | 
| 267  protected: |  | 
| 268   // Ask previous host mapper (if set) for mapping of given host. |  | 
| 269   std::string MapUsingPrevious(const std::string& host); |  | 
| 270 |  | 
| 271  private: |  | 
| 272   friend class ScopedHostMapper; |  | 
| 273 |  | 
| 274   // Set mapper to ask when this mapper doesn't want to modify the result. |  | 
| 275   void set_previous_mapper(HostMapper* mapper) { |  | 
| 276     previous_mapper_ = mapper; |  | 
| 277   } |  | 
| 278 |  | 
| 279   scoped_refptr<HostMapper> previous_mapper_; |  | 
| 280 }; |  | 
| 281 |  | 
| 282 #ifdef UNIT_TEST |  | 
| 283 // This function is designed to allow unit tests to override the behavior of |  | 
| 284 // HostResolver.  For example, a HostMapper instance can force all hostnames |  | 
| 285 // to map to a fixed IP address such as 127.0.0.1. |  | 
| 286 // |  | 
| 287 // The previously set HostMapper (or NULL if there was none) is returned. |  | 
| 288 // |  | 
| 289 // NOTE: This function is not thread-safe, so take care to only call this |  | 
| 290 // function while there are no outstanding HostResolver instances. |  | 
| 291 // |  | 
| 292 // NOTE: In most cases, you should use ScopedHostMapper instead, which is |  | 
| 293 // defined in host_resolver_unittest.h |  | 
| 294 // |  | 
| 295 HostMapper* SetHostMapper(HostMapper* host_mapper); |  | 
| 296 #endif |  | 
| 297 |  | 
| 298 }  // namespace net | 134 }  // namespace net | 
| 299 | 135 | 
| 300 #endif  // NET_BASE_HOST_RESOLVER_H_ | 136 #endif  // NET_BASE_HOST_RESOLVER_IMPL_H_ | 
| OLD | NEW | 
|---|