// 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_ #pragma once #include #include #include #include #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/network_change_notifier.h" namespace net { // RRResponse contains the result of a successful request for a resource record. struct RRResponse { RRResponse(); ~RRResponse(); // HasExpired returns true if |fetch_time| + |ttl| is less than // |current_time|. bool HasExpired(base::Time current_time) const; // For testing only bool ParseFromResponse(const uint8* data, unsigned len, uint16 rrtype_requested); // 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 rrdatas; // sigs contains the RRSIG records returned. std::vector 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 DnsRRResolver : 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(); ~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, 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(); 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, RRResponse> cache_; // inflight_ maps from a request to an active resolution which is taking // place. std::map, 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_