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