]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/test-recpacketcache_cc.cc
Merge pull request #7870 from omoerbeek/stubquery-fix-arg
[thirdparty/pdns.git] / pdns / test-recpacketcache_cc.cc
CommitLineData
49a3500d 1#define BOOST_TEST_DYN_LINK
2#define BOOST_TEST_NO_MAIN
3
4#ifdef HAVE_CONFIG_H
5#include "config.h"
6#endif
7#include <boost/test/unit_test.hpp>
015fa236 8#include "arguments.hh"
49a3500d 9#include "dnswriter.hh"
10#include "dnsrecords.hh"
11#include "dns_random.hh"
12#include "iputils.hh"
13#include "recpacketcache.hh"
14#include <utility>
15
16
c7f29d3e 17BOOST_AUTO_TEST_SUITE(test_recpacketcache_cc)
49a3500d 18
19BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) {
20 RecursorPacketCache rpc;
e9f63d47 21 string fpacket;
181270f6 22 unsigned int tag=0;
e9f63d47
RG
23 uint32_t age=0;
24 uint32_t qhash=0;
25 uint32_t ttd=3600;
49a3500d 26 BOOST_CHECK_EQUAL(rpc.size(), 0);
27
015fa236
OM
28 ::arg().set("rng")="auto";
29 ::arg().set("entropy-source")="/dev/urandom";
30
49a3500d 31 DNSName qname("www.powerdns.com");
32 vector<uint8_t> packet;
33 DNSPacketWriter pw(packet, qname, QType::A);
34 pw.getHeader()->rd=true;
35 pw.getHeader()->qr=false;
b51ef4f9 36 pw.getHeader()->id=dns_random(UINT16_MAX);
49a3500d 37 string qpacket((const char*)&packet[0], packet.size());
e9f63d47
RG
38 pw.startRecord(qname, QType::A, ttd);
39
40 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash), false);
c15ff3df 41 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash), false);
49a3500d 42
43 ARecordContent ar("127.0.0.1");
44 ar.toPacket(pw);
45 pw.commit();
46 string rpacket((const char*)&packet[0], packet.size());
47
5e1f23ca 48 rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, Indeterminate, 0, 0, boost::none);
49a3500d 49 BOOST_CHECK_EQUAL(rpc.size(), 1);
50 rpc.doPruneTo(0);
51 BOOST_CHECK_EQUAL(rpc.size(), 0);
5e1f23ca 52 rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, Indeterminate, 0, 0, boost::none);
49a3500d 53 BOOST_CHECK_EQUAL(rpc.size(), 1);
54 rpc.doWipePacketCache(qname);
55 BOOST_CHECK_EQUAL(rpc.size(), 0);
56
5e1f23ca 57 rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, Indeterminate, 0, 0, boost::none);
08b02366 58 BOOST_CHECK_EQUAL(rpc.size(), 1);
e9f63d47
RG
59 uint32_t qhash2 = 0;
60 bool found = rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash2);
61 BOOST_CHECK_EQUAL(found, true);
62 BOOST_CHECK_EQUAL(qhash, qhash2);
49a3500d 63 BOOST_CHECK_EQUAL(fpacket, rpacket);
c15ff3df
RG
64 found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash2);
65 BOOST_CHECK_EQUAL(found, true);
66 BOOST_CHECK_EQUAL(qhash, qhash2);
67 BOOST_CHECK_EQUAL(fpacket, rpacket);
49a3500d 68
69 packet.clear();
70 qname+=DNSName("co.uk");
71 DNSPacketWriter pw2(packet, qname, QType::A);
72
73 pw2.getHeader()->rd=true;
74 pw2.getHeader()->qr=false;
b51ef4f9 75 pw2.getHeader()->id=dns_random(UINT16_MAX);
49a3500d 76 qpacket.assign((const char*)&packet[0], packet.size());
e9f63d47
RG
77
78 found = rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash);
79 BOOST_CHECK_EQUAL(found, false);
c15ff3df
RG
80 found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash);
81 BOOST_CHECK_EQUAL(found, false);
49a3500d 82
83 rpc.doWipePacketCache(DNSName("com"), 0xffff, true);
84 BOOST_CHECK_EQUAL(rpc.size(), 0);
181270f6
RG
85}
86
87BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) {
88 /* Insert a response with tag1, the exact same query with a different tag
89 should lead to a miss. Inserting a different response with the second tag
90 should not override the first one, and we should get a hit for the
91 query with either tags, with the response matching the tag.
92 */
93 RecursorPacketCache rpc;
94 string fpacket;
95 const unsigned int tag1=0;
96 const unsigned int tag2=42;
97 uint32_t age=0;
98 uint32_t qhash=0;
99 uint32_t temphash=0;
100 uint32_t ttd=3600;
101 BOOST_CHECK_EQUAL(rpc.size(), 0);
102
015fa236
OM
103 ::arg().set("rng")="auto";
104 ::arg().set("entropy-source")="/dev/urandom";
105
181270f6
RG
106 DNSName qname("www.powerdns.com");
107 vector<uint8_t> packet;
108 DNSPacketWriter pw(packet, qname, QType::A);
109 pw.getHeader()->rd=true;
110 pw.getHeader()->qr=false;
b51ef4f9 111 pw.getHeader()->id=dns_random(UINT16_MAX);
181270f6
RG
112 string qpacket(reinterpret_cast<const char*>(&packet[0]), packet.size());
113 pw.startRecord(qname, QType::A, ttd);
114
115 /* Both interfaces (with and without the qname/qtype/qclass) should get the same hash */
116 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &qhash), false);
117 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false);
118 BOOST_CHECK_EQUAL(qhash, temphash);
119
120 /* Different tag, should still get get the same hash, for both interfaces */
121 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, time(nullptr), &fpacket, &age, &temphash), false);
122 BOOST_CHECK_EQUAL(qhash, temphash);
123 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false);
124 BOOST_CHECK_EQUAL(qhash, temphash);
125
126 {
127 ARecordContent ar("127.0.0.1");
128 ar.toPacket(pw);
129 pw.commit();
130 }
131 string r1packet(reinterpret_cast<const char*>(&packet[0]), packet.size());
132
133 {
134 ARecordContent ar("127.0.0.2");
135 ar.toPacket(pw);
136 pw.commit();
137 }
138 string r2packet(reinterpret_cast<const char*>(&packet[0]), packet.size());
139
140 BOOST_CHECK(r1packet != r2packet);
141
142 /* inserting a response for tag1 */
5e1f23ca 143 rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
144 BOOST_CHECK_EQUAL(rpc.size(), 1);
145
146 /* inserting a different response for tag2, should not override the first one */
5e1f23ca 147 rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
148 BOOST_CHECK_EQUAL(rpc.size(), 2);
149
150 /* remove all responses from the cache */
151 rpc.doPruneTo(0);
152 BOOST_CHECK_EQUAL(rpc.size(), 0);
153
154 /* reinsert both */
5e1f23ca 155 rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
156 BOOST_CHECK_EQUAL(rpc.size(), 1);
157
5e1f23ca 158 rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
159 BOOST_CHECK_EQUAL(rpc.size(), 2);
160
161 /* remove the responses by qname, should remove both */
162 rpc.doWipePacketCache(qname);
163 BOOST_CHECK_EQUAL(rpc.size(), 0);
164
165 /* insert the response for tag1 */
5e1f23ca 166 rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
167 BOOST_CHECK_EQUAL(rpc.size(), 1);
168
169 /* we can retrieve it */
170 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true);
171 BOOST_CHECK_EQUAL(qhash, temphash);
172 BOOST_CHECK_EQUAL(fpacket, r1packet);
173
174 /* with both interfaces */
175 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &temphash), true);
176 BOOST_CHECK_EQUAL(qhash, temphash);
177 BOOST_CHECK_EQUAL(fpacket, r1packet);
178
179 /* but not with the second tag */
180 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false);
181 /* we should still get the same hash */
182 BOOST_CHECK_EQUAL(temphash, qhash);
183
184 /* adding a response for the second tag */
5e1f23ca 185 rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, Indeterminate, 0, 0, boost::none);
181270f6
RG
186 BOOST_CHECK_EQUAL(rpc.size(), 2);
187
188 /* We still get the correct response for the first tag */
189 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &temphash), true);
190 BOOST_CHECK_EQUAL(qhash, temphash);
191 BOOST_CHECK_EQUAL(fpacket, r1packet);
192
193 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true);
194 BOOST_CHECK_EQUAL(qhash, temphash);
195 BOOST_CHECK_EQUAL(fpacket, r1packet);
196
197 /* and the correct response for the second tag */
198 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, time(nullptr), &fpacket, &age, &temphash), true);
199 BOOST_CHECK_EQUAL(qhash, temphash);
200 BOOST_CHECK_EQUAL(fpacket, r2packet);
201
202 BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true);
203 BOOST_CHECK_EQUAL(qhash, temphash);
204 BOOST_CHECK_EQUAL(fpacket, r2packet);
205}
49a3500d 206
207BOOST_AUTO_TEST_SUITE_END()