]>
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 | */ | |
3ea54bf0 BH |
22 | #ifndef PDNS_RECPACKETCACHE_HH |
23 | #define PDNS_RECPACKETCACHE_HH | |
24 | #include <string> | |
3ea54bf0 | 25 | #include <inttypes.h> |
57842ca3 BH |
26 | #include "dns.hh" |
27 | #include "namespaces.hh" | |
3d40879b | 28 | #include <iostream> |
3f3459f0 BH |
29 | #include <boost/multi_index_container.hpp> |
30 | #include <boost/multi_index/ordered_index.hpp> | |
49a3500d | 31 | #include <boost/multi_index/hashed_index.hpp> |
3f3459f0 BH |
32 | #include <boost/tuple/tuple_comparison.hpp> |
33 | #include <boost/multi_index/sequenced_index.hpp> | |
3ea54bf0 | 34 | |
bf269e28 | 35 | #include "packetcache.hh" |
88694a6a | 36 | #include "validate.hh" |
bf269e28 | 37 | |
02b47f43 RG |
38 | #ifdef HAVE_CONFIG_H |
39 | #include "config.h" | |
40 | #endif | |
d9d3f9c1 | 41 | #include "rec-protobuf.hh" |
02b47f43 | 42 | |
3f3459f0 BH |
43 | |
44 | using namespace ::boost::multi_index; | |
45 | ||
46 | //! Stores whole packets, ready for lobbing back at the client. Not threadsafe. | |
578050d0 | 47 | /* Note: we store answers as value AND KEY, and with careful work, we make sure that |
48 | you can use a query as a key too. But query and answer must compare as identical! | |
49 | ||
50 | This precludes doing anything smart with EDNS directly from the packet */ | |
bf269e28 | 51 | class RecursorPacketCache: public PacketCache |
3ea54bf0 BH |
52 | { |
53 | public: | |
54 | RecursorPacketCache(); | |
e9f63d47 | 55 | bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); |
c15ff3df | 56 | bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); |
08b02366 RG |
57 | bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, uint16_t* ecsBegin, uint16_t* ecsEnd, RecProtoBufMessage* protobufMessage); |
58 | bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, uint16_t* ecsBegin, uint16_t* ecsEnd, RecProtoBufMessage* protobufMessage); | |
4b0bdd5f | 59 | void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, uint16_t ecsBegin, uint16_t ecsEnd, boost::optional<RecProtoBufMessage>&& protobufMessage); |
3f3459f0 | 60 | void doPruneTo(unsigned int maxSize=250000); |
09645ebb | 61 | uint64_t doDump(int fd); |
65a60c2c | 62 | int doWipePacketCache(const DNSName& name, uint16_t qtype=0xffff, bool subtree=false); |
3ea54bf0 BH |
63 | |
64 | void prune(); | |
16beeaa4 BH |
65 | uint64_t d_hits, d_misses; |
66 | uint64_t size(); | |
0bbf7d0a | 67 | uint64_t bytes(); |
16beeaa4 | 68 | |
3ea54bf0 | 69 | private: |
49a3500d | 70 | struct HashTag {}; |
71 | struct NameTag {}; | |
3ea54bf0 BH |
72 | struct Entry |
73 | { | |
b5e675a7 | 74 | Entry(const DNSName& qname, std::string&& packet, std::string&& query): d_name(qname), d_packet(std::move(packet)), d_query(std::move(query)) |
972a6068 RG |
75 | { |
76 | } | |
77 | ||
49a3500d | 78 | DNSName d_name; |
3ea54bf0 | 79 | mutable std::string d_packet; // "I know what I am doing" |
08b02366 | 80 | mutable std::string d_query; |
02b47f43 | 81 | #ifdef HAVE_PROTOBUF |
d362f7c1 | 82 | mutable boost::optional<RecProtoBufMessage> d_protobufMessage; |
02b47f43 | 83 | #endif |
08b02366 RG |
84 | mutable time_t d_ttd; |
85 | mutable time_t d_creation; // so we can 'age' our packets | |
49a3500d | 86 | uint32_t d_qhash; |
87 | uint32_t d_tag; | |
08b02366 RG |
88 | uint16_t d_type; |
89 | uint16_t d_class; | |
90 | mutable uint16_t d_ecsBegin; | |
91 | mutable uint16_t d_ecsEnd; | |
4d3f74e8 | 92 | mutable vState d_vstate; |
57842ca3 | 93 | inline bool operator<(const struct Entry& rhs) const; |
972a6068 | 94 | |
6b68a4e3 | 95 | time_t getTTD() const |
38c9ceaa BH |
96 | { |
97 | return d_ttd; | |
98 | } | |
3ea54bf0 | 99 | }; |
bf269e28 | 100 | |
3f3459f0 BH |
101 | typedef multi_index_container< |
102 | Entry, | |
103 | indexed_by < | |
49a3500d | 104 | hashed_non_unique<tag<HashTag>, composite_key<Entry, member<Entry,uint32_t,&Entry::d_tag>, member<Entry,uint32_t,&Entry::d_qhash> > >, |
105 | sequenced<> , | |
106 | ordered_non_unique<tag<NameTag>, member<Entry,DNSName,&Entry::d_name>, CanonDNSNameCompare > | |
107 | > | |
3f3459f0 BH |
108 | > packetCache_t; |
109 | ||
49a3500d | 110 | packetCache_t d_packetCache; |
c15ff3df | 111 | |
08b02366 RG |
112 | static bool qrMatch(const packetCache_t::index<HashTag>::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint16_t ecsBegin, uint16_t ecsEnd); |
113 | bool checkResponseMatches(std::pair<packetCache_t::index<HashTag>::type::iterator, packetCache_t::index<HashTag>::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, RecProtoBufMessage* protobufMessage, uint16_t ecsBegin, uint16_t ecsEnd); | |
e74f866a RG |
114 | |
115 | public: | |
116 | void preRemoval(const Entry& entry) | |
117 | { | |
118 | } | |
3ea54bf0 BH |
119 | }; |
120 | ||
121 | #endif |