summaryrefslogtreecommitdiffstats
path: root/net/base/async_host_resolver.h
blob: 42ba997e78f440226576421d71c99d27d184494c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_BASE_ASYNC_HOST_RESOLVER_H_
#define NET_BASE_ASYNC_HOST_RESOLVER_H_
#pragma once

#include <list>
#include <map>
#include <vector>

#include "base/observer_list.h"
#include "base/threading/non_thread_safe.h"
#include "net/base/address_family.h"
#include "net/base/dns_transaction.h"
#include "net/base/host_resolver.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_log.h"
#include "net/base/rand_callback.h"

namespace net {

class AddressesList;
class ClientSocketFactory;

class NET_API AsyncHostResolver : public HostResolver,
                                  public DnsTransaction::Delegate,
                                  public base::NonThreadSafe {
 public:
  AsyncHostResolver(const IPEndPoint& dns_server,
                    size_t max_transactions,
                    size_t max_pending_requests_,
                    const RandIntCallback& rand_int,
                    ClientSocketFactory* factory,
                    NetLog* net_log);
  virtual ~AsyncHostResolver();

  // HostResolver interface
  virtual int Resolve(const RequestInfo& info,
                      AddressList* addresses,
                      CompletionCallback* callback,
                      RequestHandle* out_req,
                      const BoundNetLog& source_net_log) OVERRIDE;
  virtual void CancelRequest(RequestHandle req_handle) OVERRIDE;
  virtual void AddObserver(HostResolver::Observer* observer) OVERRIDE;
  virtual void RemoveObserver(HostResolver::Observer* observer) OVERRIDE;
  virtual void SetDefaultAddressFamily(AddressFamily address_family) OVERRIDE;
  virtual AddressFamily GetDefaultAddressFamily() const OVERRIDE;
  virtual HostResolverImpl* GetAsHostResolverImpl() OVERRIDE;

  // DnsTransaction::Delegate interface
  virtual void OnTransactionComplete(
      int result,
      const DnsTransaction* transaction,
      const IPAddressList& ip_addresses) OVERRIDE;

 private:
  FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, QueuedLookup);
  FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest, CancelPendingLookup);
  FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest,
                           ResolverDestructionCancelsLookups);
  FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest,
                           OverflowQueueWithLowPriorityLookup);
  FRIEND_TEST_ALL_PREFIXES(AsyncHostResolverTest,
                           OverflowQueueWithHighPriorityLookup);

  class Request;

  typedef DnsTransaction::Key Key;
  typedef std::list<Request*> RequestList;
  typedef std::list<const DnsTransaction*> TransactionList;
  typedef std::map<Key, RequestList> KeyRequestListMap;

  // Create a new request for the incoming Resolve() call.
  Request* CreateNewRequest(const RequestInfo& info,
                            const std::string& dns_name,
                            CompletionCallback* callback,
                            AddressList* addresses,
                            const BoundNetLog& source_net_log);

  // Called when a request has just been started.
  void OnStart(Request* request);

  // Called when a request has just completed (before its callback is run).
  void OnFinish(Request* request, int result);

  // Called when a request has been cancelled.
  void OnCancel(Request* request);

  // If there is an in-progress transaction for Request->key(), this will
  // attach |request| to the respective list.
  bool AttachToRequestList(Request* request);

  // Will start a new transaction for |request|, will insert a new key in
  // |requestlist_map_| and append |request| to the respective list.
  int StartNewTransactionFor(Request* request);

  // Will enqueue |request| in |pending_requests_|.
  int Enqueue(Request* request);

  // A helper used by Enqueue to insert |request| into |pending_requests_|.
  Request* Insert(Request* request);

  // Returns the number of pending requests.
  size_t GetNumPending();

  // Removes and returns a pointer to the lowest/highest priority request
  // from |pending_requests_|.
  Request* RemoveLowest();
  Request* RemoveHighest();

  // Once a transaction has completed, called to start a new transaction if
  // there are pending requests.
  void ProcessPending();

  // Maximum number of concurrent transactions.
  size_t max_transactions_;

  // List of current transactions.
  TransactionList transactions_;

  // A map from Key to a list of requests waiting for the Key to resolve.
  KeyRequestListMap requestlist_map_;

  // Maximum number of pending requests.
  size_t max_pending_requests_;

  // Queues based on priority for putting pending requests.
  RequestList pending_requests_[NUM_PRIORITIES];

  // DNS server to which queries will be setn.
  IPEndPoint dns_server_;

  // Callback to be passed to DnsTransaction for generating DNS query ids.
  RandIntCallback rand_int_cb_;

  // Also passed to DnsTransaction; it's a dependency injection to aid
  // testing, outside of unit tests, its value is always NULL.
  ClientSocketFactory* factory_;

  // The observers to notify when a request starts/ends.
  ObserverList<HostResolver::Observer> observers_;

  // Monotonically increasing ID number to assign to the next request.
  // Observers are the only consumers of this ID number.
  int next_request_id_;

  NetLog* net_log_;

  DISALLOW_COPY_AND_ASSIGN(AsyncHostResolver);
};

}  // namespace net

#endif  // NET_BASE_ASYNC_HOST_RESOLVER_H_