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
16class MessageLoop;
17
18namespace net {
19
20class AddressList;
21class HostCache;
22class LoadLog;
23class 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).
34class 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.
182class 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.
225HostResolver* CreateSystemHostResolver(
226    NetworkChangeNotifier* network_change_notifier);
227
228}  // namespace net
229
230#endif  // NET_BASE_HOST_RESOLVER_H_
231