]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/auth-querycache.hh
Replace include guard ifdef/define with pragma once
[thirdparty/pdns.git] / pdns / auth-querycache.hh
CommitLineData
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 */
e8c59f2d 22#pragma once
bf269e28
RG
23#include <string>
24#include <map>
25#include "dns.hh"
26#include <boost/version.hpp>
27#include "namespaces.hh"
28using namespace ::boost::multi_index;
29
30#include <boost/multi_index/hashed_index.hpp>
31
32#include "dns.hh"
33#include "dnspacket.hh"
34#include "lock.hh"
35
36class AuthQueryCache : public boost::noncopyable
37{
38public:
39 AuthQueryCache(size_t mapsCount=1024);
40 ~AuthQueryCache();
41
42 void insert(const DNSName &qname, const QType& qtype, const vector<DNSZoneRecord>& content, uint32_t ttl, int zoneID);
43
44 bool getEntry(const DNSName &qname, const QType& qtype, vector<DNSZoneRecord>& entry, int zoneID);
45
46 size_t size() { return *d_statnumentries; } //!< number of entries in the cache
47 void cleanup(); //!< force the cache to preen itself from expired querys
48 uint64_t purge();
49 uint64_t purge(const std::string& match); // could be $ terminated. Is not a dnsname!
50 uint64_t purgeExact(const DNSName& qname); // no wildcard matching here
51
52 map<char,uint64_t> getCounts();
53
54 void setMaxEntries(uint64_t maxEntries)
55 {
56 d_maxEntries = maxEntries;
307994e7
RG
57 for (auto& shard : d_maps) {
58 shard.reserve(maxEntries / d_maps.size());
59 }
bf269e28
RG
60 }
61private:
62
63 struct CacheEntry
64 {
65 DNSName qname;
66 mutable vector<DNSZoneRecord> drs;
67 mutable time_t created{0};
68 mutable time_t ttd{0};
69 uint16_t qtype{0};
70 int zoneID{-1};
71 };
72
73 struct HashTag{};
74 struct NameTag{};
94306029 75 struct SequencedTag{};
bf269e28
RG
76 typedef multi_index_container<
77 CacheEntry,
78 indexed_by <
79 hashed_unique<tag<HashTag>, composite_key<CacheEntry,
80 member<CacheEntry,DNSName,&CacheEntry::qname>,
81 member<CacheEntry,uint16_t,&CacheEntry::qtype>,
82 member<CacheEntry,int, &CacheEntry::zoneID> > > ,
83 ordered_non_unique<tag<NameTag>, member<CacheEntry,DNSName,&CacheEntry::qname>, CanonDNSNameCompare >,
d2814f81
RG
84 /* Note that this sequence holds 'least recently inserted or replaced', not least recently used.
85 Making it a LRU would require taking a write-lock when fetching from the cache, making the RW-lock inefficient compared to a mutex */
94306029 86 sequenced<tag<SequencedTag>>
bf269e28
RG
87 >
88 > cmap_t;
89
90
91 struct MapCombo
92 {
040793d4
OM
93 MapCombo() {
94 pthread_rwlock_init(&d_mut, nullptr);
95 }
96 ~MapCombo() {
97 pthread_rwlock_destroy(&d_mut);
98 }
9c0ad051
OM
99 MapCombo(const MapCombo &) = delete;
100 MapCombo & operator=(const MapCombo &) = delete;
101
307994e7
RG
102 void reserve(size_t numberOfEntries);
103
040793d4 104 pthread_rwlock_t d_mut;
bf269e28
RG
105 cmap_t d_map;
106 };
107
108 vector<MapCombo> d_maps;
109 MapCombo& getMap(const DNSName& qname)
110 {
111 return d_maps[qname.hash() % d_maps.size()];
112 }
113
114 bool getEntryLocked(cmap_t& map, const DNSName &content, uint16_t qtype, vector<DNSZoneRecord>& entry, int zoneID, time_t now);
115 void cleanupIfNeeded();
116
117 AtomicCounter d_ops{0};
118 AtomicCounter *d_statnumhit;
119 AtomicCounter *d_statnummiss;
120 AtomicCounter *d_statnumentries;
121
122 uint64_t d_maxEntries{0};
123 time_t d_lastclean; // doesn't need to be atomic
2010ac95 124 unsigned long d_nextclean{4096};
bf269e28
RG
125 unsigned int d_cleaninterval{4096};
126 bool d_cleanskipped{false};
127
128 static const unsigned int s_mincleaninterval=1000, s_maxcleaninterval=300000;
129};