]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/speedtest.cc
Solve ticket 281, where we cache nxdomains longer than configured because of the...
[thirdparty/pdns.git] / pdns / speedtest.cc
CommitLineData
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"
9StatBag S;
10#endif
11
12uint64_t g_totalRuns;
13
14volatile bool g_stop;
15
16void alarmHandler(int)
17{
18 g_stop=true;
19}
20
21template<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
46struct 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
70struct 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
87struct 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
103struct 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
119struct 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
145struct 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
169struct 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
199struct 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
223struct 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
248vector<uint8_t> makeEmptyQuery()
249{
250 vector<uint8_t> packet;
251 DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA);
252 return packet;
253}
254
255
256vector<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
288vector<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
320struct 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
334struct 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
350struct 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
364struct 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
378struct 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
392struct NegCacheEntry
393{
394 string d_name;
395 QType d_qtype;
396 string d_qname;
397 uint32_t d_ttd;
398};
399
400struct timeval d_now;
401
402static 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
410bool 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
425struct 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
591struct 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
611struct 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
629struct 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
651struct 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
666struct 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
682struct 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
697struct NOPTest
698{
699 string getName() const
700 {
701 return "null test";
702 }
703
704 void operator()() const
705 {
706 }
707
708};
709
710
711
712int main(int argc, char** argv)
713try
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}
787catch(std::exception &e)
788{
789 cerr<<"Fatal: "<<e.what()<<endl;
790}
791