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_H_
6#define NET_BASE_HOST_RESOLVER_H_
7#pragma once
8
9#include <string>
10
11#include "base/memory/scoped_ptr.h"
12#include "googleurl/src/gurl.h"
13#include "net/base/address_family.h"
14#include "net/base/completion_callback.h"
15#include "net/base/host_port_pair.h"
16#include "net/base/net_export.h"
17#include "net/base/request_priority.h"
18
19namespace net {
20
21class AddressList;
22class BoundNetLog;
23class HostResolverImpl;
24class HostResolverProc;
25class NetLog;
26
27// This class represents the task of resolving hostnames (or IP address
28// literal) to an AddressList object.
29//
30// HostResolver can handle multiple requests at a time, so when cancelling a
31// request the RequestHandle that was returned by Resolve() needs to be
32// given.  A simpler alternative for consumers that only have 1 outstanding
33// request at a time is to create a SingleRequestHostResolver wrapper around
34// HostResolver (which will automatically cancel the single request when it
35// goes out of scope).
36class NET_EXPORT HostResolver {
37 public:
38  // The parameters for doing a Resolve(). A hostname and port are required,
39  // the rest are optional (and have reasonable defaults).
40  class NET_EXPORT RequestInfo {
41   public:
42    explicit RequestInfo(const HostPortPair& host_port_pair);
43
44    const HostPortPair& host_port_pair() const { return host_port_pair_; }
45    void set_host_port_pair(const HostPortPair& host_port_pair) {
46      host_port_pair_ = host_port_pair;
47    }
48
49    int port() const { return host_port_pair_.port(); }
50    const std::string& hostname() const { return host_port_pair_.host(); }
51
52    AddressFamily address_family() const { return address_family_; }
53    void set_address_family(AddressFamily address_family) {
54      address_family_ = address_family;
55    }
56
57    HostResolverFlags host_resolver_flags() const {
58      return host_resolver_flags_;
59    }
60    void set_host_resolver_flags(HostResolverFlags host_resolver_flags) {
61      host_resolver_flags_ = host_resolver_flags;
62    }
63
64    bool allow_cached_response() const { return allow_cached_response_; }
65    void set_allow_cached_response(bool b) { allow_cached_response_ = b; }
66
67    bool only_use_cached_response() const { return only_use_cached_response_; }
68    void set_only_use_cached_response(bool b) { only_use_cached_response_ = b; }
69
70    bool is_speculative() const { return is_speculative_; }
71    void set_is_speculative(bool b) { is_speculative_ = b; }
72
73    RequestPriority priority() const { return priority_; }
74    void set_priority(RequestPriority priority) { priority_ = priority; }
75
76    const GURL& referrer() const { return referrer_; }
77    void set_referrer(const GURL& referrer) { referrer_ = referrer; }
78
79   private:
80    // The hostname to resolve, and the port to use in resulting sockaddrs.
81    HostPortPair host_port_pair_;
82
83    // The address family to restrict results to.
84    AddressFamily address_family_;
85
86    // Flags to use when resolving this request.
87    HostResolverFlags host_resolver_flags_;
88
89    // Whether it is ok to return a result from the host cache.
90    bool allow_cached_response_;
91
92    // Whether the response will only use the cache.
93    bool only_use_cached_response_;
94
95    // Whether this request was started by the DNS prefetcher.
96    bool is_speculative_;
97
98    // The priority for the request.
99    RequestPriority priority_;
100
101    // Optional data for consumption by observers. This is the URL of the
102    // page that lead us to the navigation, for DNS prefetcher's benefit.
103    GURL referrer_;
104  };
105
106  // Interface for observing the requests that flow through a HostResolver.
107  class Observer {
108   public:
109    virtual ~Observer() {}
110
111    // Called at the start of HostResolver::Resolve(). |id| is a unique number
112    // given to the request, so it can be matched up with a corresponding call
113    // to OnFinishResolutionWithStatus() or OnCancelResolution().
114    virtual void OnStartResolution(int id, const RequestInfo& info) = 0;
115
116    // Called on completion of request |id|. Note that if the request was
117    // cancelled, OnCancelResolution() will be called instead.
118    virtual void OnFinishResolutionWithStatus(int id, bool was_resolved,
119                                              const RequestInfo& info) = 0;
120
121    // Called when request |id| has been cancelled. A request is "cancelled"
122    // if either the HostResolver is destroyed while a resolution is in
123    // progress, or HostResolver::CancelRequest() is called.
124    virtual void OnCancelResolution(int id, const RequestInfo& info) = 0;
125  };
126
127  // Opaque type used to cancel a request.
128  typedef void* RequestHandle;
129
130  // This value can be passed into CreateSystemHostResolver as the
131  // |max_concurrent_resolves| parameter. It will select a default level of
132  // concurrency.
133  static const size_t kDefaultParallelism = 0;
134
135  // If any completion callbacks are pending when the resolver is destroyed,
136  // the host resolutions are cancelled, and the completion callbacks will not
137  // be called.
138  virtual ~HostResolver();
139
140  // Resolves the given hostname (or IP address literal), filling out the
141  // |addresses| object upon success.  The |info.port| parameter will be set as
142  // the sin(6)_port field of the sockaddr_in{6} struct.  Returns OK if
143  // successful or an error code upon failure.
144  //
145  // When callback is null, the operation completes synchronously.
146  //
147  // When callback is non-null, the operation may be performed asynchronously.
148  // If the operation cannnot be completed synchronously, ERR_IO_PENDING will
149  // be returned and the real result code will be passed to the completion
150  // callback.  Otherwise the result code is returned immediately from this
151  // call.
152  // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to
153  // the async request. This handle is not valid after the request has
154  // completed.
155  //
156  // Profiling information for the request is saved to |net_log| if non-NULL.
157  virtual int Resolve(const RequestInfo& info,
158                      AddressList* addresses,
159                      CompletionCallback* callback,
160                      RequestHandle* out_req,
161                      const BoundNetLog& net_log) = 0;
162
163  // Cancels the specified request. |req| is the handle returned by Resolve().
164  // After a request is cancelled, its completion callback will not be called.
165  virtual void CancelRequest(RequestHandle req) = 0;
166
167  // Adds an observer to this resolver. The observer will be notified of the
168  // start and completion of all requests (excluding cancellation). |observer|
169  // must remain valid for the duration of this HostResolver's lifetime.
170  virtual void AddObserver(Observer* observer) = 0;
171
172  // Unregisters an observer previously added by AddObserver().
173  virtual void RemoveObserver(Observer* observer) = 0;
174
175  // Sets the default AddressFamily to use when requests have left it
176  // unspecified. For example, this could be used to restrict resolution
177  // results to AF_INET by passing in ADDRESS_FAMILY_IPV4, or to
178  // AF_INET6 by passing in ADDRESS_FAMILY_IPV6.
179  virtual void SetDefaultAddressFamily(AddressFamily address_family) {}
180  virtual AddressFamily GetDefaultAddressFamily() const;
181
182  // Returns |this| cast to a HostResolverImpl*, or NULL if the subclass
183  // is not compatible with HostResolverImpl. Used primarily to expose
184  // additional functionality on the about:net-internals page.
185  virtual HostResolverImpl* GetAsHostResolverImpl();
186
187  // Does additional cleanup prior to destruction.
188  virtual void Shutdown() {}
189
190 protected:
191  HostResolver();
192
193 private:
194  DISALLOW_COPY_AND_ASSIGN(HostResolver);
195};
196
197// This class represents the task of resolving a hostname (or IP address
198// literal) to an AddressList object.  It wraps HostResolver to resolve only a
199// single hostname at a time and cancels this request when going out of scope.
200class NET_EXPORT SingleRequestHostResolver {
201 public:
202  // |resolver| must remain valid for the lifetime of |this|.
203  explicit SingleRequestHostResolver(HostResolver* resolver);
204
205  // If a completion callback is pending when the resolver is destroyed, the
206  // host resolution is cancelled, and the completion callback will not be
207  // called.
208  ~SingleRequestHostResolver();
209
210  // Resolves the given hostname (or IP address literal), filling out the
211  // |addresses| object upon success. See HostResolver::Resolve() for details.
212  int Resolve(const HostResolver::RequestInfo& info,
213              AddressList* addresses,
214              CompletionCallback* callback,
215              const BoundNetLog& net_log);
216
217  // Cancels the in-progress request, if any. This prevents the callback
218  // from being invoked. Resolve() can be called again after cancelling.
219  void Cancel();
220
221 private:
222  // Callback for when the request to |resolver_| completes, so we dispatch
223  // to the user's callback.
224  void OnResolveCompletion(int result);
225
226  // The actual host resolver that will handle the request.
227  HostResolver* const resolver_;
228
229  // The current request (if any).
230  HostResolver::RequestHandle cur_request_;
231  CompletionCallback* cur_request_callback_;
232
233  // Completion callback for when request to |resolver_| completes.
234  CompletionCallbackImpl<SingleRequestHostResolver> callback_;
235
236  DISALLOW_COPY_AND_ASSIGN(SingleRequestHostResolver);
237};
238
239// Creates a HostResolver implementation using |resolver_proc| as resolver,
240// (which if NULL, will default to getaddrinfo() wrapper) that queries the
241// underlying system, |max_concurrent_resolves| is how many resolve
242// requests will be allowed to run in parallel. Pass
243// HostResolver::kDefaultParallelism to choose a default value.
244NET_EXPORT HostResolver* CreateSystemHostResolver(size_t max_concurrent_resolves,
245                                                  HostResolverProc* resolver_proc,
246                                                  NetLog* net_log);
247
248}  // namespace net
249
250#endif  // NET_BASE_HOST_RESOLVER_H_
251