]> granicus.if.org Git - pdns/commitdiff
add truncateTC(), useful for fixing up PowerDNS 2.9.22's odd truncation behaviour.
authorbert hubert <bert.hubert@netherlabs.nl>
Tue, 28 Apr 2015 11:36:39 +0000 (13:36 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Tue, 28 Apr 2015 11:36:39 +0000 (13:36 +0200)
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistconf.lua

index d02758e795608227449899e70bdf3e8bb3c169df..e9d6724514b7a95dee7a26c6b3a3eba4bed440d8 100644 (file)
@@ -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
index fd50c8944c76a2372495645cb7d658847563390b..6d1c162c52e533b6e689813a1b4694b8d826cce3 100644 (file)
@@ -235,6 +235,7 @@ vector<std::function<void(void)>> 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);
index 937454e9be8d402bebd1fbd68a5baa636db22834..749eeee0b57e74d314850e4dd7140f28ece7a037 100644 (file)
@@ -104,6 +104,21 @@ Rings g_rings;
 
 GlobalStateHolder<servers_t> 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<DownstreamState> state)
 {
@@ -125,6 +140,10 @@ void* responderThread(std::shared_ptr<DownstreamState> 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)
index fda41948588bf32d1c4a21af89675dabeb02d2f5..4ad49cfae73a112f42010b54ee8632e00a6c3819 100644 (file)
@@ -12,7 +12,7 @@
 
 struct DNSDistStats
 {
-  using stat_t=std::atomic<uint64_t>;
+  using stat_t=std::atomic<uint64_t>; // 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<ComboAddress> 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);
index ba5043ca476b7f6f895547578133e83661b497c5..ca45a22cd5f03802bf037b31d024cf9d45f6b535 100644 (file)
@@ -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!"))