summaryrefslogtreecommitdiffstats
path: root/net/base/dnsrr_resolver.h
blob: ab30f505db7402ebbdf083e80ba8aebc7ecbf8a7 (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
// 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_DNSRR_RESOLVER_H_
#define NET_BASE_DNSRR_RESOLVER_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/threading/non_thread_safe.h"
#include "base/time.h"
#include "build/build_config.h"
#include "net/base/completion_callback.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"

namespace net {

// RRResponse contains the result of a successful request for a resource record.
struct NET_EXPORT_PRIVATE RRResponse {
  RRResponse();
  ~RRResponse();

  // HasExpired returns true if |fetch_time| + |ttl| is less than
  // |current_time|.
  bool HasExpired(base::Time current_time) const;

#if defined(OS_POSIX) && !defined(OS_ANDROID)
  // For testing only
  bool ParseFromResponse(const uint8* data, unsigned len,
                         uint16 rrtype_requested);
#endif

  // name contains the canonical name of the resulting domain. If the queried
  // name was a CNAME then this can differ.
  std::string name;
  // ttl contains the TTL of the resource records.
  uint32 ttl;
  // dnssec is true if the response was DNSSEC validated.
  bool dnssec;
  std::vector<std::string> rrdatas;
  // sigs contains the RRSIG records returned.
  std::vector<std::string> signatures;
  // fetch_time is the time at which the response was received from the
  // network.
  base::Time fetch_time;
  // negative is true if this is a negative cache entry, i.e. is a placeholder
  // to remember that a given RR doesn't exist.
  bool negative;
};

class BoundNetLog;
class RRResolverWorker;
class RRResolverJob;

// DnsRRResolver resolves arbitary DNS resource record types. It should not be
// confused with HostResolver and should not be used to resolve A/AAAA records.
//
// HostResolver exists to lookup addresses and there are many details about
// address resolution over and above DNS (i.e. Bonjour, VPNs etc).
//
// DnsRRResolver should only be used when the data is specifically DNS data and
// the name is a fully qualified DNS domain.
//
// A DnsRRResolver must be used from the MessageLoop which created it.
class NET_EXPORT DnsRRResolver
    : NON_EXPORTED_BASE(public base::NonThreadSafe),
      public NetworkChangeNotifier::IPAddressObserver {
 public:
  typedef intptr_t Handle;

  enum {
    kInvalidHandle = 0,
  };

  enum {
    // Try harder to get a DNSSEC signed response. This doesn't mean that the
    // RRResponse will always have the dnssec bit set.
    FLAG_WANT_DNSSEC = 1,
  };

  DnsRRResolver();
  virtual ~DnsRRResolver();

  uint64 requests() const { return requests_; }
  uint64 cache_hits() const { return cache_hits_; }
  uint64 inflight_joins() const { return inflight_joins_; }

  // Resolve starts the resolution process. When complete, |callback| is called
  // with a result. If the result is |OK| then |response| is filled with the
  // result of the resolution. Note that |callback| is called via the current
  // MessageLoop.
  //
  // This returns a handle value which can be passed to |CancelResolve|. If
  // this function returns kInvalidHandle then the resolution failed
  // immediately because it was improperly formed.
  Handle Resolve(const std::string& name, uint16 rrtype,
                 uint16 flags, const CompletionCallback& callback,
                 RRResponse* response, int priority,
                 const BoundNetLog& netlog);

  // CancelResolve cancels an inflight lookup. The callback for this lookup
  // must not have already been called.
  void CancelResolve(Handle handle);

  // Implementation of NetworkChangeNotifier::IPAddressObserver
  virtual void OnIPAddressChanged() OVERRIDE;

 private:
  friend class RRResolverWorker;

  void HandleResult(const std::string& name, uint16 rrtype, int result,
                    const RRResponse& response);

  // cache_ maps from a request to a cached response. The cached answer may
  // have expired and the size of |cache_| must be <= kMaxCacheEntries.
  //                < name      , rrtype>
  std::map<std::pair<std::string, uint16>, RRResponse> cache_;
  // inflight_ maps from a request to an active resolution which is taking
  // place.
  std::map<std::pair<std::string, uint16>, RRResolverJob*> inflight_;

  uint64 requests_;
  uint64 cache_hits_;
  uint64 inflight_joins_;

  bool in_destructor_;

  DISALLOW_COPY_AND_ASSIGN(DnsRRResolver);
};

}  // namespace net

#endif  // NET_BASE_DNSRR_RESOLVER_H_