]>
Commit | Line | Data |
---|---|---|
34383528 BH |
1 | #include "dnsparser.hh" |
2 | #include "sstuff.hh" | |
3 | #include "misc.hh" | |
4 | #include "dnswriter.hh" | |
5 | #include "dnsrecords.hh" | |
6 | #include <boost/format.hpp> | |
7 | #ifndef RECURSOR | |
8 | #include "statbag.hh" | |
9 | StatBag S; | |
10 | #endif | |
11 | ||
12 | uint64_t g_totalRuns; | |
13 | ||
14 | volatile bool g_stop; | |
15 | ||
16 | void alarmHandler(int) | |
17 | { | |
18 | g_stop=true; | |
19 | } | |
20 | ||
21 | template<typename C> void doRun(const C& cmd, int mseconds=100) | |
22 | { | |
23 | struct itimerval it; | |
24 | it.it_value.tv_sec=mseconds/1000; | |
25 | it.it_value.tv_usec = 1000* (mseconds%1000); | |
26 | it.it_interval.tv_sec=0; | |
27 | it.it_interval.tv_usec=0; | |
28 | ||
ecefa116 | 29 | signal(SIGVTALRM, alarmHandler); |
34383528 | 30 | setitimer(ITIMER_VIRTUAL, &it, 0); |
ecefa116 | 31 | |
34383528 BH |
32 | unsigned int runs=0; |
33 | g_stop=false; | |
34 | DTime dt; | |
35 | dt.set(); | |
36 | while(runs++, !g_stop) { | |
37 | cmd(); | |
38 | } | |
39 | double delta=dt.udiff()/1000000.0; | |
40 | boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run"); | |
41 | ||
42 | cerr<< (fmt % cmd.getName() % delta % (runs/delta) % (delta* 1000000.0/runs)) << endl; | |
43 | g_totalRuns += runs; | |
44 | } | |
45 | ||
46 | struct ARecordTest | |
47 | { | |
48 | explicit ARecordTest(int records) : d_records(records) {} | |
49 | ||
50 | string getName() const | |
51 | { | |
52 | return (boost::format("%d a records") % d_records).str(); | |
53 | } | |
54 | ||
55 | void operator()() const | |
56 | { | |
57 | vector<uint8_t> packet; | |
58 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A); | |
59 | for(int records = 0; records < d_records; records++) { | |
60 | pw.startRecord("outpost.ds9a.nl", QType::A); | |
61 | ARecordContent arc("1.2.3.4"); | |
62 | arc.toPacket(pw); | |
63 | } | |
64 | pw.commit(); | |
65 | } | |
66 | int d_records; | |
67 | }; | |
68 | ||
69 | ||
70 | struct MakeStringFromCharStarTest | |
71 | { | |
72 | MakeStringFromCharStarTest() : d_size(0){} | |
73 | string getName() const | |
74 | { | |
75 | return (boost::format("make a std::string")).str(); | |
76 | } | |
77 | ||
78 | void operator()() const | |
79 | { | |
80 | string name("outpost.ds9a.nl"); | |
81 | d_size += name.length(); | |
82 | ||
83 | } | |
84 | mutable int d_size; | |
85 | }; | |
86 | ||
87 | struct MakeARecordTest | |
88 | { | |
89 | string getName() const | |
90 | { | |
91 | return (boost::format("make a-record")).str(); | |
92 | } | |
93 | ||
94 | void operator()() const | |
95 | { | |
96 | static string src("1.2.3.4"); | |
97 | ARecordContent arc(src); | |
98 | //ARecordContent arc(0x01020304); | |
99 | ||
100 | } | |
101 | }; | |
102 | ||
103 | struct MakeARecordTestMM | |
104 | { | |
105 | string getName() const | |
106 | { | |
107 | return (boost::format("make a-record (mm)")).str(); | |
108 | } | |
109 | ||
110 | void operator()() const | |
111 | { | |
112 | DNSRecordContent*drc = DNSRecordContent::mastermake(QType::A, 1, | |
b7821a82 | 113 | "1.2.3.4"); |
34383528 BH |
114 | delete drc; |
115 | } | |
116 | }; | |
117 | ||
118 | ||
119 | struct A2RecordTest | |
120 | { | |
121 | explicit A2RecordTest(int records) : d_records(records) {} | |
122 | ||
123 | string getName() const | |
124 | { | |
125 | return (boost::format("%d a records") % d_records).str(); | |
126 | } | |
127 | ||
128 | void operator()() const | |
129 | { | |
130 | vector<uint8_t> packet; | |
131 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A); | |
132 | ARecordContent arc("1.2.3.4"); | |
133 | string name("outpost.ds9a.nl"); | |
134 | for(int records = 0; records < d_records; records++) { | |
135 | pw.startRecord(name, QType::A); | |
136 | ||
137 | arc.toPacket(pw); | |
138 | } | |
139 | pw.commit(); | |
140 | } | |
141 | int d_records; | |
142 | }; | |
143 | ||
144 | ||
145 | struct TXTRecordTest | |
146 | { | |
147 | explicit TXTRecordTest(int records) : d_records(records) {} | |
148 | ||
149 | string getName() const | |
150 | { | |
151 | return (boost::format("%d TXT records") % d_records).str(); | |
152 | } | |
153 | ||
154 | void operator()() const | |
155 | { | |
156 | vector<uint8_t> packet; | |
157 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::TXT); | |
158 | for(int records = 0; records < d_records; records++) { | |
159 | pw.startRecord("outpost.ds9a.nl", QType::TXT); | |
160 | TXTRecordContent arc("\"een leuk verhaaltje in een TXT\""); | |
161 | arc.toPacket(pw); | |
162 | } | |
163 | pw.commit(); | |
164 | } | |
165 | int d_records; | |
166 | }; | |
167 | ||
168 | ||
169 | struct GenericRecordTest | |
170 | { | |
171 | explicit GenericRecordTest(int records, uint16_t type, const std::string& content) | |
172 | : d_records(records), d_type(type), d_content(content) {} | |
173 | ||
174 | string getName() const | |
175 | { | |
176 | return (boost::format("%d %s records") % d_records % | |
b7821a82 | 177 | DNSRecordContent::NumberToType(d_type)).str(); |
34383528 BH |
178 | } |
179 | ||
180 | void operator()() const | |
181 | { | |
182 | vector<uint8_t> packet; | |
183 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", d_type); | |
184 | for(int records = 0; records < d_records; records++) { | |
185 | pw.startRecord("outpost.ds9a.nl", d_type); | |
186 | DNSRecordContent*drc = DNSRecordContent::mastermake(d_type, 1, | |
b7821a82 | 187 | d_content); |
34383528 BH |
188 | drc->toPacket(pw); |
189 | delete drc; | |
190 | } | |
191 | pw.commit(); | |
192 | } | |
193 | int d_records; | |
194 | uint16_t d_type; | |
195 | string d_content; | |
196 | }; | |
197 | ||
198 | ||
199 | struct AAAARecordTest | |
200 | { | |
201 | explicit AAAARecordTest(int records) : d_records(records) {} | |
202 | ||
203 | string getName() const | |
204 | { | |
205 | return (boost::format("%d aaaa records (mm)") % d_records).str(); | |
206 | } | |
207 | ||
208 | void operator()() const | |
209 | { | |
210 | vector<uint8_t> packet; | |
211 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::AAAA); | |
212 | for(int records = 0; records < d_records; records++) { | |
213 | pw.startRecord("outpost.ds9a.nl", QType::AAAA); | |
214 | DNSRecordContent*drc = DNSRecordContent::mastermake(QType::AAAA, 1, "fe80::21d:92ff:fe6d:8441"); | |
215 | drc->toPacket(pw); | |
216 | delete drc; | |
217 | } | |
218 | pw.commit(); | |
219 | } | |
220 | int d_records; | |
221 | }; | |
222 | ||
223 | struct SOARecordTest | |
224 | { | |
225 | explicit SOARecordTest(int records) : d_records(records) {} | |
226 | ||
227 | string getName() const | |
228 | { | |
229 | return (boost::format("%d soa records (mm)") % d_records).str(); | |
230 | } | |
231 | ||
232 | void operator()() const | |
233 | { | |
234 | vector<uint8_t> packet; | |
235 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA); | |
236 | ||
237 | for(int records = 0; records < d_records; records++) { | |
238 | pw.startRecord("outpost.ds9a.nl", QType::SOA); | |
239 | DNSRecordContent*drc = DNSRecordContent::mastermake(QType::SOA, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400"); | |
240 | drc->toPacket(pw); | |
241 | delete drc; | |
242 | } | |
243 | pw.commit(); | |
244 | } | |
245 | int d_records; | |
246 | }; | |
247 | ||
248 | vector<uint8_t> makeEmptyQuery() | |
249 | { | |
250 | vector<uint8_t> packet; | |
251 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA); | |
252 | return packet; | |
253 | } | |
254 | ||
255 | ||
256 | vector<uint8_t> makeRootReferral() | |
257 | { | |
258 | vector<uint8_t> packet; | |
259 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA); | |
260 | ||
261 | // nobody reads what we output, but it appears to be the magic that shuts some nameservers up | |
262 | static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "128.8.10.90", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53", | |
b7821a82 | 263 | "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"}; |
34383528 BH |
264 | static char templ[40]; |
265 | strncpy(templ,"a.root-servers.net", sizeof(templ) - 1); | |
266 | ||
267 | ||
268 | for(char c='a';c<='m';++c) { | |
269 | *templ=c; | |
270 | pw.startRecord(".", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY); | |
271 | DNSRecordContent* drc = DNSRecordContent::mastermake(QType::NS, 1, templ); | |
272 | drc->toPacket(pw); | |
273 | delete drc; | |
274 | } | |
275 | ||
276 | for(char c='a';c<='m';++c) { | |
277 | *templ=c; | |
278 | pw.startRecord(".", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL); | |
279 | DNSRecordContent* drc = DNSRecordContent::mastermake(QType::A, 1, ips[c-'a']); | |
280 | drc->toPacket(pw); | |
281 | delete drc; | |
282 | } | |
283 | pw.commit(); | |
284 | return packet; | |
285 | ||
286 | } | |
287 | ||
288 | vector<uint8_t> makeTypicalReferral() | |
289 | { | |
290 | vector<uint8_t> packet; | |
291 | DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A); | |
292 | ||
293 | pw.startRecord("ds9a.nl", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY); | |
294 | DNSRecordContent* drc = DNSRecordContent::mastermake(QType::NS, 1, "ns1.ds9a.nl"); | |
295 | drc->toPacket(pw); | |
296 | delete drc; | |
297 | ||
298 | pw.startRecord("ds9a.nl", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY); | |
299 | drc = DNSRecordContent::mastermake(QType::NS, 1, "ns2.ds9a.nl"); | |
300 | drc->toPacket(pw); | |
301 | delete drc; | |
302 | ||
303 | ||
304 | pw.startRecord("ns1.ds9a.nl", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL); | |
305 | drc = DNSRecordContent::mastermake(QType::A, 1, "1.2.3.4"); | |
306 | drc->toPacket(pw); | |
307 | delete drc; | |
308 | ||
309 | pw.startRecord("ns2.ds9a.nl", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL); | |
310 | drc = DNSRecordContent::mastermake(QType::A, 1, "4.3.2.1"); | |
311 | drc->toPacket(pw); | |
312 | delete drc; | |
313 | ||
314 | pw.commit(); | |
315 | return packet; | |
316 | } | |
317 | ||
318 | ||
319 | ||
320 | struct RootRefTest | |
321 | { | |
322 | string getName() const | |
323 | { | |
324 | return "write rootreferral"; | |
325 | } | |
326 | ||
327 | void operator()() const | |
328 | { | |
329 | vector<uint8_t> packet=makeRootReferral(); | |
330 | } | |
331 | ||
332 | }; | |
333 | ||
b7821a82 BH |
334 | struct StackMallocTest |
335 | { | |
336 | string getName() const | |
337 | { | |
338 | return "stack allocation"; | |
339 | } | |
340 | ||
341 | void operator()() const | |
342 | { | |
343 | char *buffer= new char[200000]; | |
344 | delete buffer; | |
345 | } | |
346 | ||
347 | }; | |
348 | ||
349 | ||
34383528 BH |
350 | struct EmptyQueryTest |
351 | { | |
352 | string getName() const | |
353 | { | |
354 | return "write empty query"; | |
355 | } | |
356 | ||
357 | void operator()() const | |
358 | { | |
359 | vector<uint8_t> packet=makeEmptyQuery(); | |
360 | } | |
361 | ||
362 | }; | |
363 | ||
364 | struct TypicalRefTest | |
365 | { | |
366 | string getName() const | |
367 | { | |
368 | return "write typical referral"; | |
369 | } | |
370 | ||
371 | void operator()() const | |
372 | { | |
373 | vector<uint8_t> packet=makeTypicalReferral(); | |
374 | } | |
375 | ||
376 | }; | |
377 | ||
b7821a82 BH |
378 | struct TCacheComp |
379 | { | |
380 | bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const | |
381 | { | |
382 | int cmp=strcasecmp(a.first.c_str(), b.first.c_str()); | |
383 | if(cmp < 0) | |
384 | return true; | |
385 | if(cmp > 0) | |
386 | return false; | |
387 | ||
388 | return a.second < b.second; | |
389 | } | |
390 | }; | |
391 | ||
392 | struct NegCacheEntry | |
393 | { | |
394 | string d_name; | |
395 | QType d_qtype; | |
396 | string d_qname; | |
397 | uint32_t d_ttd; | |
398 | }; | |
399 | ||
400 | struct timeval d_now; | |
401 | ||
402 | static bool magicAddrMatch(const QType& query, const QType& answer) | |
403 | { | |
404 | if(query.getCode() != QType::ADDR) | |
405 | return false; | |
406 | return answer.getCode() == QType::A || answer.getCode() == QType::AAAA; | |
407 | } | |
408 | ||
409 | ||
410 | bool moreSpecificThan(const string& a, const string &b) | |
411 | { | |
412 | static string dot("."); | |
413 | int counta=(a!=dot), countb=(b!=dot); | |
414 | ||
415 | for(string::size_type n=0;n<a.size();++n) | |
416 | if(a[n]=='.') | |
417 | counta++; | |
418 | for(string::size_type n=0;n<b.size();++n) | |
419 | if(b[n]=='.') | |
420 | countb++; | |
421 | return counta>countb; | |
422 | } | |
423 | ||
34383528 BH |
424 | |
425 | struct ParsePacketTest | |
426 | { | |
427 | explicit ParsePacketTest(const vector<uint8_t>& packet, const std::string& name) | |
428 | : d_packet(packet), d_name(name) | |
429 | {} | |
430 | ||
431 | string getName() const | |
432 | { | |
433 | return "parse '"+d_name+"'"; | |
434 | } | |
435 | ||
436 | void operator()() const | |
437 | { | |
438 | MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); | |
b7821a82 BH |
439 | typedef map<pair<string, QType>, set<DNSResourceRecord>, TCacheComp > tcache_t; |
440 | tcache_t tcache; | |
441 | ||
442 | struct { | |
443 | vector<DNSResourceRecord> d_result; | |
444 | bool d_aabit; | |
445 | int d_rcode; | |
446 | } lwr; | |
447 | DNSResourceRecord rr; | |
448 | for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) { | |
449 | DNSResourceRecord rr; | |
450 | rr.qtype=i->first.d_type; | |
451 | rr.qname=i->first.d_label; | |
452 | ||
453 | rr.ttl=i->first.d_ttl; | |
454 | rr.content=i->first.d_content->getZoneRepresentation(); // this should be the serialised form | |
455 | rr.d_place=(DNSResourceRecord::Place) i->first.d_place; | |
456 | lwr.d_result.push_back(rr); | |
457 | } | |
458 | ||
459 | ||
460 | ||
461 | ||
462 | // reap all answers from this packet that are acceptable | |
463 | for(vector<DNSResourceRecord>::iterator i=lwr.d_result.begin();i != lwr.d_result.end();++i) { | |
464 | if(i->qtype.getCode() == QType::OPT) { | |
465 | // <<prefix<<qname<<": skipping OPT answer '"<<i->qname<<"' from '"<<auth<<"' nameservers" <<endl; | |
466 | continue; | |
467 | } | |
468 | // LOG<<prefix<<qname<<": accept answer '"<<i->qname<<"|"<<i->qtype.getName()<<"|"<<i->content<<"' from '"<<auth<<"' nameservers? "; | |
469 | if(i->qtype.getCode()==QType::ANY) { | |
470 | // LOG<<"NO! - we don't accept 'ANY' data"<<endl; | |
471 | continue; | |
472 | } | |
473 | string auth("."); | |
474 | if(dottedEndsOn(i->qname, auth)) { | |
475 | if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && i->d_place==DNSResourceRecord::ANSWER && 0) { | |
476 | // LOG<<"NO! Is from delegation-only zone"<<endl; | |
477 | // s_nodelegated++; | |
478 | return; // RCode::NXDomain; | |
479 | } | |
480 | else { | |
481 | // LOG<<"YES!"<<endl; | |
482 | ||
483 | // i->ttl=min(s_maxcachettl, i->ttl); | |
484 | ||
485 | DNSResourceRecord rr=*i; | |
486 | rr.d_place=DNSResourceRecord::ANSWER; | |
487 | ||
488 | // rr.ttl += d_now.tv_sec; | |
489 | ||
490 | if(rr.qtype.getCode() == QType::NS) // people fiddle with the case | |
491 | rr.content=toLower(rr.content); // this must stay! (the cache can't be case-insensitive on the RHS of records) | |
492 | tcache[make_pair(i->qname,i->qtype)].insert(rr); | |
493 | } | |
494 | } | |
495 | else | |
496 | ; // LOG<<"NO!"<<endl; | |
497 | } | |
498 | ||
499 | // supplant | |
500 | for(tcache_t::iterator i=tcache.begin();i!=tcache.end();++i) { | |
501 | if(i->second.size() > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) | |
502 | uint32_t lowestTTL=numeric_limits<uint32_t>::max(); | |
503 | for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j) | |
504 | lowestTTL=min(lowestTTL, j->ttl); | |
505 | ||
506 | for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j) | |
507 | ((tcache_t::value_type::second_type::value_type*)&(*j))->ttl=lowestTTL; | |
508 | } | |
509 | ||
510 | // RC.replace(d_now.tv_sec, i->first.first, i->first.second, i->second, lwr.d_aabit); | |
511 | } | |
512 | set<string, CIStringCompare> nsset; | |
513 | // LOG<<prefix<<qname<<": determining status after receiving this packet"<<endl; | |
514 | ||
515 | bool done=false, realreferral=false, negindic=false; | |
516 | string newauth, soaname, newtarget; | |
517 | string qname("."); | |
518 | vector<DNSResourceRecord> ret; | |
519 | QType qtype(QType::A); | |
520 | string auth("."); | |
521 | ||
522 | for(vector<DNSResourceRecord>::const_iterator i=lwr.d_result.begin();i!=lwr.d_result.end();++i) { | |
523 | if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA && | |
524 | lwr.d_rcode==RCode::NXDomain) { | |
525 | // LOG<<prefix<<qname<<": got negative caching indication for RECORD '"<<qname+"'"<<endl; | |
526 | ret.push_back(*i); | |
527 | ||
528 | NegCacheEntry ne; | |
529 | ||
530 | ne.d_qname=i->qname; | |
531 | ne.d_ttd=d_now.tv_sec + min(i->ttl, 3600U); // controversial | |
532 | ne.d_name=qname; | |
533 | ne.d_qtype=QType(0); // this encodes 'whole record' | |
534 | ||
535 | { | |
536 | // Lock l(&s_negcachelock); | |
537 | // replacing_insert(s_negcache, ne); | |
538 | } | |
539 | negindic=true; | |
540 | } | |
ecefa116 | 541 | else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) { |
b7821a82 BH |
542 | ret.push_back(*i); |
543 | newtarget=i->content; | |
544 | } | |
545 | // for ANY answers we *must* have an authoritive answer | |
546 | else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) && | |
547 | ( | |
548 | i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) ) | |
549 | ) | |
550 | ) | |
551 | { | |
552 | ||
553 | // LOG<<prefix<<qname<<": answer is in: resolved to '"<< i->content<<"|"<<i->qtype.getName()<<"'"<<endl; | |
554 | ||
555 | done=true; | |
556 | ret.push_back(*i); | |
557 | } | |
558 | else if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::NS) { | |
559 | if(moreSpecificThan(i->qname,auth)) { | |
560 | newauth=i->qname; | |
561 | // LOG<<prefix<<qname<<": got NS record '"<<i->qname<<"' -> '"<<i->content<<"'"<<endl; | |
562 | realreferral=true; | |
563 | } | |
564 | else | |
565 | ;// // LOG<<prefix<<qname<<": got upwards/level NS record '"<<i->qname<<"' -> '"<<i->content<<"', had '"<<auth<<"'"<<endl; | |
566 | nsset.insert(i->content); | |
567 | } | |
568 | else if(!done && i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA && | |
569 | lwr.d_rcode==RCode::NoError) { | |
570 | // LOG<<prefix<<qname<<": got negative caching indication for '"<< (qname+"|"+i->qtype.getName()+"'") <<endl; | |
571 | ret.push_back(*i); | |
572 | ||
573 | NegCacheEntry ne; | |
574 | ne.d_qname=i->qname; | |
575 | ne.d_ttd=d_now.tv_sec + i->ttl; | |
576 | ne.d_name=qname; | |
577 | ne.d_qtype=qtype; | |
578 | if(qtype.getCode()) { // prevents us from blacking out a whole domain | |
579 | // Lock l(&s_negcachelock); | |
580 | // replacing_insert(s_negcache, ne); | |
581 | } | |
582 | negindic=true; | |
583 | } | |
584 | } | |
585 | ||
34383528 BH |
586 | } |
587 | const vector<uint8_t>& d_packet; | |
588 | std::string d_name; | |
589 | }; | |
590 | ||
b7821a82 BH |
591 | struct ParsePacketBareTest |
592 | { | |
593 | explicit ParsePacketBareTest(const vector<uint8_t>& packet, const std::string& name) | |
594 | : d_packet(packet), d_name(name) | |
595 | {} | |
596 | ||
597 | string getName() const | |
598 | { | |
599 | return "parse '"+d_name+"' bare"; | |
600 | } | |
601 | ||
602 | void operator()() const | |
603 | { | |
604 | MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); | |
605 | } | |
606 | const vector<uint8_t>& d_packet; | |
607 | std::string d_name; | |
608 | }; | |
609 | ||
610 | ||
34383528 BH |
611 | struct SimpleCompressTest |
612 | { | |
613 | explicit SimpleCompressTest(const std::string& name) | |
614 | : d_name(name) | |
615 | {} | |
616 | ||
617 | string getName() const | |
618 | { | |
619 | return "compress '"+d_name+"'"; | |
620 | } | |
621 | ||
622 | void operator()() const | |
623 | { | |
624 | simpleCompress(d_name); | |
625 | } | |
626 | std::string d_name; | |
627 | }; | |
628 | ||
629 | struct VectorExpandTest | |
630 | { | |
631 | string getName() const | |
632 | { | |
633 | return "vector expand"; | |
634 | } | |
635 | ||
636 | void operator()() const | |
637 | { | |
638 | vector<uint8_t> d_record; | |
639 | d_record.resize(12); | |
640 | ||
641 | string out="\x03www\x04ds9a\x02nl"; | |
642 | string::size_type len = d_record.size(); | |
643 | d_record.resize(len + out.length()); | |
644 | memcpy(&d_record[len], out.c_str(), out.length()); | |
645 | } | |
646 | ||
647 | }; | |
648 | ||
b7821a82 BH |
649 | |
650 | ||
651 | struct IEqualsTest | |
652 | { | |
653 | string getName() const | |
654 | { | |
655 | return "iequals test"; | |
656 | } | |
657 | ||
658 | void operator()() const | |
659 | { | |
660 | static string a("www.ds9a.nl"), b("www.lwn.net"); | |
ecefa116 | 661 | bool ret = boost::iequals(a, b); |
b7821a82 BH |
662 | } |
663 | ||
664 | }; | |
665 | ||
666 | struct MyIEqualsTest | |
667 | { | |
668 | string getName() const | |
669 | { | |
670 | return "pdns_iequals test"; | |
671 | } | |
672 | ||
673 | void operator()() const | |
674 | { | |
675 | static string a("www.ds9a.nl"), b("www.lwn.net"); | |
676 | bool ret = pdns_iequals(a, b); | |
677 | } | |
678 | ||
679 | }; | |
680 | ||
681 | ||
682 | struct StrcasecmpTest | |
683 | { | |
684 | string getName() const | |
685 | { | |
686 | return "strcasecmp test"; | |
687 | } | |
688 | ||
689 | void operator()() const | |
690 | { | |
691 | static string a("www.ds9a.nl"), b("www.lwn.net"); | |
692 | bool ret = strcasecmp(a.c_str(), b.c_str()); | |
693 | } | |
694 | }; | |
695 | ||
696 | ||
34383528 BH |
697 | struct NOPTest |
698 | { | |
699 | string getName() const | |
700 | { | |
701 | return "null test"; | |
702 | } | |
703 | ||
704 | void operator()() const | |
705 | { | |
706 | } | |
707 | ||
708 | }; | |
709 | ||
710 | ||
711 | ||
712 | int main(int argc, char** argv) | |
713 | try | |
714 | { | |
715 | reportAllTypes(); | |
b7821a82 | 716 | doRun(NOPTest()); |
ecefa116 | 717 | |
b7821a82 BH |
718 | doRun(IEqualsTest()); |
719 | doRun(MyIEqualsTest()); | |
720 | doRun(StrcasecmpTest()); | |
721 | ||
722 | doRun(StackMallocTest()); | |
34383528 BH |
723 | |
724 | vector<uint8_t> packet = makeRootReferral(); | |
b7821a82 | 725 | doRun(ParsePacketBareTest(packet, "root-referral")); |
34383528 BH |
726 | doRun(ParsePacketTest(packet, "root-referral")); |
727 | ||
728 | doRun(RootRefTest()); | |
729 | ||
730 | doRun(EmptyQueryTest()); | |
731 | doRun(TypicalRefTest()); | |
732 | ||
733 | ||
734 | packet = makeEmptyQuery(); | |
735 | doRun(ParsePacketTest(packet, "empty-query")); | |
736 | ||
737 | packet = makeTypicalReferral(); | |
738 | cerr<<"typical referral size: "<<packet.size()<<endl; | |
b7821a82 | 739 | doRun(ParsePacketBareTest(packet, "typical-referral")); |
34383528 | 740 | |
b7821a82 | 741 | doRun(ParsePacketTest(packet, "typical-referral")); |
34383528 BH |
742 | |
743 | doRun(SimpleCompressTest("www.france.ds9a.nl")); | |
744 | ||
b7821a82 | 745 | |
34383528 BH |
746 | doRun(VectorExpandTest()); |
747 | ||
748 | doRun(ARecordTest(1)); | |
749 | doRun(ARecordTest(2)); | |
750 | doRun(ARecordTest(4)); | |
751 | doRun(ARecordTest(64)); | |
752 | ||
753 | doRun(A2RecordTest(1)); | |
754 | doRun(A2RecordTest(2)); | |
755 | doRun(A2RecordTest(4)); | |
756 | doRun(A2RecordTest(64)); | |
757 | ||
758 | doRun(MakeStringFromCharStarTest()); | |
759 | doRun(MakeARecordTest()); | |
760 | doRun(MakeARecordTestMM()); | |
761 | ||
762 | doRun(AAAARecordTest(1)); | |
763 | doRun(AAAARecordTest(2)); | |
764 | doRun(AAAARecordTest(4)); | |
765 | doRun(AAAARecordTest(64)); | |
766 | ||
767 | doRun(TXTRecordTest(1)); | |
768 | doRun(TXTRecordTest(2)); | |
769 | doRun(TXTRecordTest(4)); | |
770 | doRun(TXTRecordTest(64)); | |
771 | ||
772 | doRun(GenericRecordTest(1, QType::NS, "powerdnssec1.ds9a.nl")); | |
773 | doRun(GenericRecordTest(2, QType::NS, "powerdnssec1.ds9a.nl")); | |
774 | doRun(GenericRecordTest(4, QType::NS, "powerdnssec1.ds9a.nl")); | |
775 | doRun(GenericRecordTest(64, QType::NS, "powerdnssec1.ds9a.nl")); | |
776 | ||
777 | ||
778 | ||
779 | doRun(SOARecordTest(1)); | |
780 | doRun(SOARecordTest(2)); | |
781 | doRun(SOARecordTest(4)); | |
782 | doRun(SOARecordTest(64)); | |
783 | ||
784 | cerr<<"Total runs: " << g_totalRuns<<endl; | |
785 | ||
786 | } | |
787 | catch(std::exception &e) | |
788 | { | |
789 | cerr<<"Fatal: "<<e.what()<<endl; | |
790 | } | |
791 |