]>
Commit | Line | Data |
---|---|---|
1c2d079d | 1 | #ifndef BOOST_TEST_DYN_LINK |
49a3500d | 2 | #define BOOST_TEST_DYN_LINK |
1c2d079d FM |
3 | #endif |
4 | ||
49a3500d | 5 | #define BOOST_TEST_NO_MAIN |
6 | ||
7 | #ifdef HAVE_CONFIG_H | |
8 | #include "config.h" | |
9 | #endif | |
10 | #include <boost/test/unit_test.hpp> | |
11 | #include "dnswriter.hh" | |
12 | #include "dnsrecords.hh" | |
13 | #include "dns_random.hh" | |
14 | #include "iputils.hh" | |
15 | #include "recpacketcache.hh" | |
1e325a92 OM |
16 | #include "taskqueue.hh" |
17 | #include "rec-taskqueue.hh" | |
49a3500d | 18 | #include <utility> |
19 | ||
c7f29d3e | 20 | BOOST_AUTO_TEST_SUITE(test_recpacketcache_cc) |
49a3500d | 21 | |
a7f98e34 O |
22 | BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) |
23 | { | |
eeab0dc2 | 24 | RecursorPacketCache rpc(1000); |
e9f63d47 | 25 | string fpacket; |
a7f98e34 O |
26 | unsigned int tag = 0; |
27 | uint32_t age = 0; | |
28 | uint32_t qhash = 0; | |
29 | uint32_t ttd = 3600; | |
690b86b7 | 30 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
49a3500d | 31 | |
32 | DNSName qname("www.powerdns.com"); | |
33 | vector<uint8_t> packet; | |
34 | DNSPacketWriter pw(packet, qname, QType::A); | |
a7f98e34 O |
35 | pw.getHeader()->rd = true; |
36 | pw.getHeader()->qr = false; | |
37 | pw.getHeader()->id = dns_random_uint16(); | |
49a3500d | 38 | string qpacket((const char*)&packet[0], packet.size()); |
e9f63d47 RG |
39 | pw.startRecord(qname, QType::A, ttd); |
40 | ||
48d02436 OM |
41 | time_t now = time(nullptr); |
42 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash), false); | |
43 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash), false); | |
49a3500d | 44 | |
45 | ARecordContent ar("127.0.0.1"); | |
46 | ar.toPacket(pw); | |
47 | pw.commit(); | |
48 | string rpacket((const char*)&packet[0], packet.size()); | |
49 | ||
48d02436 | 50 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 51 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
48d02436 | 52 | rpc.doPruneTo(now, 0); |
690b86b7 | 53 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
48d02436 | 54 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 55 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
49a3500d | 56 | rpc.doWipePacketCache(qname); |
690b86b7 | 57 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
49a3500d | 58 | |
48d02436 | 59 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 60 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
e9f63d47 | 61 | uint32_t qhash2 = 0; |
48d02436 | 62 | bool found = rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash2); |
e9f63d47 RG |
63 | BOOST_CHECK_EQUAL(found, true); |
64 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
49a3500d | 65 | BOOST_CHECK_EQUAL(fpacket, rpacket); |
48d02436 | 66 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); |
c15ff3df RG |
67 | BOOST_CHECK_EQUAL(found, true); |
68 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
69 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
49a3500d | 70 | |
71 | packet.clear(); | |
a7f98e34 | 72 | qname += DNSName("co.uk"); |
49a3500d | 73 | DNSPacketWriter pw2(packet, qname, QType::A); |
74 | ||
a7f98e34 O |
75 | pw2.getHeader()->rd = true; |
76 | pw2.getHeader()->qr = false; | |
77 | pw2.getHeader()->id = dns_random_uint16(); | |
49a3500d | 78 | qpacket.assign((const char*)&packet[0], packet.size()); |
e9f63d47 | 79 | |
48d02436 | 80 | found = rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash); |
e9f63d47 | 81 | BOOST_CHECK_EQUAL(found, false); |
48d02436 | 82 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash); |
c15ff3df | 83 | BOOST_CHECK_EQUAL(found, false); |
49a3500d | 84 | |
85 | rpc.doWipePacketCache(DNSName("com"), 0xffff, true); | |
690b86b7 | 86 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
181270f6 RG |
87 | } |
88 | ||
1e325a92 OM |
89 | BOOST_AUTO_TEST_CASE(test_recPacketCacheSimpleWithRefresh) |
90 | { | |
91 | RecursorPacketCache::s_refresh_ttlperc = 30; | |
92 | RecursorPacketCache rpc(1000); | |
93 | string fpacket; | |
94 | unsigned int tag = 0; | |
95 | uint32_t age = 0; | |
96 | uint32_t qhash = 0; | |
97 | uint32_t ttd = 3600; | |
98 | BOOST_CHECK_EQUAL(rpc.size(), 0U); | |
99 | ||
19dbd489 OM |
100 | taskQueueClear(); |
101 | ||
1e325a92 OM |
102 | DNSName qname("www.powerdns.com"); |
103 | vector<uint8_t> packet; | |
104 | DNSPacketWriter pw(packet, qname, QType::A); | |
105 | pw.getHeader()->rd = true; | |
106 | pw.getHeader()->qr = false; | |
107 | pw.getHeader()->id = dns_random_uint16(); | |
108 | string qpacket((const char*)&packet[0], packet.size()); | |
109 | pw.startRecord(qname, QType::A, ttd); | |
110 | ||
111 | time_t now = time(nullptr); | |
112 | ||
113 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash), false); | |
114 | ||
115 | ARecordContent ar("127.0.0.1"); | |
116 | ar.toPacket(pw); | |
117 | pw.commit(); | |
118 | string rpacket((const char*)&packet[0], packet.size()); | |
119 | ||
120 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); | |
121 | BOOST_CHECK_EQUAL(rpc.size(), 1U); | |
122 | uint32_t qhash2 = 0; | |
123 | bool found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); | |
124 | BOOST_CHECK_EQUAL(found, true); | |
125 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
126 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
127 | ||
128 | BOOST_REQUIRE_EQUAL(getTaskSize(), 0U); | |
129 | ||
130 | // Half of time has passed, no task should have been submitted | |
131 | now += ttd / 2; | |
132 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); | |
133 | BOOST_CHECK_EQUAL(found, true); | |
134 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
135 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
136 | ||
137 | BOOST_REQUIRE_EQUAL(getTaskSize(), 0U); | |
138 | ||
139 | // 75% of time has passed, task should have been submitted as refresh perc is 30 and (100-75) = 25 <= 30 | |
140 | now += ttd / 4; | |
141 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); | |
142 | BOOST_CHECK_EQUAL(found, true); | |
143 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
144 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
145 | ||
146 | BOOST_REQUIRE_EQUAL(getTaskSize(), 1U); | |
147 | auto task = taskQueuePop(); | |
148 | BOOST_CHECK_EQUAL(task.d_qname, qname); | |
149 | } | |
150 | ||
a7f98e34 O |
151 | BOOST_AUTO_TEST_CASE(test_recPacketCacheSimplePost2038) |
152 | { | |
eeab0dc2 | 153 | RecursorPacketCache rpc(1000); |
df8cdcb3 | 154 | string fpacket; |
a7f98e34 O |
155 | unsigned int tag = 0; |
156 | uint32_t age = 0; | |
157 | uint32_t qhash = 0; | |
158 | uint32_t ttd = 3600; | |
df8cdcb3 O |
159 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
160 | ||
df8cdcb3 O |
161 | DNSName qname("www.powerdns.com"); |
162 | vector<uint8_t> packet; | |
163 | DNSPacketWriter pw(packet, qname, QType::A); | |
a7f98e34 O |
164 | pw.getHeader()->rd = true; |
165 | pw.getHeader()->qr = false; | |
166 | pw.getHeader()->id = dns_random_uint16(); | |
df8cdcb3 O |
167 | string qpacket((const char*)&packet[0], packet.size()); |
168 | pw.startRecord(qname, QType::A, ttd); | |
169 | ||
170 | time_t future = INT_MAX - 1800; // with ttd of 3600, we pass the cliff | |
171 | ||
172 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, future, &fpacket, &age, &qhash), false); | |
173 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, future, &fpacket, &age, &qhash), false); | |
174 | ||
175 | ARecordContent ar("127.0.0.1"); | |
176 | ar.toPacket(pw); | |
177 | pw.commit(); | |
178 | string rpacket((const char*)&packet[0], packet.size()); | |
179 | ||
c7bfc7e6 | 180 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), future, ttd, vState::Indeterminate, boost::none, false); |
df8cdcb3 | 181 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
48d02436 | 182 | rpc.doPruneTo(time(nullptr), 0); |
df8cdcb3 | 183 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
c7bfc7e6 | 184 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), future, ttd, vState::Indeterminate, boost::none, false); |
df8cdcb3 O |
185 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
186 | ||
187 | rpc.doWipePacketCache(qname); | |
188 | BOOST_CHECK_EQUAL(rpc.size(), 0U); | |
189 | ||
c7bfc7e6 | 190 | rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), future, ttd, vState::Indeterminate, boost::none, false); |
df8cdcb3 O |
191 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
192 | uint32_t qhash2 = 0; | |
193 | bool found = rpc.getResponsePacket(tag, qpacket, future, &fpacket, &age, &qhash2); | |
194 | BOOST_CHECK_EQUAL(found, true); | |
195 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
196 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
197 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, future, &fpacket, &age, &qhash2); | |
198 | BOOST_CHECK_EQUAL(found, true); | |
199 | BOOST_CHECK_EQUAL(qhash, qhash2); | |
200 | BOOST_CHECK_EQUAL(fpacket, rpacket); | |
201 | ||
202 | found = rpc.getResponsePacket(tag, qpacket, future + 3601, &fpacket, &age, &qhash2); | |
203 | BOOST_CHECK_EQUAL(found, false); | |
204 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, future + 3601, &fpacket, &age, &qhash2); | |
205 | BOOST_CHECK_EQUAL(found, false); | |
206 | ||
df8cdcb3 | 207 | packet.clear(); |
a7f98e34 | 208 | qname += DNSName("co.uk"); |
df8cdcb3 O |
209 | DNSPacketWriter pw2(packet, qname, QType::A); |
210 | ||
a7f98e34 O |
211 | pw2.getHeader()->rd = true; |
212 | pw2.getHeader()->qr = false; | |
213 | pw2.getHeader()->id = dns_random_uint16(); | |
df8cdcb3 O |
214 | qpacket.assign((const char*)&packet[0], packet.size()); |
215 | ||
216 | found = rpc.getResponsePacket(tag, qpacket, future, &fpacket, &age, &qhash); | |
217 | BOOST_CHECK_EQUAL(found, false); | |
218 | found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, future, &fpacket, &age, &qhash); | |
219 | BOOST_CHECK_EQUAL(found, false); | |
220 | ||
221 | rpc.doWipePacketCache(DNSName("com"), 0xffff, true); | |
222 | BOOST_CHECK_EQUAL(rpc.size(), 0U); | |
223 | } | |
224 | ||
a7f98e34 O |
225 | BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) |
226 | { | |
181270f6 RG |
227 | /* Insert a response with tag1, the exact same query with a different tag |
228 | should lead to a miss. Inserting a different response with the second tag | |
229 | should not override the first one, and we should get a hit for the | |
230 | query with either tags, with the response matching the tag. | |
231 | */ | |
eeab0dc2 | 232 | RecursorPacketCache rpc(1000); |
181270f6 | 233 | string fpacket; |
a7f98e34 O |
234 | const unsigned int tag1 = 0; |
235 | const unsigned int tag2 = 42; | |
236 | uint32_t age = 0; | |
237 | uint32_t qhash = 0; | |
238 | uint32_t temphash = 0; | |
239 | uint32_t ttd = 3600; | |
690b86b7 | 240 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
181270f6 RG |
241 | |
242 | DNSName qname("www.powerdns.com"); | |
243 | vector<uint8_t> packet; | |
244 | DNSPacketWriter pw(packet, qname, QType::A); | |
a7f98e34 O |
245 | pw.getHeader()->rd = true; |
246 | pw.getHeader()->qr = false; | |
247 | pw.getHeader()->id = dns_random_uint16(); | |
181270f6 RG |
248 | string qpacket(reinterpret_cast<const char*>(&packet[0]), packet.size()); |
249 | pw.startRecord(qname, QType::A, ttd); | |
250 | ||
251 | /* Both interfaces (with and without the qname/qtype/qclass) should get the same hash */ | |
252 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &qhash), false); | |
253 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false); | |
254 | BOOST_CHECK_EQUAL(qhash, temphash); | |
255 | ||
256 | /* Different tag, should still get get the same hash, for both interfaces */ | |
257 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, time(nullptr), &fpacket, &age, &temphash), false); | |
258 | BOOST_CHECK_EQUAL(qhash, temphash); | |
259 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false); | |
260 | BOOST_CHECK_EQUAL(qhash, temphash); | |
261 | ||
262 | { | |
263 | ARecordContent ar("127.0.0.1"); | |
264 | ar.toPacket(pw); | |
265 | pw.commit(); | |
266 | } | |
267 | string r1packet(reinterpret_cast<const char*>(&packet[0]), packet.size()); | |
268 | ||
269 | { | |
270 | ARecordContent ar("127.0.0.2"); | |
271 | ar.toPacket(pw); | |
272 | pw.commit(); | |
273 | } | |
274 | string r2packet(reinterpret_cast<const char*>(&packet[0]), packet.size()); | |
275 | ||
276 | BOOST_CHECK(r1packet != r2packet); | |
277 | ||
278 | /* inserting a response for tag1 */ | |
d7c99a70 | 279 | rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 280 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
181270f6 RG |
281 | |
282 | /* inserting a different response for tag2, should not override the first one */ | |
d7c99a70 | 283 | rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 284 | BOOST_CHECK_EQUAL(rpc.size(), 2U); |
181270f6 RG |
285 | |
286 | /* remove all responses from the cache */ | |
48d02436 | 287 | rpc.doPruneTo(time(nullptr), 0); |
690b86b7 | 288 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
181270f6 RG |
289 | |
290 | /* reinsert both */ | |
d7c99a70 | 291 | rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 292 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
181270f6 | 293 | |
d7c99a70 | 294 | rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 295 | BOOST_CHECK_EQUAL(rpc.size(), 2U); |
181270f6 RG |
296 | |
297 | /* remove the responses by qname, should remove both */ | |
298 | rpc.doWipePacketCache(qname); | |
690b86b7 | 299 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
181270f6 RG |
300 | |
301 | /* insert the response for tag1 */ | |
d7c99a70 | 302 | rpc.insertResponsePacket(tag1, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 303 | BOOST_CHECK_EQUAL(rpc.size(), 1U); |
181270f6 RG |
304 | |
305 | /* we can retrieve it */ | |
306 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true); | |
307 | BOOST_CHECK_EQUAL(qhash, temphash); | |
308 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
309 | ||
310 | /* with both interfaces */ | |
311 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &temphash), true); | |
312 | BOOST_CHECK_EQUAL(qhash, temphash); | |
313 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
314 | ||
315 | /* but not with the second tag */ | |
316 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), false); | |
317 | /* we should still get the same hash */ | |
318 | BOOST_CHECK_EQUAL(temphash, qhash); | |
319 | ||
320 | /* adding a response for the second tag */ | |
d7c99a70 | 321 | rpc.insertResponsePacket(tag2, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, false); |
690b86b7 | 322 | BOOST_CHECK_EQUAL(rpc.size(), 2U); |
181270f6 RG |
323 | |
324 | /* We still get the correct response for the first tag */ | |
325 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, time(nullptr), &fpacket, &age, &temphash), true); | |
326 | BOOST_CHECK_EQUAL(qhash, temphash); | |
327 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
328 | ||
329 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag1, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true); | |
330 | BOOST_CHECK_EQUAL(qhash, temphash); | |
331 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
332 | ||
333 | /* and the correct response for the second tag */ | |
334 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, time(nullptr), &fpacket, &age, &temphash), true); | |
335 | BOOST_CHECK_EQUAL(qhash, temphash); | |
336 | BOOST_CHECK_EQUAL(fpacket, r2packet); | |
337 | ||
338 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag2, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true); | |
339 | BOOST_CHECK_EQUAL(qhash, temphash); | |
340 | BOOST_CHECK_EQUAL(fpacket, r2packet); | |
341 | } | |
49a3500d | 342 | |
a7f98e34 O |
343 | BOOST_AUTO_TEST_CASE(test_recPacketCache_TCP) |
344 | { | |
e51c2d64 | 345 | /* Insert a response with UDP, the exact same query with a TCP flag |
1e325a92 | 346 | should lead to a miss. |
e51c2d64 | 347 | */ |
eeab0dc2 | 348 | RecursorPacketCache rpc(1000); |
e51c2d64 | 349 | string fpacket; |
a7f98e34 O |
350 | uint32_t age = 0; |
351 | uint32_t qhash = 0; | |
352 | uint32_t temphash = 0; | |
353 | uint32_t ttd = 3600; | |
e51c2d64 O |
354 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
355 | ||
e51c2d64 O |
356 | DNSName qname("www.powerdns.com"); |
357 | vector<uint8_t> packet; | |
358 | DNSPacketWriter pw(packet, qname, QType::A); | |
a7f98e34 O |
359 | pw.getHeader()->rd = true; |
360 | pw.getHeader()->qr = false; | |
361 | pw.getHeader()->id = dns_random_uint16(); | |
e51c2d64 O |
362 | string qpacket(reinterpret_cast<const char*>(&packet[0]), packet.size()); |
363 | pw.startRecord(qname, QType::A, ttd); | |
364 | ||
365 | /* Both interfaces (with and without the qname/qtype/qclass) should get the same hash */ | |
366 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, time(nullptr), &fpacket, &age, &qhash), false); | |
367 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, nullptr, &temphash, nullptr, false), false); | |
368 | BOOST_CHECK_EQUAL(qhash, temphash); | |
369 | ||
370 | /* Different tcp/udp, should still get get the same hash, for both interfaces */ | |
371 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, time(nullptr), &fpacket, &age, &qhash), false); | |
372 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, nullptr, &temphash, nullptr, true), false); | |
373 | BOOST_CHECK_EQUAL(qhash, temphash); | |
374 | ||
375 | { | |
376 | ARecordContent ar("127.0.0.1"); | |
377 | ar.toPacket(pw); | |
378 | pw.commit(); | |
379 | } | |
380 | string r1packet(reinterpret_cast<const char*>(&packet[0]), packet.size()); | |
381 | ||
382 | { | |
383 | ARecordContent ar("127.0.0.2"); | |
384 | ar.toPacket(pw); | |
385 | pw.commit(); | |
386 | } | |
387 | string r2packet(reinterpret_cast<const char*>(&packet[0]), packet.size()); | |
388 | ||
389 | BOOST_CHECK(r1packet != r2packet); | |
390 | ||
391 | /* inserting a response for udp */ | |
392 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, false); | |
393 | BOOST_CHECK_EQUAL(rpc.size(), 1U); | |
394 | ||
395 | /* inserting a different response for tcp, should not override the first one */ | |
396 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, true); | |
397 | BOOST_CHECK_EQUAL(rpc.size(), 2U); | |
398 | ||
399 | /* remove all responses from the cache */ | |
48d02436 | 400 | rpc.doPruneTo(time(nullptr), 0); |
e51c2d64 O |
401 | BOOST_CHECK_EQUAL(rpc.size(), 0U); |
402 | ||
403 | /* reinsert both */ | |
404 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, false); | |
405 | BOOST_CHECK_EQUAL(rpc.size(), 1U); | |
406 | ||
407 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, true); | |
408 | BOOST_CHECK_EQUAL(rpc.size(), 2U); | |
409 | ||
410 | /* remove the responses by qname, should remove both */ | |
411 | rpc.doWipePacketCache(qname); | |
412 | BOOST_CHECK_EQUAL(rpc.size(), 0U); | |
413 | ||
414 | /* insert the response for tcp */ | |
415 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r1packet), time(0), ttd, vState::Indeterminate, boost::none, true); | |
416 | BOOST_CHECK_EQUAL(rpc.size(), 1U); | |
417 | ||
418 | vState vState; | |
419 | /* we can retrieve it */ | |
420 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &vState, &temphash, nullptr, true), true); | |
421 | BOOST_CHECK_EQUAL(qhash, temphash); | |
422 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
423 | ||
424 | /* first interface assumes udp */ | |
425 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, time(nullptr), &fpacket, &age, &temphash), false); | |
426 | BOOST_CHECK_EQUAL(qhash, temphash); | |
427 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
428 | ||
2f612c56 | 429 | /* and not with explicit udp */ |
e51c2d64 O |
430 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &vState, &temphash, nullptr, false), false); |
431 | /* we should still get the same hash */ | |
432 | BOOST_CHECK_EQUAL(temphash, qhash); | |
433 | ||
434 | /* adding a response for udp */ | |
435 | rpc.insertResponsePacket(0, qhash, string(qpacket), qname, QType::A, QClass::IN, string(r2packet), time(0), ttd, vState::Indeterminate, boost::none, false); | |
436 | BOOST_CHECK_EQUAL(rpc.size(), 2U); | |
437 | ||
438 | /* We get the correct response for udp now */ | |
439 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, time(nullptr), &fpacket, &age, &temphash), true); | |
440 | BOOST_CHECK_EQUAL(qhash, temphash); | |
441 | BOOST_CHECK_EQUAL(fpacket, r2packet); | |
442 | ||
443 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &temphash), true); | |
444 | BOOST_CHECK_EQUAL(qhash, temphash); | |
445 | BOOST_CHECK_EQUAL(fpacket, r2packet); | |
446 | ||
447 | /* and the correct response for tcp */ | |
448 | BOOST_CHECK_EQUAL(rpc.getResponsePacket(0, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &vState, &temphash, nullptr, true), true); | |
449 | BOOST_CHECK_EQUAL(qhash, temphash); | |
450 | BOOST_CHECK_EQUAL(fpacket, r1packet); | |
451 | } | |
452 | ||
49a3500d | 453 | BOOST_AUTO_TEST_SUITE_END() |