File: recursor_cache.hh

package info (click to toggle)
pdns-recursor 3.1.4-1
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 840 kB
  • ctags: 1,918
  • sloc: cpp: 9,746; ansic: 3,019; sh: 452; makefile: 123
file content (124 lines) | stat: -rw-r--r-- 3,272 bytes parent folder | download
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
115
116
117
118
119
120
121
122
123
124
#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>
#if BOOST_VERSION >= 103300
#include <boost/multi_index/hashed_index.hpp>
#endif

#undef max

#define L theL()
using namespace boost;
using namespace ::boost::multi_index;

class MemRecursorCache : public boost::noncopyable //  : public RecursorCache
{
public:
  MemRecursorCache() : d_followRFC2181(false), d_cachecachevalid(false)
  {}
  unsigned int size();
  unsigned int bytes();
  int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res);
  void replace(time_t, const string &qname, const QType& qt,  const set<DNSResourceRecord>& content, bool auth);
  void doPrune(void);
  void doSlash(int perc);
  void doDumpAndClose(int fd);
  int doWipeCache(const string& name, uint16_t qtype=0xffff);
  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 predicate
  {
    predicate(uint32_t limit) : d_limit(limit)
    {
    }
    
    bool operator()(const StoredRecord& sr) const
    {
      return sr.d_ttd <= d_limit;
    }
    uint32_t d_limit;
  };

  //   typedef __gnu_cxx::hash_map<string, vector<StoredRecord> > cache_t;
  struct CacheEntry
  {
    string d_qname;
    uint16_t d_qtype;
    bool d_auth;

    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;
    records_t d_records;
    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;
    }

  };

  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;
};
string DNSRR2String(const DNSResourceRecord& rr);
DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd);

#endif