2 #include <boost/format.hpp>
3 #include <boost/container/string.hpp>
4 #include "dnsparser.hh"
7 #include "dnswriter.hh"
8 #include "dnsrecords.hh"
18 volatile bool g_ret
; // make sure the optimizer does not get too smart
22 void alarmHandler(int)
27 template<typename C
> void doRun(const C
& cmd
, int mseconds
=100)
30 it
.it_value
.tv_sec
=mseconds
/1000;
31 it
.it_value
.tv_usec
= 1000* (mseconds
%1000);
32 it
.it_interval
.tv_sec
=0;
33 it
.it_interval
.tv_usec
=0;
35 signal(SIGVTALRM
, alarmHandler
);
36 setitimer(ITIMER_VIRTUAL
, &it
, 0);
42 while(runs
++, !g_stop
) {
45 double delta
=dt
.ndiff()/1000000000.0;
46 boost::format
fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run");
48 cerr
<< (fmt
% cmd
.getName() % delta
% (runs
/delta
) % (delta
* 1000000.0/runs
)) << endl
;
54 explicit ARecordTest(int records
) : d_records(records
) {}
56 string
getName() const
58 return (boost::format("%d a records") % d_records
).str();
61 void operator()() const
63 vector
<uint8_t> packet
;
64 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::A
);
65 for(int records
= 0; records
< d_records
; records
++) {
66 pw
.startRecord(DNSName("outpost.ds9a.nl"), QType::A
);
67 ARecordContent
arc("1.2.3.4");
76 struct MakeStringFromCharStarTest
78 MakeStringFromCharStarTest() : d_size(0){}
79 string
getName() const
81 return (boost::format("make a std::string")).str();
84 void operator()() const
86 string
name("outpost.ds9a.nl");
87 d_size
+= name
.length();
96 string
getName() const
98 return "gettimeofday-test";
101 void operator()() const
104 gettimeofday(&tv
, 0);
108 pthread_mutex_t s_testlock
=PTHREAD_MUTEX_INITIALIZER
;
110 struct GetLockUncontendedTest
112 string
getName() const
114 return "getlock-uncontended-test";
117 void operator()() const
119 pthread_mutex_lock(&s_testlock
);
120 pthread_mutex_unlock(&s_testlock
);
125 struct StaticMemberTest
127 string
getName() const
129 return "static-member-test";
132 void operator()() const
134 static string
* s_ptr
;
136 s_ptr
= new string();
142 string
getName() const
147 void operator()() const
149 string
str("the quick brown fox jumped");
150 vector
<string
> parts
;
151 stringtok(parts
, str
);
155 struct VStringtokTest
157 string
getName() const
162 void operator()() const
164 string
str("the quick brown fox jumped");
165 vector
<pair
<unsigned int, unsigned> > parts
;
166 vstringtok(parts
, str
);
170 struct StringAppendTest
172 string
getName() const
174 return "stringappend";
177 void operator()() const
181 for(int n
=0; n
< 1000; ++n
)
188 struct BoostStringAppendTest
190 string
getName() const
192 return "booststringappend";
195 void operator()() const
197 boost::container::string str
;
199 for(int n
=0; n
< 1000; ++n
)
207 struct MakeARecordTest
209 string
getName() const
211 return (boost::format("make a-record")).str();
214 void operator()() const
216 static string
src("1.2.3.4");
217 ARecordContent
arc(src
);
218 //ARecordContent arc(0x01020304);
223 vector
<uint8_t> makeBigReferral()
226 vector
<uint8_t> packet
;
227 DNSPacketWriter
pw(packet
, DNSName("www.google.com"), QType::A
);
229 string gtld
="x.gtld-servers.net";
230 for(char c
='a'; c
<= 'm';++c
) {
231 pw
.startRecord(DNSName("com"), QType::NS
, 3600, 1, DNSResourceRecord::AUTHORITY
);
233 auto drc
= DNSRecordContent::mastermake(QType::NS
, 1, gtld
);
237 for(char c
='a'; c
<= 'k';++c
) {
239 pw
.startRecord(DNSName(gtld
), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
240 auto drc
= DNSRecordContent::mastermake(QType::A
, 1, "1.2.3.4");
245 pw
.startRecord(DNSName("a.gtld-servers.net"), QType::AAAA
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
246 auto aaaarc
= DNSRecordContent::mastermake(QType::AAAA
, 1, "2001:503:a83e::2:30");
247 aaaarc
->toPacket(pw
);
249 pw
.startRecord(DNSName("b.gtld-servers.net"), QType::AAAA
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
250 aaaarc
= DNSRecordContent::mastermake(QType::AAAA
, 1, "2001:503:231d::2:30");
251 aaaarc
->toPacket(pw
);
258 vector
<uint8_t> makeBigDNSPacketReferral()
260 vector
<DNSResourceRecord
> records
;
261 DNSResourceRecord rr
;
262 rr
.qtype
= QType::NS
;
264 rr
.qname
=DNSName("com");
266 string gtld
="x.gtld-servers.net";
267 for(char c
='a'; c
<= 'm';++c
) {
270 records
.push_back(rr
);
274 for(char c
='a'; c
<= 'k';++c
) {
276 rr
.qname
=DNSName(gtld
);
277 rr
.content
="1.2.3.4";
278 records
.push_back(rr
);
281 rr
.qname
=DNSName("a.gtld-servers.net");
282 rr
.qtype
=QType::AAAA
;
283 rr
.content
="2001:503:a83e::2:30";
284 records
.push_back(rr
);
286 rr
.qname
=DNSName("b.gtld-servers.net");
287 rr
.qtype
=QType::AAAA
;
288 rr
.content
="2001:503:231d::2:30";
289 records
.push_back(rr
);
292 vector
<uint8_t> packet
;
293 DNSPacketWriter
pw(packet
, DNSName("www.google.com"), QType::A
);
295 for(const auto& rec
: records
) {
296 pw
.startRecord(rec
.qname
, rec
.qtype
.getCode(), rec
.ttl
, 1, DNSResourceRecord::ADDITIONAL
);
297 auto drc
= DNSRecordContent::mastermake(rec
.qtype
.getCode(), 1, rec
.content
);
307 struct MakeARecordTestMM
309 string
getName() const
311 return (boost::format("make a-record (mm)")).str();
314 void operator()() const
316 auto drc
= DNSRecordContent::mastermake(QType::A
, 1,
324 explicit A2RecordTest(int records
) : d_records(records
) {}
326 string
getName() const
328 return (boost::format("%d a records") % d_records
).str();
331 void operator()() const
333 vector
<uint8_t> packet
;
334 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::A
);
335 ARecordContent
arc("1.2.3.4");
336 DNSName
name("outpost.ds9a.nl");
337 for(int records
= 0; records
< d_records
; records
++) {
338 pw
.startRecord(name
, QType::A
);
350 explicit TXTRecordTest(int records
) : d_records(records
) {}
352 string
getName() const
354 return (boost::format("%d TXT records") % d_records
).str();
357 void operator()() const
359 vector
<uint8_t> packet
;
360 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::TXT
);
361 for(int records
= 0; records
< d_records
; records
++) {
362 pw
.startRecord(DNSName("outpost.ds9a.nl"), QType::TXT
);
363 TXTRecordContent
arc("\"een leuk verhaaltje in een TXT\"");
372 struct GenericRecordTest
374 explicit GenericRecordTest(int records
, uint16_t type
, const std::string
& content
)
375 : d_records(records
), d_type(type
), d_content(content
) {}
377 string
getName() const
379 return (boost::format("%d %s records") % d_records
%
380 DNSRecordContent::NumberToType(d_type
)).str();
383 void operator()() const
385 vector
<uint8_t> packet
;
386 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), d_type
);
387 for(int records
= 0; records
< d_records
; records
++) {
388 pw
.startRecord(DNSName("outpost.ds9a.nl"), d_type
);
389 auto drc
= DNSRecordContent::mastermake(d_type
, 1,
401 struct AAAARecordTest
403 explicit AAAARecordTest(int records
) : d_records(records
) {}
405 string
getName() const
407 return (boost::format("%d aaaa records (mm)") % d_records
).str();
410 void operator()() const
412 vector
<uint8_t> packet
;
413 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::AAAA
);
414 for(int records
= 0; records
< d_records
; records
++) {
415 pw
.startRecord(DNSName("outpost.ds9a.nl"), QType::AAAA
);
416 auto drc
= DNSRecordContent::mastermake(QType::AAAA
, 1, "fe80::21d:92ff:fe6d:8441");
426 explicit SOARecordTest(int records
) : d_records(records
) {}
428 string
getName() const
430 return (boost::format("%d soa records (mm)") % d_records
).str();
433 void operator()() const
435 vector
<uint8_t> packet
;
436 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::SOA
);
438 for(int records
= 0; records
< d_records
; records
++) {
439 pw
.startRecord(DNSName("outpost.ds9a.nl"), QType::SOA
);
440 auto drc
= DNSRecordContent::mastermake(QType::SOA
, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400");
448 vector
<uint8_t> makeEmptyQuery()
450 vector
<uint8_t> packet
;
451 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::SOA
);
455 vector
<uint8_t> makeTypicalReferral()
457 vector
<uint8_t> packet
;
458 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::A
);
460 pw
.startRecord(DNSName("ds9a.nl"), QType::NS
, 3600, 1, DNSResourceRecord::AUTHORITY
);
461 auto drc
= DNSRecordContent::mastermake(QType::NS
, 1, "ns1.ds9a.nl");
464 pw
.startRecord(DNSName("ds9a.nl"), QType::NS
, 3600, 1, DNSResourceRecord::AUTHORITY
);
465 drc
= DNSRecordContent::mastermake(QType::NS
, 1, "ns2.ds9a.nl");
469 pw
.startRecord(DNSName("ns1.ds9a.nl"), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
470 drc
= DNSRecordContent::mastermake(QType::A
, 1, "1.2.3.4");
473 pw
.startRecord(DNSName("ns2.ds9a.nl"), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
474 drc
= DNSRecordContent::mastermake(QType::A
, 1, "4.3.2.1");
481 struct StackMallocTest
483 string
getName() const
485 return "stack allocation";
488 void operator()() const
490 char *buffer
= new char[200000];
497 struct EmptyQueryTest
499 string
getName() const
501 return "write empty query";
504 void operator()() const
506 vector
<uint8_t> packet
=makeEmptyQuery();
511 struct TypicalRefTest
513 string
getName() const
515 return "write typical referral";
518 void operator()() const
520 vector
<uint8_t> packet
=makeTypicalReferral();
527 string
getName() const
529 return "write big referral";
532 void operator()() const
534 vector
<uint8_t> packet
=makeBigReferral();
539 struct BigDNSPacketRefTest
541 string
getName() const
543 return "write big dnspacket referral";
546 void operator()() const
548 vector
<uint8_t> packet
=makeBigDNSPacketReferral();
556 bool operator()(const pair
<DNSName
, QType
>& a
, const pair
<DNSName
, QType
>& b
) const
558 if(a
.first
< b
.first
)
560 if(b
.first
< a
.first
)
563 return a
.second
< b
.second
;
575 struct timeval d_now
;
579 struct ParsePacketTest
581 explicit ParsePacketTest(const vector
<uint8_t>& packet
, const std::string
& name
)
582 : d_packet(packet
), d_name(name
)
585 string
getName() const
587 return "parse '"+d_name
+"'";
590 void operator()() const
592 MOADNSParser
mdp(false, (const char*)&*d_packet
.begin(), d_packet
.size());
593 typedef map
<pair
<DNSName
, QType
>, set
<DNSResourceRecord
>, TCacheComp
> tcache_t
;
597 vector
<DNSResourceRecord
> d_result
;
601 DNSResourceRecord rr
;
602 for(MOADNSParser::answers_t::const_iterator i
=mdp
.d_answers
.begin(); i
!=mdp
.d_answers
.end(); ++i
) {
603 DNSResourceRecord rr
;
604 rr
.qtype
=i
->first
.d_type
;
605 rr
.qname
=i
->first
.d_name
;
607 rr
.ttl
=i
->first
.d_ttl
;
608 rr
.content
=i
->first
.d_content
->getZoneRepresentation(); // this should be the serialised form
609 lwr
.d_result
.push_back(rr
);
614 const vector
<uint8_t>& d_packet
;
618 struct ParsePacketBareTest
620 explicit ParsePacketBareTest(const vector
<uint8_t>& packet
, const std::string
& name
)
621 : d_packet(packet
), d_name(name
)
624 string
getName() const
626 return "parse '"+d_name
+"' bare";
629 void operator()() const
631 MOADNSParser
mdp(false, (const char*)&*d_packet
.begin(), d_packet
.size());
633 const vector
<uint8_t>& d_packet
;
638 struct SimpleCompressTest
640 explicit SimpleCompressTest(const std::string
& name
)
644 string
getName() const
646 return "compress '"+d_name
+"'";
649 void operator()() const
651 simpleCompress(d_name
);
656 struct VectorExpandTest
658 string
getName() const
660 return "vector expand";
663 void operator()() const
665 vector
<uint8_t> d_record
;
668 string out
="\x03www\x04ds9a\x02nl";
669 string::size_type len
= d_record
.size();
670 d_record
.resize(len
+ out
.length());
671 memcpy(&d_record
[len
], out
.c_str(), out
.length());
676 struct DNSNameParseTest
678 string
getName() const
680 return "DNSName parse";
683 void operator()() const
685 DNSName
name("www.powerdns.com");
690 struct DNSNameRootTest
692 string
getName() const
694 return "DNSName root";
697 void operator()() const
708 string
getName() const
710 return "iequals test";
713 void operator()() const
715 static string
a("www.ds9a.nl"), b("www.lwn.net");
716 g_ret
= boost::iequals(a
, b
);
723 string
getName() const
725 return "pdns_iequals test";
728 void operator()() const
730 static string
a("www.ds9a.nl"), b("www.lwn.net");
731 g_ret
= pdns_iequals(a
, b
);
737 struct StrcasecmpTest
739 string
getName() const
741 return "strcasecmp test";
744 void operator()() const
746 static string
a("www.ds9a.nl"), b("www.lwn.net");
747 g_ret
= strcasecmp(a
.c_str(), b
.c_str());
752 struct Base64EncodeTest
754 string
getName() const
756 return "Bas64Encode test";
759 void operator()() const
761 static string
a("dq4KydZjmcoQQ45VYBP2EDR8FqKaMul0eSHBt7Xx5F7A4HFtabXEzDLD01bnSiGK");
769 string
getName() const
771 return "B64Decode test";
774 void operator()() const
776 static string
a("ZHE0S3lkWmptY29RUTQ1VllCUDJFRFI4RnFLYU11bDBlU0hCdDdYeDVGN0E0SEZ0YWJYRXpETEQwMWJuU2lHSw=="), b
;
777 g_ret
= B64Decode(a
,b
);
784 string
getName() const
789 void operator()() const
795 struct StatRingDNSNameQTypeToStringTest
797 explicit StatRingDNSNameQTypeToStringTest(const DNSName
&name
, const QType type
) : d_name(name
), d_type(type
) {}
799 string
getName() const { return "StatRing test with DNSName and QType to string"; }
801 void operator()() const {
802 S
.ringAccount("testring", d_name
.toLogString()+"/"+d_type
.getName());
809 struct StatRingDNSNameQTypeTest
811 explicit StatRingDNSNameQTypeTest(const DNSName
&name
, const QType type
) : d_name(name
), d_type(type
) {}
813 string
getName() const { return "StatRing test with DNSName and QType"; }
815 void operator()() const {
816 S
.ringAccount("testringdnsname", d_name
, d_type
);
824 struct NetmaskTreeTest
826 string
getName() const { return "NetmaskTreeTest"; }
828 void operator()() const {
829 Netmask
nm("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64");
830 NetmaskTree
<bool> tree
;
832 for (int i
= 0; i
< 100; i
++)
833 tree
.insert_or_assign(nm
, true);
837 int main(int argc
, char** argv
)
844 doRun(IEqualsTest());
845 doRun(MyIEqualsTest());
846 doRun(StrcasecmpTest());
847 doRun(Base64EncodeTest());
848 doRun(B64DecodeTest());
850 doRun(StackMallocTest());
852 doRun(EmptyQueryTest());
853 doRun(TypicalRefTest());
855 doRun(BigDNSPacketRefTest());
857 auto packet
= makeEmptyQuery();
858 doRun(ParsePacketTest(packet
, "empty-query"));
860 packet
= makeTypicalReferral();
861 cerr
<<"typical referral size: "<<packet
.size()<<endl
;
862 doRun(ParsePacketBareTest(packet
, "typical-referral"));
864 doRun(ParsePacketTest(packet
, "typical-referral"));
866 doRun(SimpleCompressTest("www.france.ds9a.nl"));
869 doRun(VectorExpandTest());
871 doRun(GetTimeTest());
873 doRun(GetLockUncontendedTest());
874 doRun(StaticMemberTest());
876 doRun(ARecordTest(1));
877 doRun(ARecordTest(2));
878 doRun(ARecordTest(4));
879 doRun(ARecordTest(64));
881 doRun(A2RecordTest(1));
882 doRun(A2RecordTest(2));
883 doRun(A2RecordTest(4));
884 doRun(A2RecordTest(64));
886 doRun(MakeStringFromCharStarTest());
887 doRun(MakeARecordTest());
888 doRun(MakeARecordTestMM());
890 doRun(AAAARecordTest(1));
891 doRun(AAAARecordTest(2));
892 doRun(AAAARecordTest(4));
893 doRun(AAAARecordTest(64));
895 doRun(TXTRecordTest(1));
896 doRun(TXTRecordTest(2));
897 doRun(TXTRecordTest(4));
898 doRun(TXTRecordTest(64));
900 doRun(GenericRecordTest(1, QType::NS
, "powerdnssec1.ds9a.nl"));
901 doRun(GenericRecordTest(2, QType::NS
, "powerdnssec1.ds9a.nl"));
902 doRun(GenericRecordTest(4, QType::NS
, "powerdnssec1.ds9a.nl"));
903 doRun(GenericRecordTest(64, QType::NS
, "powerdnssec1.ds9a.nl"));
907 doRun(SOARecordTest(1));
908 doRun(SOARecordTest(2));
909 doRun(SOARecordTest(4));
910 doRun(SOARecordTest(64));
912 doRun(StringtokTest());
913 doRun(VStringtokTest());
914 doRun(StringAppendTest());
915 doRun(BoostStringAppendTest());
917 doRun(DNSNameParseTest());
918 doRun(DNSNameRootTest());
920 doRun(NetmaskTreeTest());
925 S
.declareRing("testring", "Just some ring where we'll account things");
926 doRun(StatRingDNSNameQTypeToStringTest(DNSName("example.com"), QType(1)));
928 S
.declareDNSNameQTypeRing("testringdnsname", "Just some ring where we'll account things");
929 doRun(StatRingDNSNameQTypeTest(DNSName("example.com"), QType(1)));
932 cerr
<<"Total runs: " << g_totalRuns
<<endl
;
935 catch(std::exception
&e
)
937 cerr
<<"Fatal: "<<e
.what()<<endl
;