]> granicus.if.org Git - pdns/commitdiff
Add setCD()/getCD(). Restore initial flags in the response (RD/CD for now).
authorRemi Gacogne <rgacogne-github@coredump.fr>
Wed, 18 Nov 2015 16:38:46 +0000 (17:38 +0100)
committerRemi Gacogne <rgacogne-github@coredump.fr>
Wed, 18 Nov 2015 16:38:46 +0000 (17:38 +0100)
pdns/README-dnsdist.md
pdns/dns.hh
pdns/dnsdist-lua.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist.cc
pdns/dnsdist.hh

index cd1db78484ab4ba340567234d6f0a0bf66590591..5a4a75c4143705597968c03170c91ce7f1445123 100644 (file)
@@ -640,6 +640,8 @@ Here are all functions:
      * member `setRD(bool)`: set recursion desired flag
      * member `setTC(bool)`: set truncation flag (TC)
      * member `setQR(bool)`: set Query Response flag (setQR(true) indicates an *answer* packet)
+     * member `getCD()`: get checking disabled flag
+     * member `setCD(bool)`: set checking disabled flag
    * NetmaskGroup related
      * nothing yet
    * QPSLimiter related:
index b013beb24b009ff234d867d69c8f66e80aabb770..9295b53638e0c439de17e9a4ecdbf0f5524673fb 100644 (file)
@@ -217,6 +217,18 @@ struct dnsheader {
         unsigned        arcount :16;    /* number of resource entries */
 };
 
+inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh)
+{
+  return (uint16_t*) (((char *) dh) + sizeof(uint16_t));
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define FLAGS_RD_OFFSET (8)
+#define FLAGS_CD_OFFSET (12)
+#elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+#define FLAGS_RD_OFFSET (0)
+#define FLAGS_CD_OFFSET (12)
+#endif
 
 #define L theL()
 extern time_t s_starttime;
index b1ddce0669c3402df7bdc0b2d00440b3024194bf..32c12f848341dec97bb4ac9fbf9783b5934b162f 100644 (file)
@@ -513,6 +513,14 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       return (bool)dh.rd;
     });
 
+  g_lua.registerFunction<void(dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) {
+      dh.cd=v;
+    });
+
+  g_lua.registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) {
+      return (bool)dh.cd;
+    });
+
 
   g_lua.registerFunction<void(dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) {
       dh.tc=v;
index 30287084bf8780d3ecb5e693b32fbfff42402278..a69c0ae72833f2aada20a8f19e1e614366666dc9 100644 (file)
@@ -134,6 +134,9 @@ void* tcpClientThread(int pipefd)
 
     uint16_t qlen, rlen;
     string pool; 
+    const uint16_t rdMask = 1 << FLAGS_RD_OFFSET;
+    const uint16_t cdMask = 1 << FLAGS_CD_OFFSET;
+    const uint16_t restoreFlagsMask = UINT16_MAX & ~(rdMask | cdMask);
 
     shared_ptr<DownstreamState> ds;
     if (!setNonBlocking(ci.fd))
@@ -150,6 +153,8 @@ void* tcpClientThread(int pipefd)
        DNSName qname(query, qlen, 12, false, &qtype);
        string ruleresult;
        struct dnsheader* dh =(dnsheader*)query;
+       const uint16_t * flags = getFlagsFromDNSHeader(dh);
+       uint16_t origFlags = *flags;
        
         if(blockFilter) {
          std::lock_guard<std::mutex> lock(g_luamutex);
@@ -260,7 +265,15 @@ void* tcpClientThread(int pipefd)
 
         char answerbuffer[rlen];
         readn2WithTimeout(dsock, answerbuffer, rlen, ds->tcpRecvTimeout);
-      
+        struct dnsheader* responseHeaders = (struct dnsheader*)answerbuffer;
+        uint16_t * responseFlags = getFlagsFromDNSHeader(responseHeaders);
+        /* clear the flags we are about to restore */
+        *responseFlags &= restoreFlagsMask;
+        /* only keep the flags we want to restore */
+        origFlags &= ~restoreFlagsMask;
+        /* set the saved flags as they were */
+        *responseFlags |= origFlags;
+
         if (putNonBlockingMsgLen(ci.fd, rlen, ds->tcpSendTimeout))
           writen2WithTimeout(ci.fd, answerbuffer, rlen, ds->tcpSendTimeout);
       }
index 9f5d60fe083dc588be1c053dcb4496a9e67148a3..5e2137743fbc14a22f58a075f85610dc8fb91c03 100644 (file)
@@ -143,6 +143,9 @@ DelayPipe<DelayedPacket> * g_delay = 0;
 void* responderThread(std::shared_ptr<DownstreamState> state)
 {
   char packet[4096];
+  const uint16_t rdMask = 1 << FLAGS_RD_OFFSET;
+  const uint16_t cdMask = 1 << FLAGS_CD_OFFSET;
+  const uint16_t restoreFlagsMask = UINT16_MAX & ~(rdMask | cdMask);
   
   struct dnsheader* dh = (struct dnsheader*)packet;
   int len;
@@ -164,6 +167,15 @@ void* responderThread(std::shared_ptr<DownstreamState> state)
       truncateTC(packet, (unsigned int*)&len);
     }
 
+    uint16_t * flags = getFlagsFromDNSHeader(dh);
+    uint16_t origFlags = ids->origFlags;
+    /* clear the flags we are about to restore */
+    *flags &= restoreFlagsMask;
+    /* only keep the flags we want to restore */
+    origFlags &= ~restoreFlagsMask;
+    /* set the saved flags as they were */
+    *flags |= origFlags;
+
     dh->id = ids->origID;
     g_stats.responses++;
 
@@ -426,6 +438,8 @@ try
       if(dh->qr)    // don't respond to responses
        continue;
       
+      const uint16_t * flags = getFlagsFromDNSHeader(dh);
+      const uint16_t origFlags = *flags;
       DNSName qname(packet, len, 12, false, &qtype);
       g_rings.queryRing.push_back(qname);
             
@@ -525,6 +539,7 @@ try
       ids->qtype = qtype;
       ids->origDest.sin4.sin_family=0;
       ids->delayMsec = delayMsec;
+      ids->origFlags = origFlags;
       HarvestDestinationAddress(&msgh, &ids->origDest);
       
       dh->id = idOffset;
index 871abbbef2f0e87cc3671137737b3bc5870fe370..d3450e1fb7e260bad3847a707fd51881ed603c61 100644 (file)
@@ -168,6 +168,7 @@ struct IDState
   std::atomic<uint16_t> age;                                  // 4
   uint16_t qtype;                                             // 2
   uint16_t origID;                                            // 2
+  uint16_t origFlags;                                         // 2
   int delayMsec;
 };