]> granicus.if.org Git - pdns/commitdiff
Add EDNS unknown version handling
authorAki Tuomi <cmouse@cmouse.fi>
Mon, 17 Aug 2015 18:10:33 +0000 (21:10 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Tue, 25 Aug 2015 15:01:09 +0000 (18:01 +0300)
pdns/dnspacket.cc
pdns/dnspacket.hh
pdns/packethandler.cc

index e5c90e0c36bcba42f6d9f27b16afc7c0b3df74fd..7a173c1241d2afafa5600e6d5d5a2ff3218e181d 100644 (file)
@@ -60,6 +60,8 @@ DNSPacket::DNSPacket()
   d_wantsnsid=false;
   d_haveednssubnet = false;
   d_dnssecOk=false;
+  d_ednsversion=0;
+  d_ednsrcode=0;
 }
 
 const string& DNSPacket::getString()
@@ -101,6 +103,8 @@ DNSPacket::DNSPacket(const DNSPacket &orig)
   d_eso = orig.d_eso;
   d_haveednssubnet = orig.d_haveednssubnet;
   d_haveednssection = orig.d_haveednssection;
+  d_ednsversion = orig.d_ednsversion;
+  d_ednsrcode = orig.d_ednsrcode;
   d_dnssecOk = orig.d_dnssecOk;
   d_rrs=orig.d_rrs;
   
@@ -341,7 +345,7 @@ void DNSPacket::wrapup()
 
       if(!opts.empty() || d_haveednssection || d_dnssecOk)
       {
-        pw.addOpt(s_udpTruncationThreshold, 0, d_dnssecOk ? EDNSOpts::DNSSECOK : 0, opts);
+        pw.addOpt(s_udpTruncationThreshold, d_ednsrcode, d_dnssecOk ? EDNSOpts::DNSSECOK : 0, opts);
         pw.commit();
       }
     }
@@ -403,7 +407,9 @@ DNSPacket *DNSPacket::replyPacket() const
   r->d_eso = d_eso;
   r->d_haveednssubnet = d_haveednssubnet;
   r->d_haveednssection = d_haveednssection;
+  r->d_ednsversion = 0;
+  r->d_ednsrcode = 0;
+
   if(d_tsigkeyname.countLabels()) {
     r->d_tsigkeyname = d_tsigkeyname;
     r->d_tsigprevious = d_tsigprevious;
@@ -554,6 +560,8 @@ try
         // cerr<<"Have an option #"<<iter->first<<": "<<makeHexDump(iter->second)<<endl;
       }
     }
+    d_ednsversion = edo.d_version;
+    d_ednsrcode = edo.d_extRCode;
   }
   else  {
     d_maxreplylen=512;
index b50f6ef74bdf2602b47426ec9be2e201a711da9b..15346f43f68c987c649c06cd39c133e59806e014 100644 (file)
@@ -131,6 +131,13 @@ public:
   bool couldBeCached(); //!< returns 0 if this query should bypass the packet cache
   bool hasEDNSSubnet();
   bool hasEDNS();
+  uint8_t getEDNSVersion() const { return d_ednsversion; };
+  void setEDNSRcode(uint16_t extRCode)
+  {
+    // WARNING: this is really 12 bits
+    d_ednsrcode=extRCode;
+  };
+  uint8_t getEDNSRCode() const { return d_ednsrcode; };
   //////// DATA !
 
   DNSName qdomain;  //!< qname of the question 4 - unsure how this is used
@@ -174,6 +181,9 @@ private:
   EDNSSubnetOpts d_eso;
 
   int d_maxreplylen;
+  uint8_t d_ednsversion;
+  // WARNING! This is really 12 bits
+  uint16_t d_ednsrcode;
   uint16_t d_qlen; // length of the question (including class & type) in this packet 2
 
   bool d_compress; // 1
index 027fcc8e004e05b37a9ba5cc8cca892e6c888555..744a5814925a6db1e12ce0a335c889f133ca1aeb 100644 (file)
@@ -1033,6 +1033,13 @@ DNSPacket *PacketHandler::questionOrRecurse(DNSPacket *p, bool *shouldRecurse)
     return 0;
   }
 
+  if (p->hasEDNS() && p->getEDNSVersion() > 0) {
+    r = p->replyPacket();
+    r->setRcode(16 & 0xF);
+    r->setEDNSRcode((16 & 0xFFF0)>>4); // set rcode to BADVERS
+    return r;
+  }
+
   if(p->d_havetsig) {
     DNSName keyname;
     string secret;