]>
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> | |
26 | #include "lock.hh" | |
27 | ||
1ea747c0 RG |
28 | struct DNSQuestion; |
29 | ||
886e2cf2 RG |
30 | class DNSDistPacketCache : boost::noncopyable |
31 | { | |
32 | public: | |
47698274 | 33 | 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); |
886e2cf2 RG |
34 | ~DNSDistPacketCache(); |
35 | ||
acb8f5d5 | 36 | void insert(uint32_t key, 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); |
1ea747c0 | 37 | bool get(const DNSQuestion& dq, uint16_t consumed, uint16_t queryId, char* response, uint16_t* responseLen, uint32_t* keyOut, uint32_t allowExpired=0, bool skipAging=false); |
4275aaba RG |
38 | void purgeExpired(size_t upTo=0); |
39 | void expunge(size_t upTo=0); | |
490dc586 | 40 | void expungeByName(const DNSName& name, uint16_t qtype=QType::ANY, bool suffixMatch=false); |
886e2cf2 RG |
41 | bool isFull(); |
42 | string toString(); | |
2b3eefc3 | 43 | uint64_t getSize(); |
9e9be156 RG |
44 | uint64_t getHits() const { return d_hits; } |
45 | uint64_t getMisses() const { return d_misses; } | |
46 | uint64_t getDeferredLookups() const { return d_deferredLookups; } | |
47 | uint64_t getDeferredInserts() const { return d_deferredInserts; } | |
48 | uint64_t getLookupCollisions() const { return d_lookupCollisions; } | |
49 | uint64_t getInsertCollisions() const { return d_insertCollisions; } | |
50 | uint64_t getMaxEntries() const { return d_maxEntries; } | |
cc8cefe1 | 51 | uint64_t getTTLTooShorts() const { return d_ttlTooShorts; } |
9e9be156 | 52 | uint64_t getEntriesCount(); |
886e2cf2 | 53 | |
47698274 | 54 | static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA); |
886e2cf2 RG |
55 | |
56 | private: | |
57 | ||
58 | struct CacheValue | |
59 | { | |
60 | time_t getTTD() const { return validity; } | |
61 | std::string value; | |
62 | DNSName qname; | |
63 | uint16_t qtype{0}; | |
64 | uint16_t qclass{0}; | |
65 | time_t added{0}; | |
66 | time_t validity{0}; | |
67 | uint16_t len{0}; | |
a176d205 | 68 | bool tcp{false}; |
886e2cf2 RG |
69 | }; |
70 | ||
2b3eefc3 RG |
71 | class CacheShard |
72 | { | |
73 | public: | |
74 | CacheShard(): d_entriesCount(0) | |
75 | { | |
76 | pthread_rwlock_init(&d_lock, 0); | |
77 | } | |
78 | CacheShard(const CacheShard& old): d_entriesCount(0) | |
79 | { | |
80 | pthread_rwlock_init(&d_lock, 0); | |
81 | } | |
82 | ||
83 | void setSize(size_t maxSize) | |
84 | { | |
85 | d_map.reserve(maxSize); | |
86 | } | |
87 | ||
88 | std::unordered_map<uint32_t,CacheValue> d_map; | |
89 | pthread_rwlock_t d_lock; | |
90 | std::atomic<uint64_t> d_entriesCount; | |
91 | }; | |
92 | ||
7acad2d5 | 93 | static uint32_t getKey(const std::string& qname, uint16_t consumed, const unsigned char* packet, uint16_t packetLen, bool tcp); |
a176d205 | 94 | static bool cachedValueMatches(const CacheValue& cachedValue, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool tcp); |
2b3eefc3 RG |
95 | uint32_t getShardIndex(uint32_t key) const; |
96 | void insertLocked(CacheShard& shard, uint32_t key, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool tcp, CacheValue& newValue, time_t now, time_t newValidity); | |
97 | ||
98 | std::vector<CacheShard> d_shards; | |
886e2cf2 | 99 | |
886e2cf2 RG |
100 | std::atomic<uint64_t> d_deferredLookups{0}; |
101 | std::atomic<uint64_t> d_deferredInserts{0}; | |
102 | std::atomic<uint64_t> d_hits{0}; | |
103 | std::atomic<uint64_t> d_misses{0}; | |
104 | std::atomic<uint64_t> d_insertCollisions{0}; | |
105 | std::atomic<uint64_t> d_lookupCollisions{0}; | |
cc8cefe1 | 106 | std::atomic<uint64_t> d_ttlTooShorts{0}; |
2b3eefc3 | 107 | |
886e2cf2 | 108 | size_t d_maxEntries; |
2b3eefc3 RG |
109 | uint32_t d_expungeIndex{0}; |
110 | uint32_t d_shardCount; | |
886e2cf2 | 111 | uint32_t d_maxTTL; |
2714396e | 112 | uint32_t d_tempFailureTTL; |
47698274 | 113 | uint32_t d_maxNegativeTTL; |
886e2cf2 | 114 | uint32_t d_minTTL; |
1ea747c0 | 115 | uint32_t d_staleTTL; |
2b67180c | 116 | bool d_dontAge; |
2b3eefc3 | 117 | bool d_deferrableInsertLock; |
886e2cf2 | 118 | }; |