From: Pieter Lexis Date: Thu, 18 Jan 2018 12:44:00 +0000 (+0100) Subject: ixfrdist: add AXFR capability X-Git-Tag: dnsdist-1.3.0~111^2~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c16458b9c59ded889f51baff772c4a45fe35c72;p=thirdparty%2Fpdns.git ixfrdist: add AXFR capability --- diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 722f277018..887fb34ddc 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -224,6 +224,12 @@ bool checkQuery(const MOADNSParser& mdp, const ComboAddress& saddr, const bool u return true; } +/* + * Returns a vector that represents the full response to a SOA + * query. QNAME is read from mdp. + * + * TODO Maybe return void and modify the vector in-place? + */ vector makeSOAPacket(const MOADNSParser& mdp) { vector packet; DNSPacketWriter pw(packet, mdp.d_qname, mdp.d_qtype); @@ -238,6 +244,51 @@ vector makeSOAPacket(const MOADNSParser& mdp) { return packet; } +bool makeAXFRPacket(const MOADNSParser& mdp, vector& packet) { + DNSPacketWriter pw(packet, mdp.d_qname, mdp.d_qtype); + pw.getHeader()->id = mdp.d_header.id; + pw.getHeader()->rd = mdp.d_header.rd; + pw.getHeader()->qr = 1; + + string dir = g_workdir + "/" + mdp.d_qname.toString(); + auto serial = getSerialsFromDir(dir); + string fname = dir + "/" + std::to_string(serial); + // Use the SOA from the file, the one in g_soas _may_ have changed + shared_ptr soa; + loadSOAFromDisk(mdp.d_qname, fname, soa); + if (soa == nullptr) { + // :( + cerr<<"[WARNING] Could not retrieve SOA record from "<toPacket(pw); + pw.commit(); + + for (auto const &record : records) { + if (record.d_type == QType::SOA) { + continue; + } + pw.startRecord(record.d_name + mdp.d_qname, record.d_type); + record.d_content->toPacket(pw); + } + pw.commit(); + + // Add the final SOA + pw.startRecord(mdp.d_qname, QType::SOA); + soa->toPacket(pw); + pw.commit(); + + return true; +} void handleUDPRequest(int fd, boost::any&) { // TODO make the buffer-size configurable @@ -334,6 +385,13 @@ void handleTCPRequest(int fd, boost::any&) { packet = makeSOAPacket(mdp); } + if (mdp.d_qtype == QType::AXFR) { + if (!makeAXFRPacket(mdp, packet)) { + close(cfd); + return; + } + } + char buf[2]; buf[0]=packet.size()/256; buf[1]=packet.size()%256;