Home | History | Annotate | Download | only in base
      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 
     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