]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/speedtest.cc
REVERT ME: remove test that fails compilation
[thirdparty/pdns.git] / pdns / speedtest.cc
1 #include "config.h"
2 #include <boost/format.hpp>
3 #include <boost/container/string.hpp>
4 #include "dnsparser.hh"
5 #include "sstuff.hh"
6 #include "misc.hh"
7 #include "dnswriter.hh"
8 #include "dnsrecords.hh"
9 #include <fstream>
10
11 #ifndef RECURSOR
12 #include "statbag.hh"
13 #include "base64.hh"
14 StatBag S;
15 #endif
16
17 volatile bool g_ret; // make sure the optimizer does not get too smart
18 uint64_t g_totalRuns;
19 volatile bool g_stop;
20
21 void alarmHandler(int)
22 {
23 g_stop=true;
24 }
25
26 template<typename C> void doRun(const C& cmd, int mseconds=100)
27 {
28 struct itimerval it;
29 it.it_value.tv_sec=mseconds/1000;
30 it.it_value.tv_usec = 1000* (mseconds%1000);
31 it.it_interval.tv_sec=0;
32 it.it_interval.tv_usec=0;
33
34 signal(SIGVTALRM, alarmHandler);
35 setitimer(ITIMER_VIRTUAL, &it, 0);
36
37 unsigned int runs=0;
38 g_stop=false;
39 CPUTime dt;
40 dt.start();
41 while(runs++, !g_stop) {
42 cmd();
43 }
44 double delta=dt.ndiff()/1000000000.0;
45 boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run");
46
47 cerr<< (fmt % cmd.getName() % delta % (runs/delta) % (delta* 1000000.0/runs)) << endl;
48 g_totalRuns += runs;
49 }
50
51 struct ARecordTest
52 {
53 explicit ARecordTest(int records) : d_records(records) {}
54
55 string getName() const
56 {
57 return (boost::format("%d a records") % d_records).str();
58 }
59
60 void operator()() const
61 {
62 vector<uint8_t> packet;
63 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::A);
64 for(int records = 0; records < d_records; records++) {
65 pw.startRecord(DNSName("outpost.ds9a.nl"), QType::A);
66 ARecordContent arc("1.2.3.4");
67 arc.toPacket(pw);
68 }
69 pw.commit();
70 }
71 int d_records;
72 };
73
74
75 struct MakeStringFromCharStarTest
76 {
77 MakeStringFromCharStarTest() : d_size(0){}
78 string getName() const
79 {
80 return (boost::format("make a std::string")).str();
81 }
82
83 void operator()() const
84 {
85 string name("outpost.ds9a.nl");
86 d_size += name.length();
87
88 }
89 mutable int d_size;
90 };
91
92
93 struct GetTimeTest
94 {
95 string getName() const
96 {
97 return "gettimeofday-test";
98 }
99
100 void operator()() const
101 {
102 struct timeval tv;
103 gettimeofday(&tv, 0);
104 }
105 };
106
107 pthread_mutex_t s_testlock=PTHREAD_MUTEX_INITIALIZER;
108
109 struct GetLockUncontendedTest
110 {
111 string getName() const
112 {
113 return "getlock-uncontended-test";
114 }
115
116 void operator()() const
117 {
118 pthread_mutex_lock(&s_testlock);
119 pthread_mutex_unlock(&s_testlock);
120 }
121 };
122
123
124 struct StaticMemberTest
125 {
126 string getName() const
127 {
128 return "static-member-test";
129 }
130
131 void operator()() const
132 {
133 static string* s_ptr;
134 if(!s_ptr)
135 s_ptr = new string();
136 }
137 };
138
139 struct StringtokTest
140 {
141 string getName() const
142 {
143 return "stringtok";
144 }
145
146 void operator()() const
147 {
148 string str("the quick brown fox jumped");
149 vector<string> parts;
150 stringtok(parts, str);
151 }
152 };
153
154 struct VStringtokTest
155 {
156 string getName() const
157 {
158 return "vstringtok";
159 }
160
161 void operator()() const
162 {
163 string str("the quick brown fox jumped");
164 vector<pair<unsigned int, unsigned> > parts;
165 vstringtok(parts, str);
166 }
167 };
168
169 struct StringAppendTest
170 {
171 string getName() const
172 {
173 return "stringappend";
174 }
175
176 void operator()() const
177 {
178 string str;
179 static char i;
180 for(int n=0; n < 1000; ++n)
181 str.append(1, i);
182 i++;
183 }
184 };
185
186
187 struct BoostStringAppendTest
188 {
189 string getName() const
190 {
191 return "booststringappend";
192 }
193
194 void operator()() const
195 {
196 boost::container::string str;
197 static char i;
198 for(int n=0; n < 1000; ++n)
199 str.append(1, i);
200 i++;
201 }
202 };
203
204
205
206 struct MakeARecordTest
207 {
208 string getName() const
209 {
210 return (boost::format("make a-record")).str();
211 }
212
213 void operator()() const
214 {
215 static string src("1.2.3.4");
216 ARecordContent arc(src);
217 //ARecordContent arc(0x01020304);
218
219 }
220 };
221
222 vector<uint8_t> makeBigReferral()
223 {
224
225 vector<uint8_t> packet;
226 DNSPacketWriter pw(packet, DNSName("www.google.com"), QType::A);
227
228 string gtld="x.gtld-servers.net";
229 for(char c='a'; c<= 'm';++c) {
230 pw.startRecord(DNSName("com"), QType::NS, 3600, 1, DNSResourceRecord::AUTHORITY);
231 gtld[0]=c;
232 auto drc = DNSRecordContent::mastermake(QType::NS, 1, gtld);
233 drc->toPacket(pw);
234 }
235
236 for(char c='a'; c<= 'k';++c) {
237 gtld[0]=c;
238 pw.startRecord(DNSName(gtld), QType::A, 3600, 1, DNSResourceRecord::ADDITIONAL);
239 auto drc = DNSRecordContent::mastermake(QType::A, 1, "1.2.3.4");
240 drc->toPacket(pw);
241 }
242
243
244 pw.startRecord(DNSName("a.gtld-servers.net"), QType::AAAA, 3600, 1, DNSResourceRecord::ADDITIONAL);
245 auto aaaarc = DNSRecordContent::mastermake(QType::AAAA, 1, "2001:503:a83e::2:30");
246 aaaarc->toPacket(pw);
247
248 pw.startRecord(DNSName("b.gtld-servers.net"), QType::AAAA, 3600, 1, DNSResourceRecord::ADDITIONAL);
249 aaaarc = DNSRecordContent::mastermake(QType::AAAA, 1, "2001:503:231d::2:30");
250 aaaarc->toPacket(pw);
251
252
253 pw.commit();
254 return packet;
255 }
256
257 vector<uint8_t> makeBigDNSPacketReferral()
258 {
259 vector<DNSResourceRecord> records;
260 DNSResourceRecord rr;
261 rr.qtype = QType::NS;
262 rr.ttl=3600;
263 rr.qname=DNSName("com");
264
265 string gtld="x.gtld-servers.net";
266 for(char c='a'; c<= 'm';++c) {
267 gtld[0]=c;
268 rr.content = gtld;
269 records.push_back(rr);
270 }
271
272 rr.qtype = QType::A;
273 for(char c='a'; c<= 'k';++c) {
274 gtld[0]=c;
275 rr.qname=DNSName(gtld);
276 rr.content="1.2.3.4";
277 records.push_back(rr);
278 }
279
280 rr.qname=DNSName("a.gtld-servers.net");
281 rr.qtype=QType::AAAA;
282 rr.content="2001:503:a83e::2:30";
283 records.push_back(rr);
284
285 rr.qname=DNSName("b.gtld-servers.net");
286 rr.qtype=QType::AAAA;
287 rr.content="2001:503:231d::2:30";
288 records.push_back(rr);
289
290
291 vector<uint8_t> packet;
292 DNSPacketWriter pw(packet, DNSName("www.google.com"), QType::A);
293 // shuffle(records);
294 for(const auto& rec : records) {
295 pw.startRecord(rec.qname, rec.qtype.getCode(), rec.ttl, 1, DNSResourceRecord::ADDITIONAL);
296 auto drc = DNSRecordContent::mastermake(rec.qtype.getCode(), 1, rec.content);
297 drc->toPacket(pw);
298 }
299
300 pw.commit();
301 return packet;
302 }
303
304
305
306 struct MakeARecordTestMM
307 {
308 string getName() const
309 {
310 return (boost::format("make a-record (mm)")).str();
311 }
312
313 void operator()() const
314 {
315 auto drc = DNSRecordContent::mastermake(QType::A, 1,
316 "1.2.3.4");
317 }
318 };
319
320
321 struct A2RecordTest
322 {
323 explicit A2RecordTest(int records) : d_records(records) {}
324
325 string getName() const
326 {
327 return (boost::format("%d a records") % d_records).str();
328 }
329
330 void operator()() const
331 {
332 vector<uint8_t> packet;
333 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::A);
334 ARecordContent arc("1.2.3.4");
335 DNSName name("outpost.ds9a.nl");
336 for(int records = 0; records < d_records; records++) {
337 pw.startRecord(name, QType::A);
338
339 arc.toPacket(pw);
340 }
341 pw.commit();
342 }
343 int d_records;
344 };
345
346
347 struct TXTRecordTest
348 {
349 explicit TXTRecordTest(int records) : d_records(records) {}
350
351 string getName() const
352 {
353 return (boost::format("%d TXT records") % d_records).str();
354 }
355
356 void operator()() const
357 {
358 vector<uint8_t> packet;
359 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::TXT);
360 for(int records = 0; records < d_records; records++) {
361 pw.startRecord(DNSName("outpost.ds9a.nl"), QType::TXT);
362 TXTRecordContent arc("\"een leuk verhaaltje in een TXT\"");
363 arc.toPacket(pw);
364 }
365 pw.commit();
366 }
367 int d_records;
368 };
369
370
371 struct GenericRecordTest
372 {
373 explicit GenericRecordTest(int records, uint16_t type, const std::string& content)
374 : d_records(records), d_type(type), d_content(content) {}
375
376 string getName() const
377 {
378 return (boost::format("%d %s records") % d_records %
379 DNSRecordContent::NumberToType(d_type)).str();
380 }
381
382 void operator()() const
383 {
384 vector<uint8_t> packet;
385 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), d_type);
386 for(int records = 0; records < d_records; records++) {
387 pw.startRecord(DNSName("outpost.ds9a.nl"), d_type);
388 auto drc = DNSRecordContent::mastermake(d_type, 1,
389 d_content);
390 drc->toPacket(pw);
391 }
392 pw.commit();
393 }
394 int d_records;
395 uint16_t d_type;
396 string d_content;
397 };
398
399
400 struct AAAARecordTest
401 {
402 explicit AAAARecordTest(int records) : d_records(records) {}
403
404 string getName() const
405 {
406 return (boost::format("%d aaaa records (mm)") % d_records).str();
407 }
408
409 void operator()() const
410 {
411 vector<uint8_t> packet;
412 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::AAAA);
413 for(int records = 0; records < d_records; records++) {
414 pw.startRecord(DNSName("outpost.ds9a.nl"), QType::AAAA);
415 auto drc = DNSRecordContent::mastermake(QType::AAAA, 1, "fe80::21d:92ff:fe6d:8441");
416 drc->toPacket(pw);
417 }
418 pw.commit();
419 }
420 int d_records;
421 };
422
423 struct SOARecordTest
424 {
425 explicit SOARecordTest(int records) : d_records(records) {}
426
427 string getName() const
428 {
429 return (boost::format("%d soa records (mm)") % d_records).str();
430 }
431
432 void operator()() const
433 {
434 vector<uint8_t> packet;
435 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::SOA);
436
437 for(int records = 0; records < d_records; records++) {
438 pw.startRecord(DNSName("outpost.ds9a.nl"), QType::SOA);
439 auto drc = DNSRecordContent::mastermake(QType::SOA, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400");
440 drc->toPacket(pw);
441 }
442 pw.commit();
443 }
444 int d_records;
445 };
446
447 vector<uint8_t> makeEmptyQuery()
448 {
449 vector<uint8_t> packet;
450 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::SOA);
451 return packet;
452 }
453
454 vector<uint8_t> makeTypicalReferral()
455 {
456 vector<uint8_t> packet;
457 DNSPacketWriter pw(packet, DNSName("outpost.ds9a.nl"), QType::A);
458
459 pw.startRecord(DNSName("ds9a.nl"), QType::NS, 3600, 1, DNSResourceRecord::AUTHORITY);
460 auto drc = DNSRecordContent::mastermake(QType::NS, 1, "ns1.ds9a.nl");
461 drc->toPacket(pw);
462
463 pw.startRecord(DNSName("ds9a.nl"), QType::NS, 3600, 1, DNSResourceRecord::AUTHORITY);
464 drc = DNSRecordContent::mastermake(QType::NS, 1, "ns2.ds9a.nl");
465 drc->toPacket(pw);
466
467
468 pw.startRecord(DNSName("ns1.ds9a.nl"), QType::A, 3600, 1, DNSResourceRecord::ADDITIONAL);
469 drc = DNSRecordContent::mastermake(QType::A, 1, "1.2.3.4");
470 drc->toPacket(pw);
471
472 pw.startRecord(DNSName("ns2.ds9a.nl"), QType::A, 3600, 1, DNSResourceRecord::ADDITIONAL);
473 drc = DNSRecordContent::mastermake(QType::A, 1, "4.3.2.1");
474 drc->toPacket(pw);
475
476 pw.commit();
477 return packet;
478 }
479
480 struct StackMallocTest
481 {
482 string getName() const
483 {
484 return "stack allocation";
485 }
486
487 void operator()() const
488 {
489 char *buffer= new char[200000];
490 delete[] buffer;
491 }
492
493 };
494
495
496 struct EmptyQueryTest
497 {
498 string getName() const
499 {
500 return "write empty query";
501 }
502
503 void operator()() const
504 {
505 vector<uint8_t> packet=makeEmptyQuery();
506 }
507
508 };
509
510 struct TypicalRefTest
511 {
512 string getName() const
513 {
514 return "write typical referral";
515 }
516
517 void operator()() const
518 {
519 vector<uint8_t> packet=makeTypicalReferral();
520 }
521
522 };
523
524 struct BigRefTest
525 {
526 string getName() const
527 {
528 return "write big referral";
529 }
530
531 void operator()() const
532 {
533 vector<uint8_t> packet=makeBigReferral();
534 }
535
536 };
537
538 struct BigDNSPacketRefTest
539 {
540 string getName() const
541 {
542 return "write big dnspacket referral";
543 }
544
545 void operator()() const
546 {
547 vector<uint8_t> packet=makeBigDNSPacketReferral();
548 }
549
550 };
551
552
553 struct TCacheComp
554 {
555 bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const
556 {
557 int cmp=strcasecmp(a.first.c_str(), b.first.c_str());
558 if(cmp < 0)
559 return true;
560 if(cmp > 0)
561 return false;
562
563 return a.second < b.second;
564 }
565 };
566
567 struct NegCacheEntry
568 {
569 DNSName d_name;
570 QType d_qtype;
571 DNSName d_qname;
572 uint32_t d_ttd;
573 };
574
575 struct timeval d_now;
576
577
578
579 struct ParsePacketTest
580 {
581 explicit ParsePacketTest(const vector<uint8_t>& packet, const std::string& name)
582 : d_packet(packet), d_name(name)
583 {}
584
585 string getName() const
586 {
587 return "parse '"+d_name+"'";
588 }
589
590 void operator()() const
591 {
592 #if 0
593 MOADNSParser mdp(false, (const char*)&*d_packet.begin(), d_packet.size());
594 typedef map<pair<DNSName, QType>, set<DNSResourceRecord>, TCacheComp > tcache_t;
595 tcache_t tcache;
596
597 struct {
598 vector<DNSResourceRecord> d_result;
599 bool d_aabit;
600 int d_rcode;
601 } lwr;
602 DNSResourceRecord rr;
603 for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {
604 DNSResourceRecord rr;
605 rr.qtype=i->first.d_type;
606 rr.qname=i->first.d_name;
607
608 rr.ttl=i->first.d_ttl;
609 rr.content=i->first.d_content->getZoneRepresentation(); // this should be the serialised form
610 lwr.d_result.push_back(rr);
611 }
612
613 #endif
614 }
615 const vector<uint8_t>& d_packet;
616 std::string d_name;
617 };
618
619 struct ParsePacketBareTest
620 {
621 explicit ParsePacketBareTest(const vector<uint8_t>& packet, const std::string& name)
622 : d_packet(packet), d_name(name)
623 {}
624
625 string getName() const
626 {
627 return "parse '"+d_name+"' bare";
628 }
629
630 void operator()() const
631 {
632 MOADNSParser mdp(false, (const char*)&*d_packet.begin(), d_packet.size());
633 }
634 const vector<uint8_t>& d_packet;
635 std::string d_name;
636 };
637
638
639 struct SimpleCompressTest
640 {
641 explicit SimpleCompressTest(const std::string& name)
642 : d_name(name)
643 {}
644
645 string getName() const
646 {
647 return "compress '"+d_name+"'";
648 }
649
650 void operator()() const
651 {
652 simpleCompress(d_name);
653 }
654 std::string d_name;
655 };
656
657 struct VectorExpandTest
658 {
659 string getName() const
660 {
661 return "vector expand";
662 }
663
664 void operator()() const
665 {
666 vector<uint8_t> d_record;
667 d_record.resize(12);
668
669 string out="\x03www\x04ds9a\x02nl";
670 string::size_type len = d_record.size();
671 d_record.resize(len + out.length());
672 memcpy(&d_record[len], out.c_str(), out.length());
673 }
674
675 };
676
677 struct DNSNameParseTest
678 {
679 string getName() const
680 {
681 return "DNSName parse";
682 }
683
684 void operator()() const
685 {
686 DNSName name("www.powerdns.com");
687 }
688
689 };
690
691 struct DNSNameRootTest
692 {
693 string getName() const
694 {
695 return "DNSName root";
696 }
697
698 void operator()() const
699 {
700 DNSName name(".");
701 }
702
703 };
704
705
706
707 struct IEqualsTest
708 {
709 string getName() const
710 {
711 return "iequals test";
712 }
713
714 void operator()() const
715 {
716 static string a("www.ds9a.nl"), b("www.lwn.net");
717 g_ret = boost::iequals(a, b);
718 }
719
720 };
721
722 struct MyIEqualsTest
723 {
724 string getName() const
725 {
726 return "pdns_iequals test";
727 }
728
729 void operator()() const
730 {
731 static string a("www.ds9a.nl"), b("www.lwn.net");
732 g_ret = pdns_iequals(a, b);
733 }
734
735 };
736
737
738 struct StrcasecmpTest
739 {
740 string getName() const
741 {
742 return "strcasecmp test";
743 }
744
745 void operator()() const
746 {
747 static string a("www.ds9a.nl"), b("www.lwn.net");
748 g_ret = strcasecmp(a.c_str(), b.c_str());
749 }
750 };
751
752
753 struct Base64EncodeTest
754 {
755 string getName() const
756 {
757 return "Bas64Encode test";
758 }
759
760 void operator()() const
761 {
762 static string a("dq4KydZjmcoQQ45VYBP2EDR8FqKaMul0eSHBt7Xx5F7A4HFtabXEzDLD01bnSiGK");
763 Base64Encode(a);
764 }
765 };
766
767
768 struct B64DecodeTest
769 {
770 string getName() const
771 {
772 return "B64Decode test";
773 }
774
775 void operator()() const
776 {
777 static string a("ZHE0S3lkWmptY29RUTQ1VllCUDJFRFI4RnFLYU11bDBlU0hCdDdYeDVGN0E0SEZ0YWJYRXpETEQwMWJuU2lHSw=="), b;
778 g_ret = B64Decode(a,b);
779 }
780 };
781
782
783 struct NOPTest
784 {
785 string getName() const
786 {
787 return "null test";
788 }
789
790 void operator()() const
791 {
792 }
793
794 };
795
796
797
798 int main(int argc, char** argv)
799 try
800 {
801 reportAllTypes();
802
803 doRun(NOPTest());
804
805 doRun(IEqualsTest());
806 doRun(MyIEqualsTest());
807 doRun(StrcasecmpTest());
808 doRun(Base64EncodeTest());
809 doRun(B64DecodeTest());
810
811 doRun(StackMallocTest());
812
813 doRun(EmptyQueryTest());
814 doRun(TypicalRefTest());
815 doRun(BigRefTest());
816 doRun(BigDNSPacketRefTest());
817
818 auto packet = makeEmptyQuery();
819 doRun(ParsePacketTest(packet, "empty-query"));
820
821 packet = makeTypicalReferral();
822 cerr<<"typical referral size: "<<packet.size()<<endl;
823 doRun(ParsePacketBareTest(packet, "typical-referral"));
824
825 doRun(ParsePacketTest(packet, "typical-referral"));
826
827 doRun(SimpleCompressTest("www.france.ds9a.nl"));
828
829
830 doRun(VectorExpandTest());
831
832 doRun(GetTimeTest());
833
834 doRun(GetLockUncontendedTest());
835 doRun(StaticMemberTest());
836
837 doRun(ARecordTest(1));
838 doRun(ARecordTest(2));
839 doRun(ARecordTest(4));
840 doRun(ARecordTest(64));
841
842 doRun(A2RecordTest(1));
843 doRun(A2RecordTest(2));
844 doRun(A2RecordTest(4));
845 doRun(A2RecordTest(64));
846
847 doRun(MakeStringFromCharStarTest());
848 doRun(MakeARecordTest());
849 doRun(MakeARecordTestMM());
850
851 doRun(AAAARecordTest(1));
852 doRun(AAAARecordTest(2));
853 doRun(AAAARecordTest(4));
854 doRun(AAAARecordTest(64));
855
856 doRun(TXTRecordTest(1));
857 doRun(TXTRecordTest(2));
858 doRun(TXTRecordTest(4));
859 doRun(TXTRecordTest(64));
860
861 doRun(GenericRecordTest(1, QType::NS, "powerdnssec1.ds9a.nl"));
862 doRun(GenericRecordTest(2, QType::NS, "powerdnssec1.ds9a.nl"));
863 doRun(GenericRecordTest(4, QType::NS, "powerdnssec1.ds9a.nl"));
864 doRun(GenericRecordTest(64, QType::NS, "powerdnssec1.ds9a.nl"));
865
866
867
868 doRun(SOARecordTest(1));
869 doRun(SOARecordTest(2));
870 doRun(SOARecordTest(4));
871 doRun(SOARecordTest(64));
872
873 doRun(StringtokTest());
874 doRun(VStringtokTest());
875 doRun(StringAppendTest());
876 doRun(BoostStringAppendTest());
877
878 doRun(DNSNameParseTest());
879 doRun(DNSNameRootTest());
880
881 cerr<<"Total runs: " << g_totalRuns<<endl;
882
883 }
884 catch(std::exception &e)
885 {
886 cerr<<"Fatal: "<<e.what()<<endl;
887 }
888