]>
Commit | Line | Data |
---|---|---|
bf269e28 RG |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
22 | #ifndef AUTH_QUERYCACHE_HH | |
23 | #define AUTH_QUERYCACHE_HH | |
24 | ||
25 | #include <string> | |
26 | #include <map> | |
27 | #include "dns.hh" | |
28 | #include <boost/version.hpp> | |
29 | #include "namespaces.hh" | |
30 | using namespace ::boost::multi_index; | |
31 | ||
32 | #include <boost/multi_index/hashed_index.hpp> | |
33 | ||
34 | #include "dns.hh" | |
35 | #include "dnspacket.hh" | |
36 | #include "lock.hh" | |
37 | ||
38 | class AuthQueryCache : public boost::noncopyable | |
39 | { | |
40 | public: | |
41 | AuthQueryCache(size_t mapsCount=1024); | |
42 | ~AuthQueryCache(); | |
43 | ||
44 | void insert(const DNSName &qname, const QType& qtype, const vector<DNSZoneRecord>& content, uint32_t ttl, int zoneID); | |
45 | ||
46 | bool getEntry(const DNSName &qname, const QType& qtype, vector<DNSZoneRecord>& entry, int zoneID); | |
47 | ||
48 | size_t size() { return *d_statnumentries; } //!< number of entries in the cache | |
49 | void cleanup(); //!< force the cache to preen itself from expired querys | |
50 | uint64_t purge(); | |
51 | uint64_t purge(const std::string& match); // could be $ terminated. Is not a dnsname! | |
52 | uint64_t purgeExact(const DNSName& qname); // no wildcard matching here | |
53 | ||
54 | map<char,uint64_t> getCounts(); | |
55 | ||
56 | void setMaxEntries(uint64_t maxEntries) | |
57 | { | |
58 | d_maxEntries = maxEntries; | |
59 | } | |
60 | private: | |
61 | ||
62 | struct CacheEntry | |
63 | { | |
64 | DNSName qname; | |
65 | mutable vector<DNSZoneRecord> drs; | |
66 | mutable time_t created{0}; | |
67 | mutable time_t ttd{0}; | |
68 | uint16_t qtype{0}; | |
69 | int zoneID{-1}; | |
70 | }; | |
71 | ||
72 | struct HashTag{}; | |
73 | struct NameTag{}; | |
74 | struct SequenceTag{}; | |
75 | typedef multi_index_container< | |
76 | CacheEntry, | |
77 | indexed_by < | |
78 | hashed_unique<tag<HashTag>, composite_key<CacheEntry, | |
79 | member<CacheEntry,DNSName,&CacheEntry::qname>, | |
80 | member<CacheEntry,uint16_t,&CacheEntry::qtype>, | |
81 | member<CacheEntry,int, &CacheEntry::zoneID> > > , | |
82 | ordered_non_unique<tag<NameTag>, member<CacheEntry,DNSName,&CacheEntry::qname>, CanonDNSNameCompare >, | |
83 | sequenced<tag<SequenceTag>> | |
84 | > | |
85 | > cmap_t; | |
86 | ||
87 | ||
88 | struct MapCombo | |
89 | { | |
90 | pthread_rwlock_t d_mut; | |
91 | cmap_t d_map; | |
92 | }; | |
93 | ||
94 | vector<MapCombo> d_maps; | |
95 | MapCombo& getMap(const DNSName& qname) | |
96 | { | |
97 | return d_maps[qname.hash() % d_maps.size()]; | |
98 | } | |
99 | ||
100 | bool getEntryLocked(cmap_t& map, const DNSName &content, uint16_t qtype, vector<DNSZoneRecord>& entry, int zoneID, time_t now); | |
101 | void cleanupIfNeeded(); | |
102 | ||
103 | AtomicCounter d_ops{0}; | |
104 | AtomicCounter *d_statnumhit; | |
105 | AtomicCounter *d_statnummiss; | |
106 | AtomicCounter *d_statnumentries; | |
107 | ||
108 | uint64_t d_maxEntries{0}; | |
109 | time_t d_lastclean; // doesn't need to be atomic | |
110 | unsigned long d_nextclean{4906}; | |
111 | unsigned int d_cleaninterval{4096}; | |
112 | bool d_cleanskipped{false}; | |
113 | ||
114 | static const unsigned int s_mincleaninterval=1000, s_maxcleaninterval=300000; | |
115 | }; | |
116 | ||
117 | #endif /* AUTH_QUERYCACHE_HH */ |