File: recursor_cache.hh

package info (click to toggle)
pdns-recursor 3.3-3%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,256 kB
  • sloc: cpp: 13,251; ansic: 2,647; sh: 510; makefile: 87
file content (114 lines) | stat: -rw-r--r-- 3,267 bytes parent folder | download | duplicates (3)
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
#ifndef RECURSOR_CACHE_HH
#define RECURSOR_CACHE_HH
#include <string>
#include <set>
#include "dns.hh"
#include "qtype.hh"
#include "misc.hh"
#include <iostream>

#include <boost/utility.hpp>
#undef L
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/version.hpp>

#undef max

#define L theL()
#include "namespaces.hh"
using namespace ::boost::multi_index;

class MemRecursorCache : public boost::noncopyable //  : public RecursorCache
{
public:
  MemRecursorCache() : d_followRFC2181(false), d_cachecachevalid(false)
  {
    cacheHits = cacheMisses = 0;
  }
  unsigned int size();
  unsigned int bytes();
  int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res);

  int getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]);
  void replace(time_t, const string &qname, const QType& qt,  const set<DNSResourceRecord>& content, bool auth);
  void doPrune(void);
  void doSlash(int perc);
  uint64_t doDump(int fd);
  int doWipeCache(const string& name, uint16_t qtype=0xffff);
  bool doAgeCache(time_t now, const string& name, uint16_t qtype, int32_t newTTL);
  uint64_t cacheHits, cacheMisses;
  bool d_followRFC2181;

private:
  struct StoredRecord
  {
    mutable uint32_t d_ttd;

    string d_string;

    bool operator<(const StoredRecord& rhs) const
    {
      return d_string < rhs.d_string;
    }

    unsigned int size() const
    {
      return ( unsigned int ) 4+d_string.size();
    }

  };

  struct CacheEntry
  {
    CacheEntry(const tuple<string, uint16_t>& key, const vector<StoredRecord>& records, bool auth) : 
      d_qname(key.get<0>()), d_qtype(key.get<1>()), d_auth(auth), d_records(records)
    {}

    typedef vector<StoredRecord> records_t;

    uint32_t getTTD() const
    {
      if(d_records.size()==1)
        return d_records.begin()->d_ttd;

      uint32_t earliest=numeric_limits<uint32_t>::max();
      for(records_t::const_iterator i=d_records.begin(); i != d_records.end(); ++i)
        earliest=min(earliest, i->d_ttd);
      return earliest;
    }

    string d_qname;
    uint16_t d_qtype;
    bool d_auth;
    records_t d_records;
  };

  typedef multi_index_container<
    CacheEntry,
    indexed_by <
                ordered_unique<
                      composite_key< 
                        CacheEntry,
                        member<CacheEntry,string,&CacheEntry::d_qname>,
                        member<CacheEntry,uint16_t,&CacheEntry::d_qtype>
                      >,
                      composite_key_compare<CIStringCompare, std::less<uint16_t> >
                >,
               sequenced<>
               >
  > cache_t;

  cache_t d_cache;
  pair<cache_t::iterator, cache_t::iterator> d_cachecache;
  string d_cachedqname;
  bool d_cachecachevalid;
  bool attemptToRefreshNSTTL(const QType& qt, const set<DNSResourceRecord>& content, const CacheEntry& stored);
};
string DNSRR2String(const DNSResourceRecord& rr);
DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd);

#endif