Skip to content

Commit

Permalink
Merge pull request #3443 from ahupowerdns/speedups
Browse files Browse the repository at this point in the history
Speedups! Closes some big impediments for performance & even correctness
  • Loading branch information
ahupowerdns committed Feb 24, 2016
2 parents d1bfadf + 5f15ee4 commit f4cccfd
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 28 deletions.
14 changes: 5 additions & 9 deletions pdns/iputils.hh
Expand Up @@ -95,6 +95,9 @@ union ComboAddress {

bool operator<(const ComboAddress& rhs) const
{
if(sin4.sin_family == 0) {
return false;
}
if(boost::tie(sin4.sin_family, sin4.sin_port) < boost::tie(rhs.sin4.sin_family, rhs.sin4.sin_port))
return true;
if(boost::tie(sin4.sin_family, sin4.sin_port) > boost::tie(rhs.sin4.sin_family, rhs.sin4.sin_port))
Expand All @@ -108,15 +111,7 @@ union ComboAddress {

bool operator>(const ComboAddress& rhs) const
{
if(boost::tie(sin4.sin_family, sin4.sin_port) > boost::tie(rhs.sin4.sin_family, rhs.sin4.sin_port))
return true;
if(boost::tie(sin4.sin_family, sin4.sin_port) < boost::tie(rhs.sin4.sin_family, rhs.sin4.sin_port))
return false;

if(sin4.sin_family == AF_INET)
return sin4.sin_addr.s_addr > rhs.sin4.sin_addr.s_addr;
else
return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6.sin6_addr.s6_addr, 16) > 0;
return rhs.operator<(*this);
}

struct addressOnlyHash
Expand Down Expand Up @@ -293,6 +288,7 @@ public:
Netmask()
{
d_network.sin4.sin_family=0; // disable this doing anything useful
d_network.sin4.sin_port = 0; // this guarantees d_network compares identical
d_mask=0;
d_bits=0;
}
Expand Down
23 changes: 20 additions & 3 deletions pdns/pdns_recursor.cc
Expand Up @@ -419,7 +419,7 @@ class UDPClientSocks
if(ret<0)
throw PDNSException("Making a socket for resolver (family = "+std::to_string(family)+"): "+stringerror());

setCloseOnExec(ret);
// setCloseOnExec(ret); // we're not going to exec

int tries=10;
ComboAddress sin;
Expand Down Expand Up @@ -1367,6 +1367,14 @@ void makeTCPServerSockets()
if( ::arg().mustDo("non-local-bind") )
Utility::setBindAny(AF_INET, fd);

#ifdef SO_REUSEPORT
if(::arg().mustDo("reuseport")) {
int one=1;
if(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0)
throw PDNSException("SO_REUSEPORT: "+stringerror());
}
#endif

sin.sin4.sin_port = htons(st.port);
int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6);
if (::bind(fd, (struct sockaddr *)&sin, socklen )<0)
Expand Down Expand Up @@ -1438,8 +1446,15 @@ void makeUDPServerSockets()
setSocketReceiveBuffer(fd, 250000);
sin.sin4.sin_port = htons(st.port);

int socklen=sin.getSocklen();


#ifdef SO_REUSEPORT
if(::arg().mustDo("reuseport")) {
int one=1;
if(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0)
throw PDNSException("SO_REUSEPORT: "+stringerror());
}
#endif
int socklen=sin.getSocklen();
if (::bind(fd, (struct sockaddr *)&sin, socklen)<0)
throw PDNSException("Resolver binding to server socket on port "+ std::to_string(st.port) +" for "+ st.host+": "+stringerror());

Expand Down Expand Up @@ -2663,6 +2678,8 @@ int main(int argc, char **argv)

::arg().set("include-dir","Include *.conf files from this directory")="";
::arg().set("security-poll-suffix","Domain name from which to query security update notifications")="secpoll.powerdns.com.";

::arg().setSwitch("reuseport","Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address")="no";

::arg().setCmd("help","Provide a helpful message");
::arg().setCmd("version","Print version string");
Expand Down
2 changes: 1 addition & 1 deletion pdns/syncres.hh
Expand Up @@ -554,7 +554,7 @@ struct PacketIDBirthdayCompare: public std::binary_function<PacketID, PacketID,
if( tie(a.remote, ourSock, a.type) > tie(b.remote, bSock, b.type))
return false;

return pdns_ilexicographical_compare(a.domain.toString(), b.domain.toString()); // FIXME400
return a.domain < b.domain;
}
};
extern __thread MemRecursorCache* t_RC;
Expand Down
7 changes: 7 additions & 0 deletions pdns/test-dnsname_cc.cc
Expand Up @@ -430,6 +430,13 @@ BOOST_AUTO_TEST_CASE(test_compare_naive) {
BOOST_CHECK(DNSName("abc.com.") < DNSName("Zdf.com."));
}

BOOST_AUTO_TEST_CASE(test_compare_empty) {
DNSName a, b;
BOOST_CHECK(!(a<b));
BOOST_CHECK(!a.canonCompare(b));
}


BOOST_AUTO_TEST_CASE(test_compare_canonical) {
DNSName lower("bert.com."), higher("alpha.nl.");
BOOST_CHECK(lower.canonCompare(higher));
Expand Down
8 changes: 8 additions & 0 deletions pdns/test-iputils_hh.cc
Expand Up @@ -41,6 +41,14 @@ BOOST_AUTO_TEST_CASE(test_ComboAddress) {
BOOST_CHECK(a == b);
}

BOOST_AUTO_TEST_CASE(test_ComboAddressCompare) {
ComboAddress a, b;
memset(&a, 0, sizeof(a));
memset(&b, 0, sizeof(b));
BOOST_CHECK(!(a<b));
BOOST_CHECK(!(a>b));
}

BOOST_AUTO_TEST_CASE(test_ComboAddressTruncate) {
ComboAddress ca4("130.161.252.29");
ca4.truncate(24);
Expand Down
34 changes: 19 additions & 15 deletions pdns/zoneparser-tng.cc
Expand Up @@ -35,6 +35,8 @@
#include <deque>
#include <boost/algorithm/string.hpp>

static string g_INstr("IN");

ZoneParserTNG::ZoneParserTNG(const string& fname, const DNSName& zname, const string& reldir) : d_reldir(reldir),
d_zonename(zname), d_defaultttl(3600),
d_templatecounter(0), d_templatestop(0),
Expand Down Expand Up @@ -98,24 +100,24 @@ unsigned int ZoneParserTNG::makeTTLFromZone(const string& str)
return 0;

unsigned int val=pdns_stou(str);
char lc=toupper(str[str.length()-1]);
char lc=dns_tolower(str[str.length()-1]);
if(!isdigit(lc))
switch(lc) {
case 'S':
case 's':
break;
case 'M':
case 'm':
val*=60; // minutes, not months!
break;
case 'H':
case 'h':
val*=3600;
break;
case 'D':
case 'd':
val*=3600*24;
break;
case 'W':
case 'w':
val*=3600*24*7;
break;
case 'Y': // ? :-)
case 'y': // ? :-)
val*=3600*24*365;
break;

Expand Down Expand Up @@ -203,6 +205,8 @@ bool ZoneParserTNG::getTemplateLine()

void chopComment(string& line)
{
if(line.find(';')==string::npos)
return;
string::size_type pos, len = line.length();
bool inQuote=false;
for(pos = 0 ; pos < len; ++pos) {
Expand Down Expand Up @@ -272,7 +276,7 @@ bool ZoneParserTNG::get(DNSResourceRecord& rr, std::string* comment)
if(parts.empty())
goto retry;

if(parts[0].first != parts[0].second && makeString(d_line, parts[0])[0]==';') // line consisting of nothing but comments
if(parts[0].first != parts[0].second && d_line[parts[0].first]==';') // line consisting of nothing but comments
goto retry;

if(d_line[0]=='$') {
Expand Down Expand Up @@ -310,7 +314,7 @@ bool ZoneParserTNG::get(DNSResourceRecord& rr, std::string* comment)

bool prevqname=false;
string qname = makeString(d_line, parts[0]); // Don't use DNSName here!
if(isspace(d_line[0])) {
if(dns_isspace(d_line[0])) {
rr.qname=d_prevqname;
prevqname=true;
}else {
Expand Down Expand Up @@ -346,8 +350,8 @@ bool ZoneParserTNG::get(DNSResourceRecord& rr, std::string* comment)
}

// cout<<"Next part: '"<<nextpart<<"'"<<endl;
if(pdns_iequals(nextpart, "IN")) {

if(pdns_iequals(nextpart, g_INstr)) {
// cout<<"Ignoring 'IN'\n";
continue;
}
Expand Down Expand Up @@ -375,12 +379,12 @@ bool ZoneParserTNG::get(DNSResourceRecord& rr, std::string* comment)
if(!haveQTYPE)
throw exception("Malformed line "+getLineOfFile()+": '"+d_line+"'");

rr.content=d_line.substr(range.first);

// rr.content=d_line.substr(range.first);
rr.content.assign(d_line, range.first, string::npos);
chopComment(rr.content);
trim(rr.content);
trim_if(rr.content, is_any_of(" \r\n\x1a"));

if(equals(rr.content, "@"))
if(rr.content.size()==1 && rr.content[0]=='@')
rr.content=d_zonename.toString();

if(findAndElide(rr.content, '(')) { // have found a ( and elided it
Expand Down

0 comments on commit f4cccfd

Please sign in to comment.