2 #include <boost/format.hpp>
3 #include <boost/container/string.hpp>
4 #include "dnsparser.hh"
7 #include "dnswriter.hh"
8 #include "dnsrecords.hh"
17 volatile bool g_ret
; // make sure the optimizer does not get too smart
21 void alarmHandler(int)
26 template<typename C
> void doRun(const C
& cmd
, int mseconds
=100)
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;
34 signal(SIGVTALRM
, alarmHandler
);
35 setitimer(ITIMER_VIRTUAL
, &it
, 0);
41 while(runs
++, !g_stop
) {
44 double delta
=dt
.ndiff()/1000000000.0;
45 boost::format
fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run");
47 cerr
<< (fmt
% cmd
.getName() % delta
% (runs
/delta
) % (delta
* 1000000.0/runs
)) << endl
;
53 explicit ARecordTest(int records
) : d_records(records
) {}
55 string
getName() const
57 return (boost::format("%d a records") % d_records
).str();
60 void operator()() const
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");
75 struct MakeStringFromCharStarTest
77 MakeStringFromCharStarTest() : d_size(0){}
78 string
getName() const
80 return (boost::format("make a std::string")).str();
83 void operator()() const
85 string
name("outpost.ds9a.nl");
86 d_size
+= name
.length();
95 string
getName() const
97 return "gettimeofday-test";
100 void operator()() const
103 gettimeofday(&tv
, 0);
107 pthread_mutex_t s_testlock
=PTHREAD_MUTEX_INITIALIZER
;
109 struct GetLockUncontendedTest
111 string
getName() const
113 return "getlock-uncontended-test";
116 void operator()() const
118 pthread_mutex_lock(&s_testlock
);
119 pthread_mutex_unlock(&s_testlock
);
124 struct StaticMemberTest
126 string
getName() const
128 return "static-member-test";
131 void operator()() const
133 static string
* s_ptr
;
135 s_ptr
= new string();
141 string
getName() const
146 void operator()() const
148 string
str("the quick brown fox jumped");
149 vector
<string
> parts
;
150 stringtok(parts
, str
);
154 struct VStringtokTest
156 string
getName() const
161 void operator()() const
163 string
str("the quick brown fox jumped");
164 vector
<pair
<unsigned int, unsigned> > parts
;
165 vstringtok(parts
, str
);
169 struct StringAppendTest
171 string
getName() const
173 return "stringappend";
176 void operator()() const
180 for(int n
=0; n
< 1000; ++n
)
187 struct BoostStringAppendTest
189 string
getName() const
191 return "booststringappend";
194 void operator()() const
196 boost::container::string str
;
198 for(int n
=0; n
< 1000; ++n
)
206 struct MakeARecordTest
208 string
getName() const
210 return (boost::format("make a-record")).str();
213 void operator()() const
215 static string
src("1.2.3.4");
216 ARecordContent
arc(src
);
217 //ARecordContent arc(0x01020304);
222 vector
<uint8_t> makeBigReferral()
225 vector
<uint8_t> packet
;
226 DNSPacketWriter
pw(packet
, DNSName("www.google.com"), QType::A
);
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
);
232 auto drc
= DNSRecordContent::mastermake(QType::NS
, 1, gtld
);
236 for(char c
='a'; c
<= 'k';++c
) {
238 pw
.startRecord(DNSName(gtld
), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
239 auto drc
= DNSRecordContent::mastermake(QType::A
, 1, "1.2.3.4");
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
);
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
);
257 vector
<uint8_t> makeBigDNSPacketReferral()
259 vector
<DNSResourceRecord
> records
;
260 DNSResourceRecord rr
;
261 rr
.qtype
= QType::NS
;
263 rr
.qname
=DNSName("com");
265 string gtld
="x.gtld-servers.net";
266 for(char c
='a'; c
<= 'm';++c
) {
269 records
.push_back(rr
);
273 for(char c
='a'; c
<= 'k';++c
) {
275 rr
.qname
=DNSName(gtld
);
276 rr
.content
="1.2.3.4";
277 records
.push_back(rr
);
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
);
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
);
291 vector
<uint8_t> packet
;
292 DNSPacketWriter
pw(packet
, DNSName("www.google.com"), QType::A
);
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
);
306 struct MakeARecordTestMM
308 string
getName() const
310 return (boost::format("make a-record (mm)")).str();
313 void operator()() const
315 auto drc
= DNSRecordContent::mastermake(QType::A
, 1,
323 explicit A2RecordTest(int records
) : d_records(records
) {}
325 string
getName() const
327 return (boost::format("%d a records") % d_records
).str();
330 void operator()() const
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
);
349 explicit TXTRecordTest(int records
) : d_records(records
) {}
351 string
getName() const
353 return (boost::format("%d TXT records") % d_records
).str();
356 void operator()() const
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\"");
371 struct GenericRecordTest
373 explicit GenericRecordTest(int records
, uint16_t type
, const std::string
& content
)
374 : d_records(records
), d_type(type
), d_content(content
) {}
376 string
getName() const
378 return (boost::format("%d %s records") % d_records
%
379 DNSRecordContent::NumberToType(d_type
)).str();
382 void operator()() const
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,
400 struct AAAARecordTest
402 explicit AAAARecordTest(int records
) : d_records(records
) {}
404 string
getName() const
406 return (boost::format("%d aaaa records (mm)") % d_records
).str();
409 void operator()() const
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");
425 explicit SOARecordTest(int records
) : d_records(records
) {}
427 string
getName() const
429 return (boost::format("%d soa records (mm)") % d_records
).str();
432 void operator()() const
434 vector
<uint8_t> packet
;
435 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::SOA
);
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");
447 vector
<uint8_t> makeEmptyQuery()
449 vector
<uint8_t> packet
;
450 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::SOA
);
454 vector
<uint8_t> makeTypicalReferral()
456 vector
<uint8_t> packet
;
457 DNSPacketWriter
pw(packet
, DNSName("outpost.ds9a.nl"), QType::A
);
459 pw
.startRecord(DNSName("ds9a.nl"), QType::NS
, 3600, 1, DNSResourceRecord::AUTHORITY
);
460 auto drc
= DNSRecordContent::mastermake(QType::NS
, 1, "ns1.ds9a.nl");
463 pw
.startRecord(DNSName("ds9a.nl"), QType::NS
, 3600, 1, DNSResourceRecord::AUTHORITY
);
464 drc
= DNSRecordContent::mastermake(QType::NS
, 1, "ns2.ds9a.nl");
468 pw
.startRecord(DNSName("ns1.ds9a.nl"), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
469 drc
= DNSRecordContent::mastermake(QType::A
, 1, "1.2.3.4");
472 pw
.startRecord(DNSName("ns2.ds9a.nl"), QType::A
, 3600, 1, DNSResourceRecord::ADDITIONAL
);
473 drc
= DNSRecordContent::mastermake(QType::A
, 1, "4.3.2.1");
480 struct StackMallocTest
482 string
getName() const
484 return "stack allocation";
487 void operator()() const
489 char *buffer
= new char[200000];
496 struct EmptyQueryTest
498 string
getName() const
500 return "write empty query";
503 void operator()() const
505 vector
<uint8_t> packet
=makeEmptyQuery();
510 struct TypicalRefTest
512 string
getName() const
514 return "write typical referral";
517 void operator()() const
519 vector
<uint8_t> packet
=makeTypicalReferral();
526 string
getName() const
528 return "write big referral";
531 void operator()() const
533 vector
<uint8_t> packet
=makeBigReferral();
538 struct BigDNSPacketRefTest
540 string
getName() const
542 return "write big dnspacket referral";
545 void operator()() const
547 vector
<uint8_t> packet
=makeBigDNSPacketReferral();
555 bool operator()(const pair
<DNSName
, QType
>& a
, const pair
<DNSName
, QType
>& b
) const
557 if(a
.first
< b
.first
)
559 if(b
.first
< a
.first
)
562 return a
.second
< b
.second
;
574 struct timeval d_now
;
578 struct ParsePacketTest
580 explicit ParsePacketTest(const vector
<uint8_t>& packet
, const std::string
& name
)
581 : d_packet(packet
), d_name(name
)
584 string
getName() const
586 return "parse '"+d_name
+"'";
589 void operator()() const
591 MOADNSParser
mdp(false, (const char*)&*d_packet
.begin(), d_packet
.size());
592 typedef map
<pair
<DNSName
, QType
>, set
<DNSResourceRecord
>, TCacheComp
> tcache_t
;
596 vector
<DNSResourceRecord
> d_result
;
600 DNSResourceRecord rr
;
601 for(MOADNSParser::answers_t::const_iterator i
=mdp
.d_answers
.begin(); i
!=mdp
.d_answers
.end(); ++i
) {
602 DNSResourceRecord rr
;
603 rr
.qtype
=i
->first
.d_type
;
604 rr
.qname
=i
->first
.d_name
;
606 rr
.ttl
=i
->first
.d_ttl
;
607 rr
.content
=i
->first
.d_content
->getZoneRepresentation(); // this should be the serialised form
608 lwr
.d_result
.push_back(rr
);
613 const vector
<uint8_t>& d_packet
;
617 struct ParsePacketBareTest
619 explicit ParsePacketBareTest(const vector
<uint8_t>& packet
, const std::string
& name
)
620 : d_packet(packet
), d_name(name
)
623 string
getName() const
625 return "parse '"+d_name
+"' bare";
628 void operator()() const
630 MOADNSParser
mdp(false, (const char*)&*d_packet
.begin(), d_packet
.size());
632 const vector
<uint8_t>& d_packet
;
637 struct SimpleCompressTest
639 explicit SimpleCompressTest(const std::string
& name
)
643 string
getName() const
645 return "compress '"+d_name
+"'";
648 void operator()() const
650 simpleCompress(d_name
);
655 struct VectorExpandTest
657 string
getName() const
659 return "vector expand";
662 void operator()() const
664 vector
<uint8_t> d_record
;
667 string out
="\x03www\x04ds9a\x02nl";
668 string::size_type len
= d_record
.size();
669 d_record
.resize(len
+ out
.length());
670 memcpy(&d_record
[len
], out
.c_str(), out
.length());
675 struct DNSNameParseTest
677 string
getName() const
679 return "DNSName parse";
682 void operator()() const
684 DNSName
name("www.powerdns.com");
689 struct DNSNameRootTest
691 string
getName() const
693 return "DNSName root";
696 void operator()() const
707 string
getName() const
709 return "iequals test";
712 void operator()() const
714 static string
a("www.ds9a.nl"), b("www.lwn.net");
715 g_ret
= boost::iequals(a
, b
);
722 string
getName() const
724 return "pdns_iequals test";
727 void operator()() const
729 static string
a("www.ds9a.nl"), b("www.lwn.net");
730 g_ret
= pdns_iequals(a
, b
);
736 struct StrcasecmpTest
738 string
getName() const
740 return "strcasecmp test";
743 void operator()() const
745 static string
a("www.ds9a.nl"), b("www.lwn.net");
746 g_ret
= strcasecmp(a
.c_str(), b
.c_str());
751 struct Base64EncodeTest
753 string
getName() const
755 return "Bas64Encode test";
758 void operator()() const
760 static string
a("dq4KydZjmcoQQ45VYBP2EDR8FqKaMul0eSHBt7Xx5F7A4HFtabXEzDLD01bnSiGK");
768 string
getName() const
770 return "B64Decode test";
773 void operator()() const
775 static string
a("ZHE0S3lkWmptY29RUTQ1VllCUDJFRFI4RnFLYU11bDBlU0hCdDdYeDVGN0E0SEZ0YWJYRXpETEQwMWJuU2lHSw=="), b
;
776 g_ret
= B64Decode(a
,b
);
783 string
getName() const
788 void operator()() const
794 struct StatRingDNSNameQTypeToStringTest
796 explicit StatRingDNSNameQTypeToStringTest(const DNSName
&name
, const QType type
) : d_name(name
), d_type(type
) {}
798 string
getName() const { return "StatRing test with DNSName and QType to string"; }
800 void operator()() const {
801 S
.ringAccount("testring", d_name
.toLogString()+"/"+d_type
.getName());
808 struct StatRingDNSNameQTypeTest
810 explicit StatRingDNSNameQTypeTest(const DNSName
&name
, const QType type
) : d_name(name
), d_type(type
) {}
812 string
getName() const { return "StatRing test with DNSName and QType"; }
814 void operator()() const {
815 S
.ringAccount("testringdnsname", d_name
, d_type
);
824 int main(int argc
, char** argv
)
831 doRun(IEqualsTest());
832 doRun(MyIEqualsTest());
833 doRun(StrcasecmpTest());
834 doRun(Base64EncodeTest());
835 doRun(B64DecodeTest());
837 doRun(StackMallocTest());
839 doRun(EmptyQueryTest());
840 doRun(TypicalRefTest());
842 doRun(BigDNSPacketRefTest());
844 auto packet
= makeEmptyQuery();
845 doRun(ParsePacketTest(packet
, "empty-query"));
847 packet
= makeTypicalReferral();
848 cerr
<<"typical referral size: "<<packet
.size()<<endl
;
849 doRun(ParsePacketBareTest(packet
, "typical-referral"));
851 doRun(ParsePacketTest(packet
, "typical-referral"));
853 doRun(SimpleCompressTest("www.france.ds9a.nl"));
856 doRun(VectorExpandTest());
858 doRun(GetTimeTest());
860 doRun(GetLockUncontendedTest());
861 doRun(StaticMemberTest());
863 doRun(ARecordTest(1));
864 doRun(ARecordTest(2));
865 doRun(ARecordTest(4));
866 doRun(ARecordTest(64));
868 doRun(A2RecordTest(1));
869 doRun(A2RecordTest(2));
870 doRun(A2RecordTest(4));
871 doRun(A2RecordTest(64));
873 doRun(MakeStringFromCharStarTest());
874 doRun(MakeARecordTest());
875 doRun(MakeARecordTestMM());
877 doRun(AAAARecordTest(1));
878 doRun(AAAARecordTest(2));
879 doRun(AAAARecordTest(4));
880 doRun(AAAARecordTest(64));
882 doRun(TXTRecordTest(1));
883 doRun(TXTRecordTest(2));
884 doRun(TXTRecordTest(4));
885 doRun(TXTRecordTest(64));
887 doRun(GenericRecordTest(1, QType::NS
, "powerdnssec1.ds9a.nl"));
888 doRun(GenericRecordTest(2, QType::NS
, "powerdnssec1.ds9a.nl"));
889 doRun(GenericRecordTest(4, QType::NS
, "powerdnssec1.ds9a.nl"));
890 doRun(GenericRecordTest(64, QType::NS
, "powerdnssec1.ds9a.nl"));
894 doRun(SOARecordTest(1));
895 doRun(SOARecordTest(2));
896 doRun(SOARecordTest(4));
897 doRun(SOARecordTest(64));
899 doRun(StringtokTest());
900 doRun(VStringtokTest());
901 doRun(StringAppendTest());
902 doRun(BoostStringAppendTest());
904 doRun(DNSNameParseTest());
905 doRun(DNSNameRootTest());
910 S
.declareRing("testring", "Just some ring where we'll account things");
911 doRun(StatRingDNSNameQTypeToStringTest(DNSName("example.com"), QType(1)));
913 S
.declareDNSNameQTypeRing("testringdnsname", "Just some ring where we'll account things");
914 doRun(StatRingDNSNameQTypeTest(DNSName("example.com"), QType(1)));
917 cerr
<<"Total runs: " << g_totalRuns
<<endl
;
920 catch(std::exception
&e
)
922 cerr
<<"Fatal: "<<e
.what()<<endl
;