Permalink
Browse files

implement max-tot-msec wallclock time limit per query (needs docs)

  • Loading branch information...
1 parent 563c49e commit 9de3e0340fa066d4c59449e1643a1de8c343f8f2 @ahupowerdns ahupowerdns committed Jan 21, 2015
Showing with 13 additions and 5 deletions.
  1. +0 −1 pdns/lwres.cc
  2. +1 −0 pdns/lwres.hh
  3. +4 −1 pdns/pdns_recursor.cc
  4. +6 −2 pdns/syncres.cc
  5. +2 −1 pdns/syncres.hh
View
@@ -78,7 +78,6 @@ int asyncresolve(const ComboAddress& ip, const string& domain, int type, bool do
lwr->d_rcode = 0;
lwr->d_pingCorrect = false;
lwr->d_haveEDNS = false;
-
int ret;
DTime dt;
View
@@ -56,6 +56,7 @@ public:
class LWResult
{
public:
+ LWResult() : d_usec(0) {}
typedef vector<DNSResourceRecord> res_t;
vector<DNSResourceRecord> d_result;
@@ -737,7 +737,8 @@ void startDoResolve(void *p)
if(!g_quiet) {
L<<Logger::Error<<t_id<<" ["<<MT->getTid()<<"/"<<MT->numProcesses()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<<dc->d_mdp.d_qname<<"|"<<DNSRecordContent::NumberToType(dc->d_mdp.d_qtype);
L<<"': "<<ntohs(pw.getHeader()->ancount)<<" answers, "<<ntohs(pw.getHeader()->arcount)<<" additional, took "<<sr.d_outqueries<<" packets, "<<
- sr.d_throttledqueries<<" throttled, "<<sr.d_timeouts<<" timeouts, "<<sr.d_tcpoutqueries<<" tcp connections, rcode="<<res<<endl;
+ sr.d_totUsec/1000.0<<" ms, "<<
+ sr.d_throttledqueries<<" throttled, "<<sr.d_timeouts<<" timeouts, "<<sr.d_tcpoutqueries<<" tcp connections, rcode="<<res<<endl;
}
sr.d_outqueries ? t_RC->cacheMisses++ : t_RC->cacheHits++;
@@ -1975,6 +1976,7 @@ int serviceMain(int argc, char*argv[])
SyncRes::s_serverdownthrottletime=::arg().asNum("server-down-throttle-time");
SyncRes::s_serverID=::arg()["server-id"];
SyncRes::s_maxqperq=::arg().asNum("max-qperq");
+ SyncRes::s_maxtotusec=1000*::arg().asNum("max-total-msec");
if(SyncRes::s_serverID.empty()) {
char tmp[128];
gethostname(tmp, sizeof(tmp)-1);
@@ -2299,6 +2301,7 @@ int main(int argc, char **argv)
::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate")="1680";
::arg().set("minimum-ttl-override", "Set under adverse conditions, a minimum TTL")="0";
::arg().set("max-qperq", "Maximum outgoing queries per query")="50";
+ ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited")="5000";
::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.";
View
@@ -64,6 +64,7 @@ unsigned int SyncRes::s_minimumTTL;
bool SyncRes::s_doIPv6;
bool SyncRes::s_nopacketcache;
unsigned int SyncRes::s_maxqperq;
+unsigned int SyncRes::s_maxtotusec;
string SyncRes::s_serverID;
SyncRes::LogMode SyncRes::s_lm;
@@ -73,7 +74,7 @@ bool SyncRes::s_noEDNSPing;
bool SyncRes::s_noEDNS;
SyncRes::SyncRes(const struct timeval& now) : d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
- d_now(now),
+ d_totUsec(0), d_now(now),
d_cacheonly(false), d_nocache(false), d_doEDNS0(false), d_lm(s_lm)
{
@@ -939,6 +940,9 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
s_tcpoutqueries++; d_tcpoutqueries++;
}
+ if(s_maxtotusec && d_totUsec > s_maxtotusec)
+ throw ImmediateServFailException("Too much time waiting for "+qname+"|"+qtype.getName()+", timeouts: "+boost::lexical_cast<string>(d_timeouts) +", throttles: "+boost::lexical_cast<string>(d_throttledqueries) + ", "+lexical_cast<string>(d_totUsec/1000)+"msec");
+
if(d_pdl && d_pdl->preoutquery(*remoteIP, d_requestor, qname, qtype, lwr.d_result, resolveret)) {
LOG(prefix<<qname<<": query handled by Lua"<<endl);
}
@@ -949,7 +953,7 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
if(resolveret==-3)
throw ImmediateServFailException("Query killed by policy");
-
+ d_totUsec += lwr.d_usec;
if(resolveret != 1) {
if(resolveret==0) {
LOG(prefix<<qname<<": timeout resolving after "<<lwr.d_usec/1000.0<<"msec "<< (doTCP ? "over TCP" : "")<<endl);
View
@@ -299,13 +299,14 @@ public:
static unsigned int s_minimumTTL;
static bool s_doIPv6;
static unsigned int s_maxqperq;
+ static unsigned int s_maxtotusec;
unsigned int d_outqueries;
unsigned int d_tcpoutqueries;
unsigned int d_throttledqueries;
unsigned int d_timeouts;
unsigned int d_unreachables;
+ unsigned int d_totUsec;
ComboAddress d_requestor;
- // typedef map<string,NegCacheEntry> negcache_t;
typedef multi_index_container <
NegCacheEntry,

1 comment on commit 9de3e03

@paddg
Contributor
paddg commented on 9de3e03 Jan 22, 2015

I very often see such messages:

... because: Too much time waiting for ...|A, timeouts: 1, throttles: 0, 3430792msec

It seems dt.udiff() works sometimes not correct.

Please sign in to comment.