#include "sstuff.hh"
#include "dns_random.hh"
#include "dnsrecords.hh"
+#include "dnssecinfra.hh"
-
-vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr)
+vector<pair<vector<DNSRecord>, vector<DNSRecord> > > getIXFRDeltas(const ComboAddress& master, const DNSName& zone, const DNSRecord& oursr, const DNSName& tsigalgo, const DNSName& tsigname, const std::string& tsigsecret)
{
vector<pair<vector<DNSRecord>, vector<DNSRecord> > > ret;
vector<uint8_t> packet;
pw.getHeader()->qr=0;
pw.getHeader()->rd=0;
pw.getHeader()->id=dns_random(0xffff);
- pw.startRecord(zone, QType::SOA, 3600, QClass::IN, DNSResourceRecord::AUTHORITY);
+ pw.startRecord(zone, QType::SOA, 0, QClass::IN, DNSResourceRecord::AUTHORITY);
oursr.d_content->toPacket(pw);
+
pw.commit();
-
+ if(!tsigalgo.empty()) {
+ TSIGRecordContent trc;
+ trc.d_algoName = tsigalgo;
+ trc.d_time = time((time_t*)NULL);
+ trc.d_fudge = 300;
+ trc.d_origID=ntohs(pw.getHeader()->id);
+ trc.d_eRcode=0;
+ addTSIG(pw, &trc, tsigname, tsigsecret, "", false);
+ }
uint16_t len=htons(packet.size());
string msg((const char*)&len, 2);
msg.append((const char*)&packet[0], packet.size());
char reply[len];
readn2(s.getHandle(), reply, len);
MOADNSParser mdp(string(reply, len));
+ if(mdp.d_header.rcode)
+ throw std::runtime_error("Got an error trying to IXFR zone '"+zone.toString()+"' from master '"+master.toStringWithPort()+"': "+RCode::to_s(mdp.d_header.rcode));
+
// cout<<"Got a response, rcode: "<<mdp.d_header.rcode<<", got "<<mdp.d_answers.size()<<" answers"<<endl;
for(auto& r: mdp.d_answers) {
+ if(r.first.d_type == QType::TSIG)
+ continue;
// cout<<r.first.d_name<< " " <<r.first.d_content->getZoneRepresentation()<<endl;
r.first.d_name = r.first.d_name.makeRelative(zone);
records.push_back(r.first);
using namespace boost::multi_index;
StatBag S;
-
ArgvMap &arg()
{
static ArgvMap theArg;
>
>records_t;
-uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr)
+uint32_t getSerialFromMaster(const ComboAddress& master, const DNSName& zone, shared_ptr<SOARecordContent>& sr, const DNSName& tsigalgo=DNSName(), const DNSName& tsigname=DNSName(), const std::string& tsigsecret="")
{
vector<uint8_t> packet;
DNSPacketWriter pw(packet, zone, QType::SOA);
+ if(!tsigalgo.empty()) {
+ TSIGRecordContent trc;
+ trc.d_algoName = tsigalgo;
+ trc.d_time = time((time_t*)NULL);
+ trc.d_fudge = 300;
+ trc.d_origID=ntohs(pw.getHeader()->id);
+ trc.d_eRcode=0;
+ addTSIG(pw, &trc, tsigname, tsigsecret, "", false);
+ }
Socket s(master.sin4.sin_family, SOCK_DGRAM);
s.connect(master);
string command;
if(argc < 5 || (command=argv[1], (command!="diff" && command !="track"))) {
cerr<<"Syntax: ixplore diff zone file1 file2"<<endl;
- cerr<<"Syntax: ixplore track IP-address port zone directory"<<endl;
+ cerr<<"Syntax: ixplore track IP-address port zone directory [tsigkey tsigalgo tsigsecret]"<<endl;
exit(EXIT_FAILURE);
}
if(command=="diff") {
-
records_t before, after;
DNSName zone(argv[2]);
cout<<"Loading before from "<<argv[3]<<endl;
cout<<"Loading zone, our highest available serial is "<< ourSerial<<endl;
+ DNSName tsigkey, tsigalgo;
+ if(argc > 6)
+ tsigkey=DNSName(toLower(argv[6]));
+ if(argc > 7)
+ tsigalgo=DNSName(toLower(argv[7]));
+ string tsigsecret;
+ if(argc > 8) {
+ if(B64Decode(argv[8], tsigsecret) < 0) {
+ cerr<<"Could not decode tsig secret!"<<endl;
+ exit(EXIT_FAILURE);
+ }
+ }
+
try {
if(!ourSerial)
throw std::runtime_error("There is no local zone available");
time_t last=0;
while(axfr.getChunk(nop, &chunk)) {
for(auto& dr : chunk) {
+ if(dr.d_type == QType::TSIG)
+ continue;
dr.d_name.makeUsRelative(zone);
records.insert(dr);
nrecords++;
cout<<"Checking for update, our serial number is "<<ourSerial<<".. ";
cout.flush();
shared_ptr<SOARecordContent> sr;
- uint32_t serial = getSerialFromMaster(master, zone, sr);
+ uint32_t serial = getSerialFromMaster(master, zone, sr, tsigalgo, tsigkey, tsigsecret);
if(ourSerial == serial) {
cout<<"still up to date, their serial is "<<serial<<", sleeping "<<sr->d_st.refresh<<" seconds"<<endl;
sleep(sr->d_st.refresh);
}
cout<<"got new serial: "<<serial<<", initiating IXFR!"<<endl;
- auto deltas = getIXFRDeltas(master, zone, ourSoa);
+ auto deltas = getIXFRDeltas(master, zone, ourSoa, tsigalgo, tsigkey, tsigsecret);
cout<<"Got "<<deltas.size()<<" deltas, applying.."<<endl;
for(const auto& delta : deltas) {