]>
Commit | Line | Data |
---|---|---|
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 | 17 | BOOST_AUTO_TEST_SUITE(test_recpacketcache_cc) |
49a3500d | 18 | |
19 | BOOST_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 | ||
87 | BOOST_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 | |
207 | BOOST_AUTO_TEST_SUITE_END() |