Home | History | Annotate | Download | only in base
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_BASE_HOST_RESOLVER_H_
      6 #define NET_BASE_HOST_RESOLVER_H_
      7 
      8 #include <string>
      9 
     10 #include "base/ref_counted.h"
     11 #include "googleurl/src/gurl.h"
     12 #include "net/base/address_family.h"
     13 #include "net/base/completion_callback.h"
     14 #include "net/base/request_priority.h"
     15 
     16 class MessageLoop;
     17 
     18 namespace net {
     19 
     20 class AddressList;
     21 class HostCache;
     22 class LoadLog;
     23 class NetworkChangeNotifier;
     24 
     25 // This class represents the task of resolving hostnames (or IP address
     26 // literal) to an AddressList object.
     27 //
     28 // HostResolver can handle multiple requests at a time, so when cancelling a
     29 // request the RequestHandle 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 class HostResolver : public base::RefCountedThreadSafe<HostResolver> {
     35  public:
     36   // The parameters for doing a Resolve(). |hostname| and |port| are required,
     37   // the rest are optional (and have reasonable defaults).
     38   class RequestInfo {
     39    public:
     40     RequestInfo(const std::string& hostname, int port)
     41         : hostname_(hostname),
     42           address_family_(ADDRESS_FAMILY_UNSPECIFIED),
     43           port_(port),
     44           allow_cached_response_(true),
     45           is_speculative_(false),
     46           priority_(MEDIUM) {}
     47 
     48     const int port() const { return port_; }
     49     const std::string& hostname() const { return hostname_; }
     50 
     51     AddressFamily address_family() const { return address_family_; }
     52     void set_address_family(AddressFamily address_family) {
     53       address_family_ = address_family;
     54     }
     55 
     56     bool allow_cached_response() const { return allow_cached_response_; }
     57     void set_allow_cached_response(bool b) { allow_cached_response_ = b; }
     58 
     59     bool is_speculative() const { return is_speculative_; }
     60     void set_is_speculative(bool b) { is_speculative_ = b; }
     61 
     62     RequestPriority priority() const { return priority_; }
     63     void set_priority(RequestPriority priority) { priority_ = priority; }
     64 
     65     const GURL& referrer() const { return referrer_; }
     66     void set_referrer(const GURL& referrer) { referrer_ = referrer; }
     67 
     68    private:
     69     // The hostname to resolve.
     70     std::string hostname_;
     71 
     72     // The address family to restrict results to.
     73     AddressFamily address_family_;
     74 
     75     // The port number to set in the result's sockaddrs.
     76     int port_;
     77 
     78     // Whether it is ok to return a result from the host cache.
     79     bool allow_cached_response_;
     80 
     81     // Whether this request was started by the DNS prefetcher.
     82     bool is_speculative_;
     83 
     84     // The priority for the request.
     85     RequestPriority priority_;
     86 
     87     // Optional data for consumption by observers. This is the URL of the
     88     // page that lead us to the navigation, for DNS prefetcher's benefit.
     89     GURL referrer_;
     90   };
     91 
     92   // Interface for observing the requests that flow through a HostResolver.
     93   class Observer {
     94    public:
     95     virtual ~Observer() {}
     96 
     97     // Called at the start of HostResolver::Resolve(). |id| is a unique number
     98     // given to the request, so it can be matched up with a corresponding call
     99     // to OnFinishResolutionWithStatus() or OnCancelResolution().
    100     virtual void OnStartResolution(int id, const RequestInfo& info) = 0;
    101 
    102     // Called on completion of request |id|. Note that if the request was
    103     // cancelled, OnCancelResolution() will be called instead.
    104     virtual void OnFinishResolutionWithStatus(int id, bool was_resolved,
    105                                               const RequestInfo& info) = 0;
    106 
    107     // Called when request |id| has been cancelled. A request is "cancelled"
    108     // if either the HostResolver is destroyed while a resolution is in
    109     // progress, or HostResolver::CancelRequest() is called.
    110     virtual void OnCancelResolution(int id, const RequestInfo& info) = 0;
    111   };
    112 
    113   // Opaque type used to cancel a request.
    114   typedef void* RequestHandle;
    115 
    116   // Resolves the given hostname (or IP address literal), filling out the
    117   // |addresses| object upon success.  The |info.port| parameter will be set as
    118   // the sin(6)_port field of the sockaddr_in{6} struct.  Returns OK if
    119   // successful or an error code upon failure.
    120   //
    121   // When callback is null, the operation completes synchronously.
    122   //
    123   // When callback is non-null, the operation may be performed asynchronously.
    124   // If the operation cannnot be completed synchronously, ERR_IO_PENDING will
    125   // be returned and the real result code will be passed to the completion
    126   // callback.  Otherwise the result code is returned immediately from this
    127   // call.
    128   // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to
    129   // the async request. This handle is not valid after the request has
    130   // completed.
    131   //
    132   // Profiling information for the request is saved to |load_log| if non-NULL.
    133   virtual int Resolve(const RequestInfo& info,
    134                       AddressList* addresses,
    135                       CompletionCallback* callback,
    136                       RequestHandle* out_req,
    137                       LoadLog* load_log) = 0;
    138 
    139   // Cancels the specified request. |req| is the handle returned by Resolve().
    140   // After a request is cancelled, its completion callback will not be called.
    141   virtual void CancelRequest(RequestHandle req) = 0;
    142 
    143   // Adds an observer to this resolver. The observer will be notified of the
    144   // start and completion of all requests (excluding cancellation). |observer|
    145   // must remain valid for the duration of this HostResolver's lifetime.
    146   virtual void AddObserver(Observer* observer) = 0;
    147 
    148   // Unregisters an observer previously added by AddObserver().
    149   virtual void RemoveObserver(Observer* observer) = 0;
    150 
    151   // TODO(eroman): temp hack for http://crbug.com/18373
    152   virtual void Shutdown() = 0;
    153 
    154   // Sets the default AddressFamily to use when requests have left it
    155   // unspecified. For example, this could be used to restrict resolution
    156   // results to AF_INET by passing in ADDRESS_FAMILY_IPV4, or to
    157   // AF_INET6 by passing in ADDRESS_FAMILY_IPV6.
    158   virtual void SetDefaultAddressFamily(AddressFamily address_family) {}
    159 
    160   // Returns true if this HostResolver is an instance of HostResolverImpl.
    161   // Used primarily to expose additional functionality on the
    162   // about:net-internals page.
    163   virtual bool IsHostResolverImpl() { return false; }
    164 
    165  protected:
    166   friend class base::RefCountedThreadSafe<HostResolver>;
    167 
    168   HostResolver() { }
    169 
    170   // If any completion callbacks are pending when the resolver is destroyed,
    171   // the host resolutions are cancelled, and the completion callbacks will not
    172   // be called.
    173   virtual ~HostResolver() {}
    174 
    175  private:
    176   DISALLOW_COPY_AND_ASSIGN(HostResolver);
    177 };
    178 
    179 // This class represents the task of resolving a hostname (or IP address
    180 // literal) to an AddressList object.  It wraps HostResolver to resolve only a
    181 // single hostname at a time and cancels this request when going out of scope.
    182 class SingleRequestHostResolver {
    183  public:
    184   explicit SingleRequestHostResolver(HostResolver* resolver);
    185 
    186   // If a completion callback is pending when the resolver is destroyed, the
    187   // host resolution is cancelled, and the completion callback will not be
    188   // called.
    189   ~SingleRequestHostResolver();
    190 
    191   // Resolves the given hostname (or IP address literal), filling out the
    192   // |addresses| object upon success. See HostResolver::Resolve() for details.
    193   int Resolve(const HostResolver::RequestInfo& info,
    194               AddressList* addresses,
    195               CompletionCallback* callback,
    196               LoadLog* load_log);
    197 
    198   // Cancels the in-progress request, if any. This prevents the callback
    199   // from being invoked. Resolve() can be called again after cancelling.
    200   void Cancel();
    201 
    202  private:
    203   // Callback for when the request to |resolver_| completes, so we dispatch
    204   // to the user's callback.
    205   void OnResolveCompletion(int result);
    206 
    207   // The actual host resolver that will handle the request.
    208   scoped_refptr<HostResolver> resolver_;
    209 
    210   // The current request (if any).
    211   HostResolver::RequestHandle cur_request_;
    212   CompletionCallback* cur_request_callback_;
    213 
    214   // Completion callback for when request to |resolver_| completes.
    215   net::CompletionCallbackImpl<SingleRequestHostResolver> callback_;
    216 
    217   DISALLOW_COPY_AND_ASSIGN(SingleRequestHostResolver);
    218 };
    219 
    220 // Creates a HostResolver implementation that queries the underlying system.
    221 // (Except if a unit-test has changed the global HostResolverProc using
    222 // ScopedHostResolverProc to intercept requests to the system).
    223 // |network_change_notifier| must outlive HostResolver.  It can optionally be
    224 // NULL, in which case HostResolver will not respond to network changes.
    225 HostResolver* CreateSystemHostResolver(
    226     NetworkChangeNotifier* network_change_notifier);
    227 
    228 }  // namespace net
    229 
    230 #endif  // NET_BASE_HOST_RESOLVER_H_
    231