From: bert hubert Date: Sun, 22 Nov 2015 22:01:32 +0000 (+0100) Subject: make appendRawLabel() version that accepts raw pointers (and point the std::string... X-Git-Tag: dnsdist-1.0.0-alpha1~210^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e14febcf4cccb60cbf504297e02a40b70852f098;p=pdns make appendRawLabel() version that accepts raw pointers (and point the std::string version to it), do a smart reserve in the common packet parsing case. This reduces malloc calls/packet in dnsdist from 9/query to 3, only 1 of which comes from dnsname. --- diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index c69270db9..b95cf01e1 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -32,6 +32,12 @@ DNSName::DNSName(const char* p) DNSName::DNSName(const char* pos, int len, int offset, bool uncompress, uint16_t* qtype, uint16_t* qclass, unsigned int* consumed) { + if(!uncompress) { + if(const void * fnd=memchr(pos+offset, 0, len-offset)) { + d_storage.reserve(2+(const char*)fnd-(pos+offset)); + } + } + packetParser(pos, len, offset, uncompress, qtype, qclass, consumed); } @@ -65,7 +71,7 @@ void DNSName::packetParser(const char* qpos, int len, int offset, bool uncompres break; } if (pos + labellen < end) { - appendRawLabel(string((const char*)pos, labellen)); + appendRawLabel((const char*)pos, labellen); } else throw std::range_error("Found an invalid label length in qname"); @@ -176,20 +182,25 @@ DNSName DNSName::labelReverse() const void DNSName::appendRawLabel(const std::string& label) { - if(label.empty()) + appendRawLabel(label.c_str(), label.length()); +} + +void DNSName::appendRawLabel(const char* start, unsigned int length) +{ + if(length==0) throw std::range_error("no such thing as an empty label to append"); - if(label.size() > 63) + if(length > 63) throw std::range_error("label too long to append"); - if(d_storage.size() + label.size() > 254) // reserve two bytes, one for length and one for the root label + if(d_storage.size() + length > 254) // reserve two bytes, one for length and one for the root label throw std::range_error("name too long to append"); if(d_storage.empty()) { - d_storage.append(1, (char)label.size()); + d_storage.append(1, (char)length); } else { - *d_storage.rbegin()=(char)label.size(); + *d_storage.rbegin()=(char)length; } - d_storage.append(label.c_str(), label.length()); + d_storage.append(start, length); d_storage.append(1, (char)0); } diff --git a/pdns/dnsname.hh b/pdns/dnsname.hh index e77c10818..4691d16e5 100644 --- a/pdns/dnsname.hh +++ b/pdns/dnsname.hh @@ -42,6 +42,7 @@ public: std::string toStringNoDot() const { return toString(".", false); } std::string toDNSString() const; //!< Our representation in DNS native format void appendRawLabel(const std::string& str); //!< Append this unescaped label + void appendRawLabel(const char* start, unsigned int length); //!< Append this unescaped label void prependRawLabel(const std::string& str); //!< Prepend this unescaped label std::vector getRawLabels() const; //!< Individual raw unescaped labels bool chopOff(); //!< Turn www.powerdns.com. into powerdns.com., returns false for .