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_DNSRR_RESOLVER_H_ 6#define NET_BASE_DNSRR_RESOLVER_H_ 7#pragma once 8 9#include <map> 10#include <string> 11#include <utility> 12#include <vector> 13 14#include "base/basictypes.h" 15#include "base/memory/ref_counted.h" 16#include "base/threading/non_thread_safe.h" 17#include "base/time.h" 18#include "build/build_config.h" 19#include "net/base/completion_callback.h" 20#include "net/base/network_change_notifier.h" 21 22namespace net { 23 24// RRResponse contains the result of a successful request for a resource record. 25struct RRResponse { 26 RRResponse(); 27 ~RRResponse(); 28 29 // HasExpired returns true if |fetch_time| + |ttl| is less than 30 // |current_time|. 31 bool HasExpired(base::Time current_time) const; 32 33 // For testing only 34 bool ParseFromResponse(const uint8* data, unsigned len, 35 uint16 rrtype_requested); 36 37 // name contains the canonical name of the resulting domain. If the queried 38 // name was a CNAME then this can differ. 39 std::string name; 40 // ttl contains the TTL of the resource records. 41 uint32 ttl; 42 // dnssec is true if the response was DNSSEC validated. 43 bool dnssec; 44 std::vector<std::string> rrdatas; 45 // sigs contains the RRSIG records returned. 46 std::vector<std::string> signatures; 47 // fetch_time is the time at which the response was received from the 48 // network. 49 base::Time fetch_time; 50 // negative is true if this is a negative cache entry, i.e. is a placeholder 51 // to remember that a given RR doesn't exist. 52 bool negative; 53}; 54 55class BoundNetLog; 56class RRResolverWorker; 57class RRResolverJob; 58 59// DnsRRResolver resolves arbitary DNS resource record types. It should not be 60// confused with HostResolver and should not be used to resolve A/AAAA records. 61// 62// HostResolver exists to lookup addresses and there are many details about 63// address resolution over and above DNS (i.e. Bonjour, VPNs etc). 64// 65// DnsRRResolver should only be used when the data is specifically DNS data and 66// the name is a fully qualified DNS domain. 67// 68// A DnsRRResolver must be used from the MessageLoop which created it. 69class DnsRRResolver : public base::NonThreadSafe, 70 public NetworkChangeNotifier::IPAddressObserver { 71 public: 72 typedef intptr_t Handle; 73 74 enum { 75 kInvalidHandle = 0, 76 }; 77 78 enum { 79 // Try harder to get a DNSSEC signed response. This doesn't mean that the 80 // RRResponse will always have the dnssec bit set. 81 FLAG_WANT_DNSSEC = 1, 82 }; 83 84 DnsRRResolver(); 85 ~DnsRRResolver(); 86 87 uint64 requests() const { return requests_; } 88 uint64 cache_hits() const { return cache_hits_; } 89 uint64 inflight_joins() const { return inflight_joins_; } 90 91 // Resolve starts the resolution process. When complete, |callback| is called 92 // with a result. If the result is |OK| then |response| is filled with the 93 // result of the resolution. Note that |callback| is called via the current 94 // MessageLoop. 95 // 96 // This returns a handle value which can be passed to |CancelResolve|. If 97 // this function returns kInvalidHandle then the resolution failed 98 // immediately because it was improperly formed. 99 Handle Resolve(const std::string& name, uint16 rrtype, 100 uint16 flags, CompletionCallback* callback, 101 RRResponse* response, int priority, 102 const BoundNetLog& netlog); 103 104 // CancelResolve cancels an inflight lookup. The callback for this lookup 105 // must not have already been called. 106 void CancelResolve(Handle handle); 107 108 // Implementation of NetworkChangeNotifier::IPAddressObserver 109 virtual void OnIPAddressChanged(); 110 111 private: 112 friend class RRResolverWorker; 113 114 void HandleResult(const std::string& name, uint16 rrtype, int result, 115 const RRResponse& response); 116 117 // cache_ maps from a request to a cached response. The cached answer may 118 // have expired and the size of |cache_| must be <= kMaxCacheEntries. 119 // < name , rrtype> 120 std::map<std::pair<std::string, uint16>, RRResponse> cache_; 121 // inflight_ maps from a request to an active resolution which is taking 122 // place. 123 std::map<std::pair<std::string, uint16>, RRResolverJob*> inflight_; 124 125 uint64 requests_; 126 uint64 cache_hits_; 127 uint64 inflight_joins_; 128 129 bool in_destructor_; 130 131 DISALLOW_COPY_AND_ASSIGN(DnsRRResolver); 132}; 133 134} // namespace net 135 136#endif // NET_BASE_DNSRR_RESOLVER_H_ 137