]>
Commit | Line | Data |
---|---|---|
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 | 28 | using namespace std; |
ba45c866 | 29 | using namespace ::boost::multi_index; |
12c86877 | 30 | |
ba45c866 | 31 | using 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 |
47 | struct 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 |
65 | class PacketCache |
66 | { | |
67 | public: | |
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(); |
83 | private: | |
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 |