logger.cc statbag.cc dnspacket.cc arguments.cc lwres.cc pdns_recursor.cc lwres.hh \
mtasker.hh sillyrecords.cc syncres.hh recursor_cache.cc recursor_cache.hh dnsparser.cc \
dnswriter.cc dnswriter.hh dnsrecords.cc dnsrecords.hh rcpgenerator.cc rcpgenerator.hh \
-base64.cc base64.hh zoneparser-tng.cc zoneparser-tng.hh
+base64.cc base64.hh zoneparser-tng.cc zoneparser-tng.hh
#../modules/gmysqlbackend/smysql.cc
pdns_recursor_LDFLAGS=
pdns_recursor_LDADD=
-pdns_control_SOURCES=dynloader.cc dynmessenger.cc arguments.cc logger.cc statbag.cc misc.cc unix_utility.cc
+pdns_control_SOURCES=dynloader.cc dynmessenger.cc arguments.cc logger.cc statbag.cc \
+misc.cc unix_utility.cc qtype.cc
+
pdns_control_INCLUDES=path.hh
pdns_control_LDFLAGS=@THREADFLAGS@
uint32_t *i_p=(uint32_t *)piece5;
- uint32_t soaoffset;
+ uint32_t soaoffset=0;
if(soadata.serial && (soaoffset=arg().asNum("soa-serial-offset")))
if(soadata.serial<soaoffset)
soadata.serial+=soaoffset; // thank you DENIC
stable_sort(rrs.begin(),rrs.end(),rrcomp);
if(!d_tcp && !arg().mustDo("no-shuffle")) {
- // now shuffle! start out with the ANSWER records
- vector<DNSResourceRecord>::iterator first, second;
- for(first=rrs.begin();first!=rrs.end();++first)
- if(first->d_place==DNSResourceRecord::ANSWER && first->qtype.getCode() != QType::CNAME) // CNAME must come first
- break;
- for(second=first;second!=rrs.end();++second)
- if(second->d_place!=DNSResourceRecord::ANSWER)
- break;
-
- if(second-first>1)
- random_shuffle(first,second);
-
- // now shuffle the additional records
- for(first=second;first!=rrs.end();++first)
- if(first->d_place==DNSResourceRecord::ADDITIONAL && first->qtype.getCode() != QType::CNAME) // CNAME must come first
- break;
- for(second=first;second!=rrs.end();++second)
- if(second->d_place!=DNSResourceRecord::ADDITIONAL)
- break;
-
- if(second-first>1)
- random_shuffle(first,second);
+ shuffle(rrs);
}
d_wrapped=true;
}
+
+// shuffle, maintaining some semblance of order
+void shuffle(vector<DNSResourceRecord>& rrs)
+{
+ vector<DNSResourceRecord>::iterator first, second;
+ for(first=rrs.begin();first!=rrs.end();++first)
+ if(first->d_place==DNSResourceRecord::ANSWER && first->qtype.getCode() != QType::CNAME) // CNAME must come first
+ break;
+ for(second=first;second!=rrs.end();++second)
+ if(second->d_place!=DNSResourceRecord::ANSWER)
+ break;
+
+ if(second-first>1)
+ random_shuffle(first,second);
+
+ // now shuffle the additional records
+ for(first=second;first!=rrs.end();++first)
+ if(first->d_place==DNSResourceRecord::ADDITIONAL && first->qtype.getCode() != QType::CNAME) // CNAME must come first
+ break;
+ for(second=first;second!=rrs.end();++second)
+ if(second->d_place!=DNSResourceRecord::ADDITIONAL)
+ break;
+
+ if(second-first>1)
+ random_shuffle(first,second);
+
+ // we don't shuffle the rest
+}
#include "utility.hh"
-
+#include "dns.hh"
#ifndef WIN32
# include <sys/time.h>
# include <sys/types.h>
#include <stdexcept>
#include <string>
#include <ctype.h>
+#include <vector>
+
using namespace std;
bool chopOff(string &domain);
bool endsOn(const string &domain, const string &suffix);
}
string makeHexDump(const string& str);
-
+void shuffle(vector<DNSResourceRecord>& rrs);
#endif
RC.replace("", QType(QType::NS), nsset); // and stuff in the cache
}
+
void startDoResolve(void *p)
{
try {
else {
pw.getHeader()->rcode=res;
if(ret.size()) {
+ shuffle(ret);
for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) {
pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, 1, (DNSPacketWriter::Place)i->d_place);
shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), 1, i->content));