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