From: Remi Gacogne Date: Tue, 11 Oct 2016 14:03:39 +0000 (+0200) Subject: Don't parse spurious RRs in queries when we don't need them X-Git-Tag: rec-3.7.4^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c82b5d10efb8ec42f1c27954bd1fbf979112511;p=pdns Don't parse spurious RRs in queries when we don't need them --- diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index 7d69253dd..e745835d7 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -309,8 +309,8 @@ void *qthread(void *number) DNSDistributor *distributor = DNSDistributor::Create(::arg().asNum("distributor-threads", 1)); // the big dispatcher! int num = (int)(unsigned long)number; g_distributors[num] = distributor; - DNSPacket question; - DNSPacket cached; + DNSPacket question(true); + DNSPacket cached(false); AtomicCounter &numreceived=*S.getPointer("udp-queries"); AtomicCounter &numreceiveddo=*S.getPointer("udp-do-queries"); diff --git a/pdns/dnsbulktest.cc b/pdns/dnsbulktest.cc index 7673ee6cf..4fc61d06e 100644 --- a/pdns/dnsbulktest.cc +++ b/pdns/dnsbulktest.cc @@ -116,7 +116,7 @@ struct SendReceive } // parse packet, set 'id', fill out 'ip' - MOADNSParser mdp(string(buf, len)); + MOADNSParser mdp(false, string(buf, len)); if(!g_quiet) { cout<<"Reply to question for qname='"<rd || dh->qr) continue; - MOADNSParser mdp((const char*)pr.d_payload, pr.d_len); + MOADNSParser mdp(false, (const char*)pr.d_payload, pr.d_len); memcpy(&entry.ip, &pr.d_ip->ip_src, 4); entry.port = pr.d_udp->uh_sport; diff --git a/pdns/dnsgram.cc b/pdns/dnsgram.cc index 80eaedbde..d49399558 100644 --- a/pdns/dnsgram.cc +++ b/pdns/dnsgram.cc @@ -111,7 +111,7 @@ try ntohs(pr.d_udp->uh_dport)==53 || ntohs(pr.d_udp->uh_sport)==53) && pr.d_len > 12) { try { - MOADNSParser mdp((const char*)pr.d_payload, pr.d_len); + MOADNSParser mdp(false, (const char*)pr.d_payload, pr.d_len); if(lastreport.tv_sec == 0) { lastreport = pr.d_pheader.ts; diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index b1b06a97e..6285a821f 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -48,7 +48,7 @@ bool DNSPacket::s_doEDNSSubnetProcessing; uint16_t DNSPacket::s_udpTruncationThreshold; -DNSPacket::DNSPacket() +DNSPacket::DNSPacket(bool isQuery) { d_wrapped=false; d_compress=true; @@ -56,6 +56,7 @@ DNSPacket::DNSPacket() d_wantsnsid=false; d_haveednssubnet = false; d_dnssecOk=false; + d_isQuery = isQuery; } const string& DNSPacket::getString() @@ -109,6 +110,8 @@ DNSPacket::DNSPacket(const DNSPacket &orig) d_rawpacket=orig.d_rawpacket; d=orig.d; + + d_isQuery = orig.d_isQuery; } void DNSPacket::setRcode(int v) @@ -365,7 +368,7 @@ void DNSPacket::setQuestion(int op, const string &qd, int newqtype) /** convenience function for creating a reply packet from a question packet. Do not forget to delete it after use! */ DNSPacket *DNSPacket::replyPacket() const { - DNSPacket *r=new DNSPacket; + DNSPacket *r=new DNSPacket(false); r->setSocket(d_socket); r->d_anyLocal=d_anyLocal; r->setRemote(&d_remote); @@ -443,7 +446,7 @@ void DNSPacket::setTSIGDetails(const TSIGRecordContent& tr, const string& keynam bool DNSPacket::getTSIGDetails(TSIGRecordContent* trc, string* keyname, string* message) const { - MOADNSParser mdp(d_rawpacket); + MOADNSParser mdp(d_isQuery, d_rawpacket); if(!mdp.getTSIGPos()) return false; @@ -482,7 +485,7 @@ try return -1; } - MOADNSParser mdp(d_rawpacket); + MOADNSParser mdp(d_isQuery, d_rawpacket); EDNSOpts edo; // ANY OPTION WHICH *MIGHT* BE SET DOWN BELOW SHOULD BE CLEARED FIRST! diff --git a/pdns/dnspacket.hh b/pdns/dnspacket.hh index f6c2646d2..2acbe6b50 100644 --- a/pdns/dnspacket.hh +++ b/pdns/dnspacket.hh @@ -67,7 +67,7 @@ class DNSSECKeeper; class DNSPacket { public: - DNSPacket(); + DNSPacket(bool isQuery); DNSPacket(const DNSPacket &orig); int noparse(const char *mesg, int len); //!< just suck the data inward @@ -174,6 +174,7 @@ private: string d_tsigkeyname; string d_tsigprevious; bool d_tsigtimersonly; + bool d_isQuery; vector d_rrs; // 4 }; diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 999a0025d..7ecedac76 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -142,7 +142,7 @@ shared_ptr DNSRecordContent::unserialize(const string& qname, memcpy(&packet[pos], &drh, sizeof(drh)); pos+=sizeof(drh); memcpy(&packet[pos], serialized.c_str(), serialized.size()); pos+=(uint16_t)serialized.size(); - MOADNSParser mdp((char*)&*packet.begin(), (unsigned int)packet.size()); + MOADNSParser mdp(false, (char*)&*packet.begin(), (unsigned int)packet.size()); shared_ptr ret= mdp.d_answers.begin()->first.d_content; ret->header.d_type=ret->d_qtype; ret->label=mdp.d_answers.begin()->first.d_label; @@ -217,7 +217,7 @@ DNSRecordContent::zmakermap_t& DNSRecordContent::getZmakermap() return zmakermap; } -void MOADNSParser::init(const char *packet, unsigned int len) +void MOADNSParser::init(bool query, const char *packet, unsigned int len) { if(len < sizeof(dnsheader)) throw MOADNSException("Packet shorter than minimal header"); @@ -232,6 +232,9 @@ void MOADNSParser::init(const char *packet, unsigned int len) d_header.nscount=ntohs(d_header.nscount); d_header.arcount=ntohs(d_header.arcount); + if (query && (d_header.qdcount > 1)) + throw MOADNSException("Query with QD > 1 ("+lexical_cast(d_header.qdcount)+")"); + uint16_t contentlen=len-sizeof(dnsheader); d_content.resize(contentlen); @@ -275,7 +278,13 @@ 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::mastermake(dr, pr, d_header.opcode)); + if (query && (dr.d_place == DNSRecord::Answer || dr.d_place == DNSRecord::Nameserver || (dr.d_type != QType::OPT && dr.d_type != QType::TSIG && dr.d_type != QType::SIG) || ((dr.d_type == QType::TSIG || dr.d_type == QType::SIG) && dr.d_class != QClass::ANY))) { + dr.d_content=boost::shared_ptr(new UnknownRecordContent(dr, pr)); + } + else { + dr.d_content=boost::shared_ptr(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) diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 20436ecba..eb3eec530 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -306,15 +306,15 @@ class MOADNSParser : public boost::noncopyable { public: //! Parse from a string - MOADNSParser(const string& buffer) : d_tsigPos(0) + MOADNSParser(bool query, const string& buffer) : d_tsigPos(0) { - init(buffer.c_str(), (unsigned int)buffer.size()); + init(query, buffer.c_str(), (unsigned int)buffer.size()); } //! Parse from a pointer and length - MOADNSParser(const char *packet, unsigned int len) : d_tsigPos(0) + MOADNSParser(bool query, const char *packet, unsigned int len) : d_tsigPos(0) { - init(packet, len); + init(query, packet, len); } dnsheader d_header; @@ -340,7 +340,7 @@ public: } private: void getDnsrecordheader(struct dnsrecordheader &ah); - void init(const char *packet, unsigned int len); + void init(bool query, const char *packet, unsigned int len); vector d_content; uint16_t d_tsigPos; }; diff --git a/pdns/dnsproxy.cc b/pdns/dnsproxy.cc index dc324ce0b..5d4b44b9e 100644 --- a/pdns/dnsproxy.cc +++ b/pdns/dnsproxy.cc @@ -225,7 +225,7 @@ void DNSProxy::mainloop(void) d.id=i->second.id; memcpy(buffer,&d,sizeof(d)); // commit spoofed id - DNSPacket p,q; + DNSPacket p(false),q(false); p.parse(buffer,len); q.parse(buffer,len); @@ -240,7 +240,7 @@ void DNSProxy::mainloop(void) string reply; // needs to be alive at time of sendmsg! if(i->second.complete) { - MOADNSParser mdp(p.getString()); + MOADNSParser mdp(false, p.getString()); // cerr<<"Got completion, "<first.d_place-1<<" "<first.d_label<<" " << DNSRecordContent::NumberToType(j->first.d_type)<<" "<first.d_content->getZoneRepresentation()<recvFromAsync(packet, remote)) { try { s_weanswers++; - MOADNSParser mdp(packet.c_str(), packet.length()); + MOADNSParser mdp(false, packet.c_str(), packet.length()); if(!mdp.d_header.qr) { cout<<"Received a question from our reference nameserver!"<id=tmp; } - MOADNSParser mdp((const char*)pr.d_payload, pr.d_len); + MOADNSParser mdp(false, (const char*)pr.d_payload, pr.d_len); QuestionIdentifier qi=QuestionIdentifier::create(pr.getSource(), pr.getDest(), mdp); if(!mdp.d_header.qr) { diff --git a/pdns/dnsscan.cc b/pdns/dnsscan.cc index 8da65686d..a72bf67e7 100644 --- a/pdns/dnsscan.cc +++ b/pdns/dnsscan.cc @@ -47,7 +47,7 @@ try while(pr.getUDPPacket()) { try { - MOADNSParser mdp((const char*)pr.d_payload, pr.d_len); + MOADNSParser mdp(false, (const char*)pr.d_payload, pr.d_len); if(mdp.d_qtype < 256) counts[mdp.d_qtype]++; diff --git a/pdns/dnsscope.cc b/pdns/dnsscope.cc index 423a7f907..b475046ee 100644 --- a/pdns/dnsscope.cc +++ b/pdns/dnsscope.cc @@ -329,7 +329,7 @@ try continue; } } - MOADNSParser mdp((const char*)pr.d_payload, pr.d_len); + MOADNSParser mdp(false, (const char*)pr.d_payload, pr.d_len); if(haveRDFilter && mdp.d_header.rd != rdFilter) { rdFilterMismatch++; continue; diff --git a/pdns/dnstcpbench.cc b/pdns/dnstcpbench.cc index e7e5658ed..f120ab676 100644 --- a/pdns/dnstcpbench.cc +++ b/pdns/dnstcpbench.cc @@ -95,7 +95,7 @@ try q->udpUsec = makeUsec(now - tv); tv=now; - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); if(!mdp.d_header.tc) return; g_truncates++; @@ -145,7 +145,7 @@ try q->tcpUsec = makeUsec(now - tv); q->answerSecond = now.tv_sec; - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); // cout<<"Had correct TCP/IP response, "<getString()); + MOADNSParser mdp(false, p->getString()); if (mdp.d_header.qdcount != 1) { L<first.d_type == QType::SOA) { diff --git a/pdns/sdig.cc b/pdns/sdig.cc index e4e9e9c75..377c1d4bf 100644 --- a/pdns/sdig.cc +++ b/pdns/sdig.cc @@ -119,7 +119,7 @@ try sock.recvFrom(reply, dest); } - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); cout<<"Reply to question for qname='"<& re catch(...) { continue; } - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); if(mdp.d_header.rcode == RCode::ServFail) continue; diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 86cd06e2f..ad42b3742 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -516,7 +516,7 @@ struct ParsePacketTest void operator()() const { - MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); + MOADNSParser mdp(false, (const char*)&*d_packet.begin(), d_packet.size()); typedef map, set, TCacheComp > tcache_t; tcache_t tcache; @@ -679,7 +679,7 @@ struct ParsePacketBareTest void operator()() const { - MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); + MOADNSParser mdp(false, (const char*)&*d_packet.begin(), d_packet.size()); } const vector& d_packet; std::string d_name; diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 6356d343b..06dd72bf1 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -287,7 +287,7 @@ void *TCPNameserver::doConnection(void *data) getQuestion(fd, mesg.get(), pktlen, remote); S.inc("tcp-queries"); - packet=shared_ptr(new DNSPacket); + packet=shared_ptr(new DNSPacket(true)); packet->setRemote(&remote); packet->d_tcp=true; packet->setSocket(fd); @@ -307,7 +307,7 @@ void *TCPNameserver::doConnection(void *data) } shared_ptr reply; - shared_ptr cached= shared_ptr(new DNSPacket); + shared_ptr cached= shared_ptr(new DNSPacket(false)); if(logDNSQueries) { string remote; if(packet->hasEDNSSubnet()) @@ -950,7 +950,7 @@ int TCPNameserver::doIXFR(shared_ptr q, int outsock) } uint32_t serial = 0; - MOADNSParser mdp(q->getString()); + MOADNSParser mdp(false, q->getString()); for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i != mdp.d_answers.end(); ++i) { const DNSRecord *rr = &i->first; if (rr->d_type == QType::SOA && rr->d_place == DNSRecord::Nameserver) { diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc index 4250e3542..44c18d273 100644 --- a/pdns/test-dnsrecords_cc.cc +++ b/pdns/test-dnsrecords_cc.cc @@ -272,14 +272,15 @@ BOOST_AUTO_TEST_CASE(test_opt_record_in) { std::string packet("\xf0\x01\x01\x00\x00\x01\x00\x01\x00\x00\x00\x01\x03www\x08powerdns\x03""com\x00\x00\x01\x00\x01\x03www\x08powerdns\x03""com\x00\x00\x01\x00\x01\x00\x00\x00\x10\x00\x04\x7f\x00\x00\x01\x00\x00\x29\x05\x00\x00\x00\x00\x00\x00\x0c\x00\x03\x00\x08powerdns",89); OPTRecordContent::report(); - MOADNSParser mdp((char*)&*packet.begin(), (unsigned int)packet.size()); + MOADNSParser mdp(true, (char*)&*packet.begin(), (unsigned int)packet.size()); - getEDNSOpts(mdp, &eo); + BOOST_CHECK_EQUAL(getEDNSOpts(mdp, &eo), true); // this should contain NSID now BOOST_CHECK_EQUAL(eo.d_packetsize, 1280); // it should contain NSID option with value 'powerdns', and nothing else + BOOST_CHECK_EQUAL(eo.d_options.size(), 1); BOOST_CHECK_EQUAL(eo.d_options[0].first, 3); // nsid BOOST_CHECK_EQUAL(eo.d_options[0].second, "powerdns"); } diff --git a/pdns/test-packetcache_cc.cc b/pdns/test-packetcache_cc.cc index 9121014eb..f2d4985bd 100644 --- a/pdns/test-packetcache_cc.cc +++ b/pdns/test-packetcache_cc.cc @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(test_PacketCachePacket) { vector > opts; DNSPacketWriter pw(pak, "www.powerdns.com", QType::A); - DNSPacket q, r, r2; + DNSPacket q(true), r(false), r2(false); q.parse((char*)&pak[0], pak.size()); pak.clear(); diff --git a/pdns/tsig-tests.cc b/pdns/tsig-tests.cc index 34d85d314..108707485 100644 --- a/pdns/tsig-tests.cc +++ b/pdns/tsig-tests.cc @@ -62,7 +62,7 @@ try string reply; sock.recvFrom(reply, dest); - MOADNSParser mdp(reply); + MOADNSParser mdp(false, reply); cout<<"Reply to question for qname='"<& new makePtr(rr, &ptr); // verify that there's a zone for the PTR - DNSPacket fakePacket; + DNSPacket fakePacket(false); SOAData sd; fakePacket.qtype = QType::PTR; if (!B.getAuth(&fakePacket, &sd, ptr.qname, 0)) @@ -1046,7 +1046,7 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) { // now the PTRs BOOST_FOREACH(const DNSResourceRecord& rr, new_ptrs) { - DNSPacket fakePacket; + DNSPacket fakePacket(false); SOAData sd; sd.db = (DNSBackend *)-1; fakePacket.qtype = QType::PTR;