]>
Commit | Line | Data |
---|---|---|
12471842 PL |
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 | */ | |
886e2cf2 RG |
22 | #pragma once |
23 | ||
24 | #include <atomic> | |
25 | #include <unordered_map> | |
af6f3d53 RG |
26 | |
27 | #include "iputils.hh" | |
886e2cf2 RG |
28 | #include "lock.hh" |
29 | ||
1ea747c0 RG |
30 | struct DNSQuestion; |
31 | ||
886e2cf2 RG |
32 | class DNSDistPacketCache : boost::noncopyable |
33 | { | |
34 | public: | |
78e3ac9e | 35 | DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL=86400, uint32_t minTTL=0, uint32_t tempFailureTTL=60, uint32_t maxNegativeTTL=3600, uint32_t staleTTL=60, bool dontAge=false, uint32_t shards=1, bool deferrableInsertLock=true, bool parseECS=false); |
886e2cf2 RG |
36 | ~DNSDistPacketCache(); |
37 | ||
d7728daf RG |
38 | void insert(uint32_t key, const boost::optional<Netmask>& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const char* response, uint16_t responseLen, bool tcp, uint8_t rcode, boost::optional<uint32_t> tempFailureTTL); |
39 | bool get(const DNSQuestion& dq, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, uint32_t* keyOut, boost::optional<Netmask>& subnetOut, bool dnssecOK, uint32_t allowExpired=0, bool skipAging=false); | |
f627611d RG |
40 | size_t purgeExpired(size_t upTo=0); |
41 | size_t expunge(size_t upTo=0); | |
42 | size_t expungeByName(const DNSName& name, uint16_t qtype=QType::ANY, bool suffixMatch=false); | |
886e2cf2 RG |
43 | bool isFull(); |
44 | string toString(); | |
2b3eefc3 | 45 | uint64_t getSize(); |
9e9be156 RG |
46 | uint64_t getHits() const { return d_hits; } |
47 | uint64_t getMisses() const { return d_misses; } | |
48 | uint64_t getDeferredLookups() const { return d_deferredLookups; } | |
49 | uint64_t getDeferredInserts() const { return d_deferredInserts; } | |
50 | uint64_t getLookupCollisions() const { return d_lookupCollisions; } | |
51 | uint64_t getInsertCollisions() const { return d_insertCollisions; } | |
52 | uint64_t getMaxEntries() const { return d_maxEntries; } | |
cc8cefe1 | 53 | uint64_t getTTLTooShorts() const { return d_ttlTooShorts; } |
9e9be156 | 54 | uint64_t getEntriesCount(); |
f037144c | 55 | uint64_t dump(int fd); |
c1b81381 | 56 | |
389d903a | 57 | bool isECSParsingEnabled() const { return d_parseECS; } |
886e2cf2 | 58 | |
c1b81381 RG |
59 | bool keepStaleData() const |
60 | { | |
61 | return d_keepStaleData; | |
62 | } | |
63 | void setKeepStaleData(bool keep) | |
64 | { | |
65 | d_keepStaleData = keep; | |
66 | } | |
67 | ||
47698274 | 68 | static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA); |
78e3ac9e | 69 | static uint32_t getKey(const std::string& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp); |
af6f3d53 | 70 | static bool getClientSubnet(const char* packet, unsigned int consumed, uint16_t len, boost::optional<Netmask>& subnet); |
886e2cf2 RG |
71 | |
72 | private: | |
73 | ||
74 | struct CacheValue | |
75 | { | |
76 | time_t getTTD() const { return validity; } | |
77 | std::string value; | |
78 | DNSName qname; | |
78e3ac9e | 79 | boost::optional<Netmask> subnet; |
886e2cf2 RG |
80 | uint16_t qtype{0}; |
81 | uint16_t qclass{0}; | |
8dcdbdb1 | 82 | uint16_t queryFlags{0}; |
886e2cf2 RG |
83 | time_t added{0}; |
84 | time_t validity{0}; | |
85 | uint16_t len{0}; | |
a176d205 | 86 | bool tcp{false}; |
d7728daf | 87 | bool dnssecOK{false}; |
886e2cf2 RG |
88 | }; |
89 | ||
2b3eefc3 RG |
90 | class CacheShard |
91 | { | |
92 | public: | |
93 | CacheShard(): d_entriesCount(0) | |
94 | { | |
95 | pthread_rwlock_init(&d_lock, 0); | |
96 | } | |
97 | CacheShard(const CacheShard& old): d_entriesCount(0) | |
98 | { | |
99 | pthread_rwlock_init(&d_lock, 0); | |
100 | } | |
101 | ||
102 | void setSize(size_t maxSize) | |
103 | { | |
104 | d_map.reserve(maxSize); | |
105 | } | |
106 | ||
107 | std::unordered_map<uint32_t,CacheValue> d_map; | |
108 | pthread_rwlock_t d_lock; | |
109 | std::atomic<uint64_t> d_entriesCount; | |
110 | }; | |
111 | ||
d7728daf | 112 | bool cachedValueMatches(const CacheValue& cachedValue, uint16_t queryFlags, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool tcp, bool dnssecOK, const boost::optional<Netmask>& subnet) const; |
2b3eefc3 | 113 | uint32_t getShardIndex(uint32_t key) const; |
78e3ac9e | 114 | void insertLocked(CacheShard& shard, uint32_t key, CacheValue& newValue); |
2b3eefc3 RG |
115 | |
116 | std::vector<CacheShard> d_shards; | |
886e2cf2 | 117 | |
886e2cf2 RG |
118 | std::atomic<uint64_t> d_deferredLookups{0}; |
119 | std::atomic<uint64_t> d_deferredInserts{0}; | |
120 | std::atomic<uint64_t> d_hits{0}; | |
121 | std::atomic<uint64_t> d_misses{0}; | |
122 | std::atomic<uint64_t> d_insertCollisions{0}; | |
123 | std::atomic<uint64_t> d_lookupCollisions{0}; | |
cc8cefe1 | 124 | std::atomic<uint64_t> d_ttlTooShorts{0}; |
2b3eefc3 | 125 | |
886e2cf2 | 126 | size_t d_maxEntries; |
2b3eefc3 RG |
127 | uint32_t d_expungeIndex{0}; |
128 | uint32_t d_shardCount; | |
886e2cf2 | 129 | uint32_t d_maxTTL; |
2714396e | 130 | uint32_t d_tempFailureTTL; |
47698274 | 131 | uint32_t d_maxNegativeTTL; |
886e2cf2 | 132 | uint32_t d_minTTL; |
1ea747c0 | 133 | uint32_t d_staleTTL; |
2b67180c | 134 | bool d_dontAge; |
2b3eefc3 | 135 | bool d_deferrableInsertLock; |
78e3ac9e | 136 | bool d_parseECS; |
c1b81381 | 137 | bool d_keepStaleData{false}; |
886e2cf2 | 138 | }; |