]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/packetcache.hh
make sure we don't try to perform a complete multithreaded cache cleanup when we...
[thirdparty/pdns.git] / pdns / packetcache.hh
CommitLineData
12c86877
BH
1/*
2 PowerDNS Versatile Database Driven Nameserver
2667dc9a 3 Copyright (C) 2002 - 2008 PowerDNS.COM BV
12c86877
BH
4
5 This program is free software; you can redistribute it and/or modify
22dc646a
BH
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
8
12c86877
BH
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
06bd9ccf 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12c86877
BH
18*/
19#ifndef PACKETCACHE_HH
20#define PACKETCACHE_HH
21
22#include <string>
23#include <utility>
24#include <map>
ba45c866 25#include <map>
5f8fcf64 26#include "dns.hh"
ba45c866 27#include <boost/version.hpp>
12c86877 28using namespace std;
ba45c866 29using namespace ::boost::multi_index;
12c86877 30
ba45c866 31using namespace boost;
12c86877
BH
32#include "dnspacket.hh"
33#include "lock.hh"
34#include "statbag.hh"
35
36/** This class performs 'whole packet caching'. Feed it a question packet and it will
37 try to find an answer. If you have an answer, insert it to have it cached for later use.
38 Take care not to replace existing cache entries. While this works, it is wasteful. Only
39 insert packets that where not found by get()
40
41 Locking!
42
43 The cache itself is protected by a read/write lock. Because deleting is a two step process, which
44 first marks and then sweeps, a second lock is present to prevent simultaneous inserts and deletes.
12c86877 45*/
ba45c866 46
9e134196
BH
47struct CIBackwardsStringCompare: public binary_function<string, string, bool>
48{
66d21e07 49 bool operator()(const string& str_a, const string& str_b) const
9e134196 50 {
66d21e07
BH
51 string::const_reverse_iterator ra, rb;
52 char a=0, b=0;
53 for(ra = str_a.rbegin(), rb = str_b.rbegin();
54 ra < str_a.rend() && rb < str_b.rend() && (a=dns_tolower(*ra)) == (b=dns_tolower(*rb));
55 ra++, rb++);
9e134196 56
66d21e07
BH
57 if (ra < str_a.rend() && rb==str_b.rend()) { a=*(ra++); b=0; }
58 if (rb < str_b.rend() && ra==str_a.rend()) { b=*(rb++); a=0; }
9e134196 59
66d21e07 60 return a < b;
9e134196
BH
61 }
62};
63
64
12c86877
BH
65class PacketCache
66{
67public:
68 PacketCache();
2f24bcd2 69 enum CacheEntryType { PACKETCACHE, QUERYCACHE};
ba45c866 70
12c86877 71 void insert(DNSPacket *q, DNSPacket *r); //!< We copy the contents of *p into our cache. Do not needlessly call this to insert questions already in the cache as it wastes resources
12c86877 72
ba45c866 73 void insert(const string &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID=-1, bool meritsRecursion=false);
2667dc9a
BH
74
75 int get(DNSPacket *p, DNSPacket *q); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method.
ba45c866
BH
76 bool getEntry(const string &content, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1, bool meritsRecursion=false);
77
12c86877
BH
78 int size(); //!< number of entries in the cache
79 void cleanup(); //!< force the cache to preen itself from expired packets
e63ea45c 80 int purge(const vector<string>&matches= vector<string>());
2667dc9a 81
12c86877
BH
82 map<char,int> getCounts();
83private:
ba45c866 84 struct CacheEntry
12c86877 85 {
ba45c866
BH
86 CacheEntry() { qtype = ctype = 0; zoneID = -1; meritsRecursion=false;}
87
88 string qname;
89 uint16_t qtype;
90 uint16_t ctype;
91 int zoneID;
12c86877 92 time_t ttd;
ba45c866 93 bool meritsRecursion;
12c86877
BH
94 string value;
95 };
96
12c86877 97 void getTTLS();
ba45c866
BH
98
99 typedef multi_index_container<
100 CacheEntry,
101 indexed_by <
102 ordered_unique<
103 composite_key<
104 CacheEntry,
105 member<CacheEntry,string,&CacheEntry::qname>,
106 member<CacheEntry,uint16_t,&CacheEntry::qtype>,
107 member<CacheEntry,uint16_t, &CacheEntry::ctype>,
108 member<CacheEntry,int, &CacheEntry::zoneID>,
109 member<CacheEntry,bool, &CacheEntry::meritsRecursion>
110 >,
9e134196 111 composite_key_compare<CIBackwardsStringCompare, std::less<uint16_t>, std::less<uint16_t>, std::less<int>, std::less<bool> >
ba45c866
BH
112 >,
113 sequenced<>
114 >
115 > cmap_t;
116
12c86877 117
12c86877
BH
118 cmap_t d_map;
119
120 pthread_rwlock_t d_mut;
12c86877
BH
121
122 int d_hit;
123 int d_miss;
124 int d_ttl;
125 int d_recursivettl;
126 bool d_doRecursion;
dee7ba5a
BH
127 unsigned int *d_statnumhit;
128 unsigned int *d_statnummiss;
129 unsigned int *d_statnumentries;
12c86877
BH
130};
131
12c86877
BH
132
133
134#endif /* PACKETCACHE_HH */
135