]> granicus.if.org Git - pdns/commitdiff
Add mastermake that understands QClass
authorRuben d'Arco <cyclops@prof-x.net>
Mon, 3 Dec 2012 05:44:54 +0000 (06:44 +0100)
committermind04 <mind04@monshouwer.org>
Fri, 12 Jul 2013 15:17:25 +0000 (17:17 +0200)
This is needed to parse the update packages correctly which do have
records in other QClasses then just 'IN'.
We don't need it always, only for specific classes, which this mastermake tries to filter

pdns/dnsparser.cc
pdns/dnsparser.hh

index 5a65f0b6162249ece44b1baeaa9c766358fa7f72..5554b97555786d9627ba13dc087428104dc67403 100644 (file)
@@ -170,6 +170,24 @@ DNSRecordContent* DNSRecordContent::mastermake(uint16_t qtype, uint16_t qclass,
   return i->second(content);
 }
 
+DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t oc) {
+  // For opcode UPDATE and where the DNSRecord is an answer record, we don't care about content, because this is
+  // not used within the prerequisite section of RFC2136, so - we can simply use unknownrecordcontent.
+  // For section 3.2.3, we do need content so we need to get it properly. But only for the correct Qclasses.
+  if (oc == Opcode::Update && dr.d_place == DNSRecord::Answer && dr.d_class != 1)
+    return new UnknownRecordContent(dr, pr);
+  
+  uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT
+
+  typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass, dr.d_type));
+  if(i==getTypemap().end() || !i->second) {
+    return new UnknownRecordContent(dr, pr);
+  }
+
+  return i->second(dr, pr);
+}
+
+
 DNSRecordContent::typemap_t& DNSRecordContent::getTypemap()
 {
   static DNSRecordContent::typemap_t typemap;
@@ -202,7 +220,7 @@ void MOADNSParser::init(const char *packet, unsigned int len)
   
   memcpy(&d_header, packet, sizeof(dnsheader));
 
-  if(d_header.opcode!=0 && d_header.opcode != 4) // notification
+  if(d_header.opcode != Opcode::Query && d_header.opcode != Opcode::Notify && d_header.opcode != Opcode::Update)
     throw MOADNSException("Can't parse non-query packet with opcode="+ lexical_cast<string>(d_header.opcode));
 
   d_header.qdcount=ntohs(d_header.qdcount);
@@ -253,7 +271,7 @@ void MOADNSParser::init(const char *packet, unsigned int len)
       dr.d_label=label;
       dr.d_clen=ah.d_clen;
 
-      dr.d_content=boost::shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(dr, pr));
+      dr.d_content=boost::shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(dr, pr, d_header.opcode));
       d_answers.push_back(make_pair(dr, pr.d_pos));
 
       if(dr.d_type == QType::TSIG && dr.d_class == 0xff) 
index 414c73e9810fbacc4975329a5c84fab97fb18ee5..22def5ee609c41d98bf23affd1fe0825b76f7afd 100644 (file)
@@ -151,6 +151,7 @@ class DNSRecordContent
 {
 public:
   static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr);
+  static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr, uint16_t opcode);
   static DNSRecordContent* mastermake(uint16_t qtype, uint16_t qclass, const string& zone);
 
   virtual std::string getZoneRepresentation() const = 0;