From 6ad8b29a4b1b2cf503d82c958fb150cc278bb1a2 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Tue, 28 Apr 2015 13:36:39 +0200 Subject: [PATCH] add truncateTC(), useful for fixing up PowerDNS 2.9.22's odd truncation behaviour. --- pdns/README-dnsdist.md | 2 ++ pdns/dnsdist-lua.cc | 1 + pdns/dnsdist.cc | 19 +++++++++++++++++++ pdns/dnsdist.hh | 5 +++-- pdns/dnsdistconf.lua | 1 + 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index d02758e79..e9d672451 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -513,6 +513,8 @@ Here are all functions: * `addQPSLimit({domain, domain}, n)`: limit queries within those domains (together) to n per second * `addQPSLimit(netmask, n)`: limit queries within that netmask to n per second * `addQPSLimit({netmask, netmask}, n)`: limit queries within those netmasks (together) to n per second + * Answer changing functions: + * `truncateTC(bool)`: if set (default) truncate TC=1 answers so they are actually empty. Fixes an issue for PowerDNS Authoritative Server 2.9.22. * Advanced functions for writing your own policies and hooks * ComboAddress related: * `tostring()`: return in human-friendly format diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index fd50c8944..6d1c162c5 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -235,6 +235,7 @@ vector> setupLua(bool client, const std::string& confi g_outputBuffer=g_policy.getLocal()->name+"\n"; }); + g_lua.writeFunction("truncateTC", [](bool tc) { g_truncateTC=tc; }); g_lua.registerMember("name", &ServerPolicy::name); g_lua.registerMember("policy", &ServerPolicy::policy); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 937454e9b..749eeee0b 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -104,6 +104,21 @@ Rings g_rings; GlobalStateHolder g_dstates; +bool g_truncateTC{1}; +void truncateTC(const char* packet, unsigned int* len) +try +{ + unsigned int consumed; + DNSName qname(packet, *len, 12, false, 0, 0, &consumed); + *len=consumed+12+4; + struct dnsheader* dh =(struct dnsheader*)packet; + dh->ancount = dh->arcount = dh->nscount=0; +} +catch(...) +{ + g_stats.truncFail++; +} + // listens on a dedicated socket, lobs answers from downstream servers to original requestors void* responderThread(std::shared_ptr state) { @@ -125,6 +140,10 @@ void* responderThread(std::shared_ptr state) else --state->outstanding; // you'd think an attacker could game this, but we're using connected socket + if(dh->tc && g_truncateTC) { + truncateTC(packet, (unsigned int*)&len); + } + dh->id = ids->origID; g_stats.responses++; if(ids->origDest.sin4.sin_family == 0) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index fda419485..4ad49cfae 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -12,7 +12,7 @@ struct DNSDistStats { - using stat_t=std::atomic; + using stat_t=std::atomic; // aww yiss ;-) stat_t responses{0}; stat_t servfailResponses{0}; stat_t queries{0}; @@ -23,6 +23,7 @@ struct DNSDistStats stat_t selfAnswered{0}; stat_t downstreamTimeouts{0}; stat_t downstreamSendErrors{0}; + stat_t truncFail{0}; double latency{0}; }; @@ -288,7 +289,7 @@ extern ComboAddress g_serverControl; // not changed during runtime extern std::vector g_locals; // not changed at runtime extern std::string g_key; // in theory needs locking - +extern bool g_truncateTC; struct dnsheader; void controlThread(int fd, ComboAddress local); diff --git a/pdns/dnsdistconf.lua b/pdns/dnsdistconf.lua index ba5043ca4..ca45a22cd 100644 --- a/pdns/dnsdistconf.lua +++ b/pdns/dnsdistconf.lua @@ -2,6 +2,7 @@ controlSocket("0.0.0.0") webserver("0.0.0.0:8083", "geheim2") addLocal("0.0.0.0:5200") setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=") +truncateTC(true) -- fix up possibly badly truncated answers from pdns 2.9.22 warnlog(string.format("Script starting %s", "up!")) -- 2.40.0