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 22 namespace net { 23 24 // RRResponse contains the result of a successful request for a resource record. 25 struct 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 55 class BoundNetLog; 56 class RRResolverWorker; 57 class 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. 69 class 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 requests()87 uint64 requests() const { return requests_; } cache_hits()88 uint64 cache_hits() const { return cache_hits_; } inflight_joins()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