}
if(!strcmp(argv[1],"to")) {
printf("input: '%s'\noutput: '%s'\n",
- argv[2],
- toBase32Hex(argv[2]).c_str());
+ argv[2],
+ toBase32Hex(argv[2]).c_str());
}
else {
cout<<"input: '"<<argv[2]<<"'\noutput: '"<<fromBase32Hex(argv[2])<<"'\n";
Lock l(&d_lock);
if(d_suckdomains.empty())
continue;
-
+
sr=d_suckdomains.front();
d_suckdomains.pop_front();
}
}
bool DNSSECKeeper::getPreRRSIGs(DNSBackend& db, const std::string& signer, const std::string& qname,
- const std::string& wildcardname, const QType& qtype,
- DNSPacketWriter::Place signPlace, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL)
+ const std::string& wildcardname, const QType& qtype,
+ DNSPacketWriter::Place signPlace, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL)
{
// cerr<<"Doing DB lookup for precomputed RRSIGs for '"<<(wildcardname.empty() ? qname : wildcardname)<<"'"<<endl;
- SOAData sd;
- sd.db=(DNSBackend *)-1; // force uncached answer
- if(!db.getSOA(signer, sd)) {
- DLOG(L<<"Could not get SOA for domain"<<endl);
- return false;
- }
- db.lookup(QType(QType::RRSIG), wildcardname.empty() ? qname : wildcardname, NULL, sd.domain_id);
- DNSResourceRecord rr;
- while(db.get(rr)) {
- // cerr<<"Considering for '"<<qtype.getName()<<"' RRSIG '"<<rr.content<<"'\n";
- vector<string> parts;
- stringtok(parts, rr.content);
- if(parts[0] == qtype.getName() && pdns_iequals(parts[7], signer+".")) {
- // cerr<<"Got it"<<endl;
- if (!wildcardname.empty())
- rr.qname = qname;
- rr.d_place = (DNSResourceRecord::Place)signPlace;
- rr.ttl = signTTL;
- rrsigs.push_back(rr);
- }
- else ; // cerr<<"Skipping!"<<endl;
- }
- return true;
+ SOAData sd;
+ sd.db=(DNSBackend *)-1; // force uncached answer
+ if(!db.getSOA(signer, sd)) {
+ DLOG(L<<"Could not get SOA for domain"<<endl);
+ return false;
+ }
+ db.lookup(QType(QType::RRSIG), wildcardname.empty() ? qname : wildcardname, NULL, sd.domain_id);
+ DNSResourceRecord rr;
+ while(db.get(rr)) {
+ // cerr<<"Considering for '"<<qtype.getName()<<"' RRSIG '"<<rr.content<<"'\n";
+ vector<string> parts;
+ stringtok(parts, rr.content);
+ if(parts[0] == qtype.getName() && pdns_iequals(parts[7], signer+".")) {
+ // cerr<<"Got it"<<endl;
+ if (!wildcardname.empty())
+ rr.qname = qname;
+ rr.d_place = (DNSResourceRecord::Place)signPlace;
+ rr.ttl = signTTL;
+ rrsigs.push_back(rr);
+ }
+ else ; // cerr<<"Skipping!"<<endl;
+ }
+ return true;
}
bool DNSSECKeeper::TSIGGrantsAccess(const string& zone, const string& keyname, const string& algorithm)
}
void dm_add_option(struct dhcp_message *msg, u_int8_t option,
- u_int8_t length, void *opt) {
+ u_int8_t length, void *opt) {
u_int8_t *pos = msg->pos;
if (&msg->options[MAX_OPT_LEN] - pos < length + 2) abort();
#if 0
int dm_parse_msg_raw(char *dframe, int plen,
- struct in_addr *from_ip, struct dhcp_message *msg) {
+ struct in_addr *from_ip, struct dhcp_message *msg) {
struct iphdr *ip;
struct udphdr *udp;
int iphlen, udplen;
typedef accumulator_set<
double
, stats<boost::accumulators::tag::extended_p_square,
- boost::accumulators::tag::median(with_p_square_quantile),
+ boost::accumulators::tag::median(with_p_square_quantile),
boost::accumulators::tag::mean(immediate)
- >
+ >
> acc_t;
acc_t* d_acc;
entry.port = pr.d_udp->uh_sport;
entry.id=dh->id;
- // ecount[entry]++;
+ // ecount[entry]++;
string::size_type pos = 0;
for(pos = 0; pos < mdp.d_qname.size() ; ++pos ) {
char c=mdp.d_qname[pos] ;
}
catch(MOADNSException& mde) {
- // cerr<<"error parsing packet: "<<mde.what()<<endl;
+ // cerr<<"error parsing packet: "<<mde.what()<<endl;
continue;
}
catch(std::exception& e) {
uint16_t qlen, rlen;
try {
for(;;) {
- if(!getMsgLen(ci.fd, &qlen))
- break;
-
- ds->queries++;
- ds->outstanding++;
- char query[qlen];
- readn2(ci.fd, query, qlen);
- // FIXME: drop AXFR queries here, they confuse us
+ if(!getMsgLen(ci.fd, &qlen))
+ break;
+
+ ds->queries++;
+ ds->outstanding++;
+ char query[qlen];
+ readn2(ci.fd, query, qlen);
+ // FIXME: drop AXFR queries here, they confuse us
retry:;
- if(!putMsgLen(dsock, qlen)) {
- infolog("Downstream connection to %s died on us, getting a new one!", ds->remote.toStringWithPort());
- close(dsock);
- dsock=getTCPDownstream(&ds);
- goto retry;
- }
+ if(!putMsgLen(dsock, qlen)) {
+ infolog("Downstream connection to %s died on us, getting a new one!", ds->remote.toStringWithPort());
+ close(dsock);
+ dsock=getTCPDownstream(&ds);
+ goto retry;
+ }
- writen2(dsock, query, qlen);
+ writen2(dsock, query, qlen);
- if(!getMsgLen(dsock, &rlen)) {
- infolog("Downstream connection to %s died on us phase 2, getting a new one!", ds->remote.toStringWithPort());
- close(dsock);
- dsock=getTCPDownstream(&ds);
- goto retry;
- }
-
- char answerbuffer[rlen];
- readn2(dsock, answerbuffer, rlen);
+ if(!getMsgLen(dsock, &rlen)) {
+ infolog("Downstream connection to %s died on us phase 2, getting a new one!", ds->remote.toStringWithPort());
+ close(dsock);
+ dsock=getTCPDownstream(&ds);
+ goto retry;
+ }
+
+ char answerbuffer[rlen];
+ readn2(dsock, answerbuffer, rlen);
- putMsgLen(ci.fd, rlen);
- writen2(ci.fd, answerbuffer, rlen);
+ putMsgLen(ci.fd, rlen);
+ writen2(ci.fd, answerbuffer, rlen);
}
}
catch(...){}
prev[n].queries = dss.queries;
numQueries += dss.queries;
for(unsigned int i=0 ; i < g_maxOutstanding; ++i) {
- IDState& ids = dss.idStates[i];
- if(ids.origFD >=0 && ids.age++ > 2) {
- ids.age = AtomicCounter();
- ids.origFD = -1;
- dss.reuseds++;
- --dss.outstanding;
- }
+ IDState& ids = dss.idStates[i];
+ if(ids.origFD >=0 && ids.age++ > 2) {
+ ids.age = AtomicCounter();
+ ids.origFD = -1;
+ dss.reuseds++;
+ --dss.outstanding;
+ }
}
}
lastreport = pr.d_pheader.ts;
}
- // if(pr.d_pheader.ts.tv_sec > 1176897290 && pr.d_pheader.ts.tv_sec < 1176897310 )
- // pw.write();
+ // if(pr.d_pheader.ts.tv_sec > 1176897290 && pr.d_pheader.ts.tv_sec < 1176897310 )
+ // pw.write();
if(mdp.d_header.rd && !mdp.d_header.qr) {
g_lastquestionTime=pr.d_pheader.ts;
}
catch(MOADNSException& mde) {
- // cerr<<"error parsing packet: "<<mde.what()<<endl;
+ // cerr<<"error parsing packet: "<<mde.what()<<endl;
parseErrors++;
continue;
}
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2010 Netherlabs Computer Consulting BV
-
+ Copyright (C) 2010 Netherlabs Computer Consulting BV
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation
void DNSLabel::init(unsigned int len)
{
- d_capacity = len;
- d_storage = new char[d_capacity];
-
- d_fulllen = 0;
- d_offset = 0;
+ d_capacity = len;
+ d_storage = new char[d_capacity];
+
+ d_fulllen = 0;
+ d_offset = 0;
}
DNSLabel::DNSLabel(const DNSLabel& rhs)
{
- init();
- *this=rhs;
+ init();
+ *this=rhs;
}
DNSLabel::DNSLabel()
{
- init();
- appendChar(0); // "root"
+ init();
+ appendChar(0); // "root"
}
// FIXME: this should validate if 'raw' is a valid dns label!
DNSLabel::DNSLabel(const char*raw, unsigned int len)
{
- if(!validateStrict(raw, len))
- throw std::range_error("invalid raw label passed to DNSLabel");
- init(len);
- memcpy(d_storage, raw, len);
- d_fulllen = len;
+ if(!validateStrict(raw, len))
+ throw std::range_error("invalid raw label passed to DNSLabel");
+ init(len);
+ memcpy(d_storage, raw, len);
+ d_fulllen = len;
}
DNSLabel& DNSLabel::operator=(const DNSLabel& rhs)
{
- unsigned int newlen = rhs.getLength();
- if(newlen > d_capacity) {
- delete[] d_storage;
- d_storage = new char[newlen];
- }
- d_fulllen = newlen;
- d_offset=0;
- memcpy(d_storage, rhs.d_storage, d_fulllen);
-
- return *this;
+ unsigned int newlen = rhs.getLength();
+ if(newlen > d_capacity) {
+ delete[] d_storage;
+ d_storage = new char[newlen];
+ }
+ d_fulllen = newlen;
+ d_offset=0;
+ memcpy(d_storage, rhs.d_storage, d_fulllen);
+
+ return *this;
}
DNSLabel::~DNSLabel()
{
- delete[] d_storage;
+ delete[] d_storage;
}
DNSLabel::DNSLabel(const char* human)
{
- // FIXME: do the escaping thing
- init();
- const char* labelStart=human;
- const char* p;
- for(p=human; *p; ++p) {
- if(*p=='.') {
- char labelLen = p - labelStart;
- appendChar(labelLen);
- appendRange(labelStart, labelLen);
- labelStart=p+1;
- }
- }
- if(labelStart != p) { // human input did not end on a trailing dot
- char labelLen = p - labelStart;
- appendChar(labelLen);
- appendRange(labelStart, labelLen);
- }
- d_storage[d_fulllen++]=0;
+ // FIXME: do the escaping thing
+ init();
+ const char* labelStart=human;
+ const char* p;
+ for(p=human; *p; ++p) {
+ if(*p=='.') {
+ char labelLen = p - labelStart;
+ appendChar(labelLen);
+ appendRange(labelStart, labelLen);
+ labelStart=p+1;
+ }
+ }
+ if(labelStart != p) { // human input did not end on a trailing dot
+ char labelLen = p - labelStart;
+ appendChar(labelLen);
+ appendRange(labelStart, labelLen);
+ }
+ d_storage[d_fulllen++]=0;
}
bool DNSLabel::validateStrict(const char* raw, unsigned int len)
{
- int result = validateConsume(raw, len);
- if(result < 0 || (unsigned int)result != len)
- return false;
- return true;
+ int result = validateConsume(raw, len);
+ if(result < 0 || (unsigned int)result != len)
+ return false;
+ return true;
}
int DNSLabel::validateConsume(const char* raw, unsigned int maxLen)
{
- if(!maxLen)
- return -1; // shortest ok label is: '\x00'
+ if(!maxLen)
+ return -1; // shortest ok label is: '\x00'
- const unsigned char* p = (const unsigned char*) raw;
+ const unsigned char* p = (const unsigned char*) raw;
- for(;;) {
- if(p > (const unsigned char*)raw + maxLen) // beyond the end
- return -1;
-
- // cerr<<(int)*p<<endl;
- if(*p >= 0xc0 && p + 1 < (const unsigned char*)raw + maxLen) {
- // unsigned int offset=(*p & ~0xc0) * 0xff + *(p+1);
- ++p;
- // cerr<<"Wants to refer to offset "<<offset<<endl;
- return -1;
- }
- if(*p > 64) // label length too long, or a compression pointer
- return -1;
-
- if(!*p) { // final label, return bytes consumed
- return 1 + (p - (const unsigned char*)raw);
- }
-
- p += *p + 1;
- }
- return -1; // we should not get here, but if we do, it's bad
+ for(;;) {
+ if(p > (const unsigned char*)raw + maxLen) // beyond the end
+ return -1;
+
+ // cerr<<(int)*p<<endl;
+ if(*p >= 0xc0 && p + 1 < (const unsigned char*)raw + maxLen) {
+ // unsigned int offset=(*p & ~0xc0) * 0xff + *(p+1);
+ ++p;
+ // cerr<<"Wants to refer to offset "<<offset<<endl;
+ return -1;
+ }
+ if(*p > 64) // label length too long, or a compression pointer
+ return -1;
+
+ if(!*p) { // final label, return bytes consumed
+ return 1 + (p - (const unsigned char*)raw);
+ }
+
+ p += *p + 1;
+ }
+ return -1; // we should not get here, but if we do, it's bad
}
string DNSLabel::human() const
{
- // FIXME: do the escaping thing
- const char* p = getStart();
- char labelLen;
-
- if(!*p)
- return ".";
-
- string ret;
- for(;;) {
- labelLen = *p;
- // cerr<<"human, labelLen: "<<(int) labelLen<<endl;
- ++p;
- ret.append(p, (int)labelLen);
-
- if(!labelLen)
- break;
- ret.append(1, '.');
- p+=labelLen;
- }
-
- return ret;
+ // FIXME: do the escaping thing
+ const char* p = getStart();
+ char labelLen;
+
+ if(!*p)
+ return ".";
+
+ string ret;
+ for(;;) {
+ labelLen = *p;
+ // cerr<<"human, labelLen: "<<(int) labelLen<<endl;
+ ++p;
+ ret.append(p, (int)labelLen);
+
+ if(!labelLen)
+ break;
+ ret.append(1, '.');
+ p+=labelLen;
+ }
+
+ return ret;
}
bool DNSLabel::chopOff()
{
- char labelLen = *getStart();
- d_offset += labelLen+1;
- return labelLen;
+ char labelLen = *getStart();
+ d_offset += labelLen+1;
+ return labelLen;
}
bool DNSLabel::endsOn(const DNSLabel &rhs) const
{
- int longer = getLength() - rhs.getLength();
- if(longer < 0)
- return false;
- return !memcmp(getStart()+longer, rhs.getStart(),
- rhs.getLength());
+ int longer = getLength() - rhs.getLength();
+ if(longer < 0)
+ return false;
+ return !memcmp(getStart()+longer, rhs.getStart(),
+ rhs.getLength());
}
string DNSLabel::binary() const
{
- return std::string(getStart(), getLength());
+ return std::string(getStart(), getLength());
}
static unsigned int roundUpToNextPowerOfTwo(unsigned int x)
{
- x--;
+ x--;
x |= x >> 1; // handle 2 bit numbers
x |= x >> 2; // handle 4 bit numbers
x |= x >> 4; // handle 8 bit numbers
}
void DNSLabel::expandCapacity(unsigned int len)
{
- if(!len)
- d_capacity *= 2;
- else {
- d_capacity = roundUpToNextPowerOfTwo(d_capacity + len);
- }
- char *newStorage = new char[d_capacity];
- memcpy(newStorage, d_storage, d_fulllen);
- delete[] d_storage;
- d_storage=newStorage;
+ if(!len)
+ d_capacity *= 2;
+ else {
+ d_capacity = roundUpToNextPowerOfTwo(d_capacity + len);
+ }
+ char *newStorage = new char[d_capacity];
+ memcpy(newStorage, d_storage, d_fulllen);
+ delete[] d_storage;
+ d_storage=newStorage;
}
DNSLabel DNSLabel::createFromBuffer(const char* raw, unsigned int* len)
{
- int result = DNSLabel::validateConsume(raw, *len);
- if(result < 0)
- throw std::runtime_error("raw input to DNSLabel factory was invalid");
- *len = (unsigned int) result;
- return DNSLabel(raw, result);
+ int result = DNSLabel::validateConsume(raw, *len);
+ if(result < 0)
+ throw std::runtime_error("raw input to DNSLabel factory was invalid");
+ *len = (unsigned int) result;
+ return DNSLabel(raw, result);
}
void DNSLabel::chaseLabel(const char* raw, const char* beginPacket, unsigned int packetLength, unsigned int* len, bool updateLen)
{
- const unsigned char* p = (const unsigned char*) raw;
+ const unsigned char* p = (const unsigned char*) raw;
- for(;;) {
- if(p > (const unsigned char*)beginPacket + packetLength) // beyond the end
- throw std::range_error("label begins beyond end of packet");
-
- if(*p >= 0xc0 && p + 1 < (const unsigned char*)beginPacket + packetLength) {
- unsigned int offset=(*p & ~0xc0) * 256 + *(p+1);
- if(offset < 12)
- throw std::range_error("compression pointer to before beginning of content");
- offset -= 12;
- // cerr<<"new offset: "<<offset<<endl;
- if((const unsigned char*)beginPacket + offset >= p) {
- throw std::runtime_error("looping or forward compression pointer");
- }
-
- p+=2;
- if(updateLen) {
- *len = (p - (const unsigned char*)raw);
- }
-
- chaseLabel(beginPacket + offset, beginPacket, packetLength, len, false);
- return;
- }
- if(*p > 64) // label length too long, or a compression pointer
- throw std::range_error("label too long");
-
- if(!*p) { // final label, setbytes consumed
- appendChar(0);
- if(updateLen)
- *len = 1 + (p - (const unsigned char*)raw);
- return;
- }
- appendChar(*p);
- appendRange((const char*)p+1, *p);
- p += *p + 1;
- }
- // we should not get here, but if we do, it's bad
+ for(;;) {
+ if(p > (const unsigned char*)beginPacket + packetLength) // beyond the end
+ throw std::range_error("label begins beyond end of packet");
+
+ if(*p >= 0xc0 && p + 1 < (const unsigned char*)beginPacket + packetLength) {
+ unsigned int offset=(*p & ~0xc0) * 256 + *(p+1);
+ if(offset < 12)
+ throw std::range_error("compression pointer to before beginning of content");
+ offset -= 12;
+ // cerr<<"new offset: "<<offset<<endl;
+ if((const unsigned char*)beginPacket + offset >= p) {
+ throw std::runtime_error("looping or forward compression pointer");
+ }
+
+ p+=2;
+ if(updateLen) {
+ *len = (p - (const unsigned char*)raw);
+ }
+
+ chaseLabel(beginPacket + offset, beginPacket, packetLength, len, false);
+ return;
+ }
+ if(*p > 64) // label length too long, or a compression pointer
+ throw std::range_error("label too long");
+
+ if(!*p) { // final label, setbytes consumed
+ appendChar(0);
+ if(updateLen)
+ *len = 1 + (p - (const unsigned char*)raw);
+ return;
+ }
+ appendChar(*p);
+ appendRange((const char*)p+1, *p);
+ p += *p + 1;
+ }
+ // we should not get here, but if we do, it's bad
}
DNSLabel::DNSLabel(const char* raw, const char* beginPacket, unsigned int packetLength, unsigned int* len)
{
- init();
- if(!*len) {
- throw std::range_error("void label"); // shortest ok label is: '\x00'
- }
+ init();
+ if(!*len) {
+ throw std::range_error("void label"); // shortest ok label is: '\x00'
+ }
- chaseLabel(raw, beginPacket, packetLength, len, true);
+ chaseLabel(raw, beginPacket, packetLength, len, true);
}
#if 0
void endsOn(const DNSLabel& first, const DNSLabel& second)
{
- cerr<<"Does '"<<first.human()<<"' end on '"<<second.human()<<"': ";
- cerr<<first.endsOn(second)<<endl;
+ cerr<<"Does '"<<first.human()<<"' end on '"<<second.human()<<"': ";
+ cerr<<first.endsOn(second)<<endl;
}
string makeHexDump(const string& str)
}
int main()
-{
- DNSLabel label("www.powerdns.com"), suffix("powerdns.com"), root;
- endsOn(label, suffix);
-
- suffix=root;
- endsOn(label, suffix);
-
- suffix=DNSLabel("net");
- endsOn(label, suffix);
-
- while(label.chopOff()) {
- cerr<<label.human()<<endl;
- cerr<<endl;
- }
-
- DNSLabel label2("blah");
- label = label2;
-
-
- char rawLabel[]= "\003www\004ds9a\002nl";
- DNSLabel raw(rawLabel, sizeof(rawLabel));
- cerr<<"raw human: "<<raw.human()<<endl;
-
- char rawLabel2[]= "\003www\004ds9a\003nl";
- DNSLabel raw2(rawLabel2, sizeof(rawLabel2));
+{
+ DNSLabel label("www.powerdns.com"), suffix("powerdns.com"), root;
+ endsOn(label, suffix);
+
+ suffix=root;
+ endsOn(label, suffix);
+
+ suffix=DNSLabel("net");
+ endsOn(label, suffix);
+
+ while(label.chopOff()) {
+ cerr<<label.human()<<endl;
+ cerr<<endl;
+ }
+
+ DNSLabel label2("blah");
+ label = label2;
+
+
+ char rawLabel[]= "\003www\004ds9a\002nl";
+ DNSLabel raw(rawLabel, sizeof(rawLabel));
+ cerr<<"raw human: "<<raw.human()<<endl;
+
+ char rawLabel2[]= "\003www\004ds9a\003nl";
+ DNSLabel raw2(rawLabel2, sizeof(rawLabel2));
}
#endif
++i)
{
if(i->d_place!=DNSResourceRecord::ADDITIONAL)
- arrs.push_back(&*i);
+ arrs.push_back(&*i);
}
return arrs;
}
}
DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr,
- PacketReader& pr)
+ PacketReader& pr)
{
uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class is invalid for OPT
}
DNSRecordContent* DNSRecordContent::mastermake(uint16_t qtype, uint16_t qclass,
- const string& content)
+ const string& content)
{
zmakermap_t::const_iterator i=getZmakermap().find(make_pair(qclass, qtype));
if(i==getZmakermap().end()) {
#if 0
if(pr.d_pos!=contentlen) {
throw MOADNSException("Packet ("+d_qname+"|#"+lexical_cast<string>(d_qtype)+") has trailing garbage ("+ lexical_cast<string>(pr.d_pos) + " < " +
- lexical_cast<string>(contentlen) + ")");
+ lexical_cast<string>(contentlen) + ")");
}
#endif
}
}
else {
throw MOADNSException("Error parsing packet of "+lexical_cast<string>(len)+" bytes (rd="+
- lexical_cast<string>(d_header.rd)+
- "), out of bounds: "+string(re.what()));
+ lexical_cast<string>(d_header.rd)+
+ "), out of bounds: "+string(re.what()));
}
}
}
uint8_t len;
while((len=get8BitInt())) {
if(len >= 0xc0) { // extended label
- get8BitInt();
- return;
+ get8BitInt();
+ return;
}
skipBytes(len);
}
/* uint16_t dnsclass = */ dpm.get16BitInt();
if(dnstype == QType::OPT) // not aging that one with a stick
- break;
+ break;
dpm.decreaseAndSkip32BitInt(seconds);
dpm.skipRData();
boilerplate_conv(HINFO, ns_t_hinfo, conv.xfrText(d_cpu); conv.xfrText(d_host));
boilerplate_conv(RP, ns_t_rp,
- conv.xfrLabel(d_mbox);
- conv.xfrLabel(d_info)
- );
+ conv.xfrLabel(d_mbox);
+ conv.xfrLabel(d_info)
+ );
boilerplate_conv(OPT, ns_t_opt,
- conv.xfrBlob(d_data)
- );
+ conv.xfrBlob(d_data)
+ );
void OPTRecordContent::getData(vector<pair<uint16_t, string> >& options)
{
}
boilerplate_conv(TSIG, ns_t_tsig,
- conv.xfrLabel(d_algoName);
- conv.xfr48BitInt(d_time);
- conv.xfr16BitInt(d_fudge);
- uint16_t size=d_mac.size();
- conv.xfr16BitInt(size);
- conv.xfrBlob(d_mac, size);
- conv.xfr16BitInt(d_origID);
- conv.xfr16BitInt(d_eRcode);
- size=d_otherData.size();
- conv.xfr16BitInt(size);
- if (size>0) conv.xfrBlob(d_otherData, size);
- );
+ conv.xfrLabel(d_algoName);
+ conv.xfr48BitInt(d_time);
+ conv.xfr16BitInt(d_fudge);
+ uint16_t size=d_mac.size();
+ conv.xfr16BitInt(size);
+ conv.xfrBlob(d_mac, size);
+ conv.xfr16BitInt(d_origID);
+ conv.xfr16BitInt(d_eRcode);
+ size=d_otherData.size();
+ conv.xfr16BitInt(size);
+ if (size>0) conv.xfrBlob(d_otherData, size);
+ );
MXRecordContent::MXRecordContent(uint16_t preference, const string& mxname) : DNSRecordContent(ns_t_mx), d_preference(preference), d_mxname(mxname)
{
}
boilerplate_conv(MX, ns_t_mx,
- conv.xfr16BitInt(d_preference);
- conv.xfrLabel(d_mxname, true);
- )
+ conv.xfr16BitInt(d_preference);
+ conv.xfrLabel(d_mxname, true);
+ )
boilerplate_conv(KX, ns_t_kx,
- conv.xfr16BitInt(d_preference);
- conv.xfrLabel(d_exchanger, false);
- )
+ conv.xfr16BitInt(d_preference);
+ conv.xfrLabel(d_exchanger, false);
+ )
boilerplate_conv(IPSECKEY, ns_t_ipseckey,
conv.xfr8BitInt(d_preference);
)
boilerplate_conv(DHCID, 49,
- conv.xfrBlob(d_content);
- )
+ conv.xfrBlob(d_content);
+ )
boilerplate_conv(AFSDB, ns_t_afsdb,
- conv.xfr16BitInt(d_subtype);
- conv.xfrLabel(d_hostname);
- )
+ conv.xfr16BitInt(d_subtype);
+ conv.xfrLabel(d_hostname);
+ )
boilerplate_conv(NAPTR, ns_t_naptr,
- conv.xfr16BitInt(d_order); conv.xfr16BitInt(d_preference);
- conv.xfrText(d_flags); conv.xfrText(d_services); conv.xfrText(d_regexp);
- conv.xfrLabel(d_replacement);
- )
+ conv.xfr16BitInt(d_order); conv.xfr16BitInt(d_preference);
+ conv.xfrText(d_flags); conv.xfrText(d_services); conv.xfrText(d_regexp);
+ conv.xfrLabel(d_replacement);
+ )
SRVRecordContent::SRVRecordContent(uint16_t preference, uint16_t weight, uint16_t port, const string& target)
{}
boilerplate_conv(SRV, ns_t_srv,
- conv.xfr16BitInt(d_preference); conv.xfr16BitInt(d_weight); conv.xfr16BitInt(d_port);
- conv.xfrLabel(d_target);
- )
+ conv.xfr16BitInt(d_preference); conv.xfr16BitInt(d_weight); conv.xfr16BitInt(d_port);
+ conv.xfrLabel(d_target);
+ )
SOARecordContent::SOARecordContent(const string& mname, const string& rname, const struct soatimes& st)
: DNSRecordContent(ns_t_soa), d_mname(mname), d_rname(rname)
}
boilerplate_conv(SOA, ns_t_soa,
- conv.xfrLabel(d_mname, true);
- conv.xfrLabel(d_rname, true);
- conv.xfr32BitInt(d_st.serial);
- conv.xfr32BitInt(d_st.refresh);
- conv.xfr32BitInt(d_st.retry);
- conv.xfr32BitInt(d_st.expire);
- conv.xfr32BitInt(d_st.minimum);
- );
+ conv.xfrLabel(d_mname, true);
+ conv.xfrLabel(d_rname, true);
+ conv.xfr32BitInt(d_st.serial);
+ conv.xfr32BitInt(d_st.refresh);
+ conv.xfr32BitInt(d_st.retry);
+ conv.xfr32BitInt(d_st.expire);
+ conv.xfr32BitInt(d_st.minimum);
+ );
#undef KEY
boilerplate_conv(KEY, ns_t_key,
- conv.xfr16BitInt(d_flags);
- conv.xfr8BitInt(d_protocol);
- conv.xfr8BitInt(d_algorithm);
- conv.xfrBlob(d_certificate);
- );
+ conv.xfr16BitInt(d_flags);
+ conv.xfr8BitInt(d_protocol);
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfrBlob(d_certificate);
+ );
boilerplate_conv(CERT, 37,
- conv.xfr16BitInt(d_type);
+ conv.xfr16BitInt(d_type);
if (d_type == 0) throw MOADNSException("CERT type 0 is reserved");
- conv.xfr16BitInt(d_tag);
- conv.xfr8BitInt(d_algorithm);
+ conv.xfr16BitInt(d_tag);
+ conv.xfr8BitInt(d_algorithm);
conv.xfrBlob(d_certificate);
)
boilerplate_conv(TLSA, 52,
- conv.xfr8BitInt(d_certusage);
- conv.xfr8BitInt(d_selector);
- conv.xfr8BitInt(d_matchtype);
- conv.xfrHexBlob(d_cert, true);
- )
-
+ conv.xfr8BitInt(d_certusage);
+ conv.xfr8BitInt(d_selector);
+ conv.xfr8BitInt(d_matchtype);
+ conv.xfrHexBlob(d_cert, true);
+ )
+
#undef DS
DSRecordContent::DSRecordContent() : DNSRecordContent(43) {}
boilerplate_conv(DS, 43,
- conv.xfr16BitInt(d_tag);
- conv.xfr8BitInt(d_algorithm);
- conv.xfr8BitInt(d_digesttype);
- conv.xfrHexBlob(d_digest, true); // keep reading across spaces
- )
+ conv.xfr16BitInt(d_tag);
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfr8BitInt(d_digesttype);
+ conv.xfrHexBlob(d_digest, true); // keep reading across spaces
+ )
DLVRecordContent::DLVRecordContent() : DNSRecordContent(32769) {}
boilerplate_conv(DLV,32769 ,
- conv.xfr16BitInt(d_tag);
- conv.xfr8BitInt(d_algorithm);
- conv.xfr8BitInt(d_digesttype);
- conv.xfrHexBlob(d_digest, true); // keep reading across spaces
- )
+ conv.xfr16BitInt(d_tag);
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfr8BitInt(d_digesttype);
+ conv.xfrHexBlob(d_digest, true); // keep reading across spaces
+ )
boilerplate_conv(SSHFP, 44,
- conv.xfr8BitInt(d_algorithm);
- conv.xfr8BitInt(d_fptype);
- conv.xfrHexBlob(d_fingerprint);
- )
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfr8BitInt(d_fptype);
+ conv.xfrHexBlob(d_fingerprint);
+ )
boilerplate_conv(RRSIG, 46,
- conv.xfrType(d_type);
- conv.xfr8BitInt(d_algorithm);
- conv.xfr8BitInt(d_labels);
- conv.xfr32BitInt(d_originalttl);
- conv.xfrTime(d_sigexpire);
- conv.xfrTime(d_siginception);
- conv.xfr16BitInt(d_tag);
- conv.xfrLabel(d_signer);
- conv.xfrBlob(d_signature);
- )
-
+ conv.xfrType(d_type);
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfr8BitInt(d_labels);
+ conv.xfr32BitInt(d_originalttl);
+ conv.xfrTime(d_sigexpire);
+ conv.xfrTime(d_siginception);
+ conv.xfr16BitInt(d_tag);
+ conv.xfrLabel(d_signer);
+ conv.xfrBlob(d_signature);
+ )
+
RRSIGRecordContent::RRSIGRecordContent() : DNSRecordContent(46) {}
boilerplate_conv(DNSKEY, 48,
- conv.xfr16BitInt(d_flags);
- conv.xfr8BitInt(d_protocol);
- conv.xfr8BitInt(d_algorithm);
- conv.xfrBlob(d_key);
- )
+ conv.xfr16BitInt(d_flags);
+ conv.xfr8BitInt(d_protocol);
+ conv.xfr8BitInt(d_algorithm);
+ conv.xfrBlob(d_key);
+ )
DNSKEYRecordContent::DNSKEYRecordContent() : DNSRecordContent(48) {}
boilerplate_conv(RKEY, 57,
- conv.xfr16BitInt(d_flags);
- conv.xfr8BitInt(d_protocol);
- conv.xfrBlob(d_key);
- )
+ conv.xfr16BitInt(d_flags);
+ conv.xfr8BitInt(d_protocol);
+ conv.xfrBlob(d_key);
+ )
RKEYRecordContent::RKEYRecordContent() : DNSRecordContent(57) {}
/* EUI48 start */
// "fancy records"
boilerplate_conv(URL, QType::URL,
- conv.xfrLabel(d_url);
- )
+ conv.xfrLabel(d_url);
+ )
boilerplate_conv(MBOXFW, QType::MBOXFW,
- conv.xfrLabel(d_mboxfw);
- )
+ conv.xfrLabel(d_mboxfw);
+ )
if(mdp.d_header.arcount && !mdp.d_answers.empty()) {
BOOST_FOREACH(const MOADNSParser::answers_t::value_type& val, mdp.d_answers) {
if(val.first.d_place == DNSRecord::Additional && val.first.d_type == QType::OPT) {
- eo->d_packetsize=val.first.d_class;
+ eo->d_packetsize=val.first.d_class;
- EDNS0Record stuff;
- uint32_t ttl=ntohl(val.first.d_ttl);
- memcpy(&stuff, &ttl, sizeof(stuff));
-
- eo->d_extRCode=stuff.extRCode;
- eo->d_version=stuff.version;
- eo->d_Z = ntohs(stuff.Z);
- OPTRecordContent* orc =
- dynamic_cast<OPTRecordContent*>(val.first.d_content.get());
- if(!orc)
- return false;
- orc->getData(eo->d_options);
- return true;
+ EDNS0Record stuff;
+ uint32_t ttl=ntohl(val.first.d_ttl);
+ memcpy(&stuff, &ttl, sizeof(stuff));
+
+ eo->d_extRCode=stuff.extRCode;
+ eo->d_version=stuff.version;
+ eo->d_Z = ntohs(stuff.Z);
+ OPTRecordContent* orc =
+ dynamic_cast<OPTRecordContent*>(val.first.d_content.get());
+ if(!orc)
+ return false;
+ orc->getData(eo->d_options);
+ return true;
}
}
}
ordered_unique<tag<AssignedIDTag>, BOOST_MULTI_INDEX_MEMBER(QuestionData, int, d_assignedID) >
>
> qids_t;
-
+
qids_t qids;
qids_t::const_iterator i=qids.find(qi);
QuestionData qd=*i;
- // cout<<"Matched answer "<<qi<<endl;
+ // cout<<"Matched answer "<<qi<<endl;
qd.d_origAnswers=mdp.d_answers;
qd.d_origRcode=mdp.d_header.rcode;
qids.replace(i, qd);
if(qd.d_newRcode!=-1) {
- // cout<<"Removing entry "<<qi<<", is done [in main loop]"<<endl;
+ // cout<<"Removing entry "<<qi<<", is done [in main loop]"<<endl;
measureResultAndClean(qi);
}
s_socket->setNonBlocking();
ComboAddress remote(g_vm["target-ip"].as<string>(),
- g_vm["target-port"].as<uint16_t>());
+ g_vm["target-port"].as<uint16_t>());
cerr<<"Replaying packets to: '"<<g_vm["target-ip"].as<string>()<<"', port "<<g_vm["target-port"].as<uint16_t>()<<endl;
/*
IPEndpoint remote(argc > 2 ? argv[2] : "127.0.0.1",
- argc > 3 ? atoi(argv[3]) : 5300);
+ argc > 3 ? atoi(argv[3]) : 5300);
*/
for(unsigned int i=0; i < mdp.d_qname.length(); ++i)
if(!isalnum(mdp.d_qname[i]) && mdp.d_qname[i]!='.' && mdp.d_qname[i]!='-' && mdp.d_qname[i]!='_') {
- // cout<<mdp.d_qname<<"|"<<mdp.d_qtype<<"|"<<mdp.d_qclass<<"\n";
+ // cout<<mdp.d_qname<<"|"<<mdp.d_qtype<<"|"<<mdp.d_qclass<<"\n";
// sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
break;
}
if(mdp.d_qtype > 256 || mdp.d_qclass!=1 ) {
- // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
+ // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
}
for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {
}
catch(MOADNSException &e) {
cout<<"Error from remote "<<U32ToIP(ntohl(*((uint32_t*)&pr.d_ip->ip_src)))<<": "<<e.what()<<"\n";
- // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
+ // sock.sendTo(string(pr.d_payload, pr.d_payload + pr.d_len), remote);
}
}
}
ntohs(pr.d_udp->uh_dport)==53 || ntohs(pr.d_udp->uh_sport)==53) &&
pr.d_len > 12) {
try {
- if((pr.d_ip->ip_v == 4 && !doIPv4) || (pr.d_ip->ip_v == 6 && !doIPv6))
- continue;
+ if((pr.d_ip->ip_v == 4 && !doIPv4) || (pr.d_ip->ip_v == 6 && !doIPv6))
+ continue;
MOADNSParser mdp((const char*)pr.d_payload, pr.d_len);
- if(haveRDFilter && mdp.d_header.rd != rdFilter)
- continue;
-
- if(pr.d_ip->ip_v == 4)
- ++ipv4Packets;
- else
- ++ipv6Packets;
-
- if(!mdp.d_header.qr) {
- if(!mdp.d_header.rd)
- nonRDQueries++;
- queries++;
- }
+ if(haveRDFilter && mdp.d_header.rd != rdFilter)
+ continue;
+
+ if(pr.d_ip->ip_v == 4)
+ ++ipv4Packets;
+ else
+ ++ipv6Packets;
+
+ if(!mdp.d_header.qr) {
+ if(!mdp.d_header.rd)
+ nonRDQueries++;
+ queries++;
+ }
lowestTime=min((time_t)lowestTime, (time_t)pr.d_pheader.ts.tv_sec);
highestTime=max((time_t)highestTime, (time_t)pr.d_pheader.ts.tv_sec);
QuestionIdentifier qi=QuestionIdentifier::create(pr.getSource(), pr.getDest(), mdp);
if(!mdp.d_header.qr) {
- // cout<<"Question for '"<< name <<"'\n";
+ // cout<<"Question for '"<< name <<"'\n";
QuestionData& qd=statmap[qi];
untracked++;
qd.d_answercount++;
- // cout<<"Answer to '"<< name <<"': RCODE="<<(int)mdp.d_rcode<<", "<<mdp.d_answers.size()<<" answers\n";
+ // cout<<"Answer to '"<< name <<"': RCODE="<<(int)mdp.d_rcode<<", "<<mdp.d_answers.size()<<" answers\n";
if(qd.d_qcount) {
uint32_t usecs= (pr.d_pheader.ts.tv_sec - qd.d_firstquestiontime.tv_sec) * 1000000 +
(pr.d_pheader.ts.tv_usec - qd.d_firstquestiontime.tv_usec) ;
- // cout<<"Took: "<<usecs<<"usec\n";
+ // cout<<"Took: "<<usecs<<"usec\n";
if(usecs<2049000)
cumul[usecs]++;
else
rcodes[mdp.d_header.rcode]++;
}
catch(MOADNSException& mde) {
- // cerr<<"error parsing packet: "<<mde.what()<<endl;
+ // cerr<<"error parsing packet: "<<mde.what()<<endl;
if(pw)
pw->write();
dnserrors++;
/* this is where the RRSIGs begin, keys are retrieved,
but the actual signing happens in fillOutRRSIG */
int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL,
- vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs, bool ksk)
+ vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs, bool ksk)
{
if(toSign.empty())
return -1;
d_record.resize(len + part.size());
memcpy(((&*d_record.begin()) + len), part.c_str(), part.size());
- pos+=(part.size())+1;
+ pos+=(part.size())+1;
}
else {
char labelsize=(char)(i->second - i->first);
#include "dns.hh"
namespace {
- struct EDNSSubnetOptsWire
- {
- uint16_t family;
- uint8_t sourceMask;
- uint8_t scopeMask;
- } GCCPACKATTRIBUTE;
+ struct EDNSSubnetOptsWire
+ {
+ uint16_t family;
+ uint8_t sourceMask;
+ uint8_t scopeMask;
+ } GCCPACKATTRIBUTE;
}
#define RDTSC(qp) \
do { \
- unsigned long lowPart, highPart; \
+ unsigned long lowPart, highPart; \
__asm__ __volatile__("rdtsc" : "=a" (lowPart), "=d" (highPart)); \
qp = (((unsigned long long) highPart) << 32) | lowPart; \
} while (0)
if(ival != d_ttdWatch.end()) { // found something!
++processed;
- struct timeval now;
- gettimeofday(&now, 0);
- unsigned int usec = 1000000*(now.tv_sec - ival->sentTime.tv_sec) + (now.tv_usec - ival->sentTime.tv_usec);
+ struct timeval now;
+ gettimeofday(&now, 0);
+ unsigned int usec = 1000000*(now.tv_sec - ival->sentTime.tv_sec) + (now.tv_usec - ival->sentTime.tv_usec);
d_sr.deliverAnswer(*ival->iter, answer, usec); // deliver to sender/receiver
d_ttdWatch.erase(ival);
break; // we can send new questions!
g_stats.ipv6queries++;
if((ret=asendto((const char*)&*vpacket.begin(), (int)vpacket.size(), 0, ip, pw.getHeader()->id,
- domain, type, &queryfd)) < 0) {
+ domain, type, &queryfd)) < 0) {
return ret; // passes back the -2 EMFILE
}
// sleep until we see an answer to this, interface to mtasker
ret=arecvfrom(reinterpret_cast<char *>(buf.get()), bufsize-1,0, ip, &len, pw.getHeader()->id,
- domain, type, queryfd, now);
+ domain, type, queryfd, now);
}
else {
try {
if((d_nsock6 < 0 && remote.sin4.sin_family == AF_INET6) ||
(d_nsock4 < 0 && remote.sin4.sin_family == AF_INET))
continue; // don't try to notify what we can't!
- if(d_preventSelfNotification && AddressIsUs(remote))
- continue;
+ if(d_preventSelfNotification && AddressIsUs(remote))
+ continue;
sendNotification(remote.sin4.sin_family == AF_INET ? d_nsock4 : d_nsock6, domain, remote, id);
drillHole(domain, ip);
if(IsAnyAddress(us)) {
int s = socket(remote.sin4.sin_family, SOCK_DGRAM, 0);
if(s < 0)
- continue;
+ continue;
if(connect(s, (struct sockaddr*)&remote, remote.getSocklen()) < 0) {
- close(s);
- continue;
+ close(s);
+ continue;
}
ComboAddress actualLocal;
socklen_t socklen = actualLocal.getSocklen();
if(getsockname(s, (struct sockaddr*) &actualLocal, &socklen) < 0) {
- close(s);
- continue;
+ close(s);
+ continue;
}
close(s);
actualLocal.sin4.sin_port = us.sin4.sin_port;
if(actualLocal == remote)
- return true;
+ return true;
}
}
return false;
if(pfd.revents & POLLIN) {
sock=pfd.fd;
if((len=recvmsg(sock, &msgh, 0)) < 0 ) {
- if(errno != EAGAIN)
- L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
- return 0;
+ if(errno != EAGAIN)
+ L<<Logger::Error<<"recvfrom gave error, ignoring: "<<strerror(errno)<<endl;
+ return 0;
}
break;
}
if(HarvestDestinationAddress(&msgh, &dest)) {
// cerr<<"Setting d_anyLocal to '"<<dest.toString()<<"'"<<endl;
packet->d_anyLocal = dest;
- }
+ }
if(packet->parse(mesg, len)<0) {
S.inc("corrupt-packets");
void NSEC3PARAMRecordContent::toPacket(DNSPacketWriter& pw)
{
pw.xfr8BitInt(d_algorithm);
- pw.xfr8BitInt(d_flags);
- pw.xfr16BitInt(d_iterations);
+ pw.xfr8BitInt(d_flags);
+ pw.xfr16BitInt(d_iterations);
pw.xfr8BitInt(d_salt.length());
// cerr<<"salt: '"<<makeHexDump(d_salt)<<"', "<<d_salt.length()<<endl;
pw.xfrBlob(d_salt);
{
NSEC3PARAMRecordContent* ret=new NSEC3PARAMRecordContent();
pr.xfr8BitInt(ret->d_algorithm);
- pr.xfr8BitInt(ret->d_flags);
- pr.xfr16BitInt(ret->d_iterations);
+ pr.xfr8BitInt(ret->d_flags);
+ pr.xfr16BitInt(ret->d_iterations);
pr.xfr8BitInt(ret->d_saltlength);
pr.xfrHexBlob(ret->d_salt);
string ret;
RecordTextWriter rtw(ret);
rtw.xfr8BitInt(d_algorithm);
- rtw.xfr8BitInt(d_flags);
- rtw.xfr16BitInt(d_iterations);
+ rtw.xfr8BitInt(d_flags);
+ rtw.xfr16BitInt(d_iterations);
rtw.xfrHexBlob(d_salt);
return ret;
}
for(; iter != d_map.end(); ++iter) {
if(!pdns_iequals(iter->qname, suffix) && !iends_with(iter->qname, dotsuffix)) {
- // cerr<<"Stopping!"<<endl;
+ // cerr<<"Stopping!"<<endl;
break;
}
delcount++;
{
// nobody reads what we output, but it appears to be the magic that shuts some nameservers up
static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "199.7.91.13", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53",
- "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
+ "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
static char templ[40];
strncpy(templ,"a.root-servers.net", sizeof(templ) - 1);
for(vector<DNSResourceRecord>::const_iterator i=crrs.begin(); i!=crrs.end(); ++i) {
if(r->d.aa && !i->qname.empty() && i->qtype.getCode()==QType::NS && !B.getSOA(i->qname,sd,p)) { // drop AA in case of non-SOA-level NS answer, except for root referral
r->setA(false);
- // i->d_place=DNSResourceRecord::AUTHORITY; // XXX FIXME
+ // i->d_place=DNSResourceRecord::AUTHORITY; // XXX FIXME
}
string content = stripDot(i->content);
goto sendit;
}
-
+
if(weRedirected) {
BOOST_FOREACH(rr, rrset) {
if(rr.qtype.getCode() == QType::CNAME) {
//! used to send information to a newborn mthread
struct DNSComboWriter {
DNSComboWriter(const char* data, uint16_t len, const struct timeval& now) : d_mdp(data, len), d_now(now),
- d_tcp(false), d_socket(-1)
+ d_tcp(false), d_socket(-1)
{}
MOADNSParser d_mdp;
void setRemote(const ComboAddress* sa)
if(t_pdl->get()) {
if(res == RCode::NoError) {
- vector<DNSResourceRecord>::const_iterator i;
- for(i=ret.begin(); i!=ret.end(); ++i)
- if(i->qtype.getCode() == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER)
- break;
- if(i == ret.end())
- (*t_pdl)->nodata(dc->d_remote, g_listenSocketsAddresses[dc->d_socket], dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer);
- }
- else if(res == RCode::NXDomain)
+ vector<DNSResourceRecord>::const_iterator i;
+ for(i=ret.begin(); i!=ret.end(); ++i)
+ if(i->qtype.getCode() == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER)
+ break;
+ if(i == ret.end())
+ (*t_pdl)->nodata(dc->d_remote, g_listenSocketsAddresses[dc->d_socket], dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer);
+ }
+ else if(res == RCode::NXDomain)
(*t_pdl)->nxdomain(dc->d_remote, g_listenSocketsAddresses[dc->d_socket], dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer);
(*t_pdl)->postresolve(dc->d_remote, g_listenSocketsAddresses[dc->d_socket], dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer);
sendto(dc->d_socket, (const char*)&*packet.begin(), packet.size(), 0, (struct sockaddr *)(&dc->d_remote), dc->d_remote.getSocklen());
if(!SyncRes::s_nopacketcache && !variableAnswer ) {
t_packetCache->insertResponsePacket(string((const char*)&*packet.begin(), packet.size()), g_now.tv_sec,
- min(minTTL,
- (pw.getHeader()->rcode == RCode::ServFail) ? SyncRes::s_packetcacheservfailttl : SyncRes::s_packetcachettl
- )
- );
+ min(minTTL,
+ (pw.getHeader()->rcode == RCode::ServFail) ? SyncRes::s_packetcacheservfailttl : SyncRes::s_packetcachettl
+ )
+ );
}
}
else {
uint32_t age;
if(!SyncRes::s_nopacketcache && t_packetCache->getResponsePacket(question, g_now.tv_sec, &response, &age)) {
if(!g_quiet)
- L<<Logger::Error<<t_id<< " question answered from packet cache from "<<fromaddr.toString()<<endl;
+ L<<Logger::Error<<t_id<< " question answered from packet cache from "<<fromaddr.toString()<<endl;
g_stats.packetCacheHits++;
SyncRes::s_queries++;
L<<Logger::Error<<"Ignoring non-query opcode "<<dh->opcode<<" from "<<fromaddr.toString()<<" on server socket!"<<endl;
}
else {
- string question(data, len);
- if(g_weDistributeQueries)
- distributeAsyncFunction(boost::bind(doProcessUDPQuestion, question, fromaddr, fd));
- else
- doProcessUDPQuestion(question, fromaddr, fd);
+ string question(data, len);
+ if(g_weDistributeQueries)
+ distributeAsyncFunction(boost::bind(doProcessUDPQuestion, question, fromaddr, fd));
+ else
+ doProcessUDPQuestion(question, fromaddr, fd);
}
}
catch(MOADNSException& mde) {
name = "PRIVATEOID"; return;
default:
name = "Unallocated/Reserved"; return;
- }
+ }
};
static int shorthand2algorithm(const string &algorithm)
else {
cerr<<"Added a " << (keyOrZone ? "KSK" : "ZSK")<<" with algorithm = "<<algorithm<<", active="<<active<<endl;
if(bits)
- cerr<<"Requested specific key size of "<<bits<<" bits"<<endl;
+ cerr<<"Requested specific key size of "<<bits<<" bits"<<endl;
}
}
else if(cmds[0] == "remove-zone-key") {
for(unsigned int n = 3; n < cmds.size(); ++n) {
if(pdns_iequals(cmds[n], "ZSK"))
- dpk.d_flags = 256;
+ dpk.d_flags = 256;
else if(pdns_iequals(cmds[n], "KSK"))
- dpk.d_flags = 257;
+ dpk.d_flags = 257;
else if(pdns_iequals(cmds[n], "active"))
- active = 1;
+ active = 1;
else if(pdns_iequals(cmds[n], "passive") || pdns_iequals(cmds[n], "inactive"))
- active = 0;
+ active = 0;
else {
- cerr<<"Unknown key flag '"<<cmds[n]<<"'"<<endl;
- exit(1);
- }
+ cerr<<"Unknown key flag '"<<cmds[n]<<"'"<<endl;
+ exit(1);
+ }
}
if(!dk.addKey(zone, dpk, active)) {
cerr<<"Adding key failed, perhaps DNSSEC not enabled in configuration?"<<endl;
keys.assign(cmds.begin() + 2, cmds.end());
} else {
keys = boost::assign::list_of("ALLOW-2136-FROM")
- ("ALLOW-AXFR-FROM")("ALSO-NOTIFY")("AXFR-MASTER-TSIG")
+ ("ALLOW-AXFR-FROM")("ALSO-NOTIFY")("AXFR-MASTER-TSIG")
("AXFR-SOURCE")("LUA-AXFR-SCRIPT")("NSEC3NARROW")
("NSEC3PARAM")("PRESIGNED")("SOA-EDIT")
("TSIG-ALLOW-2136")("TSIG-ALLOW-AXFR"); // NOTE: Add new metas here
if(d_iter != d_readCallbacks.end()) {
d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
if(d_readCallbacks.count(d_pevents[n].portev_object) && port_associate(d_portfd, PORT_SOURCE_FD, d_pevents[n].portev_object,
- POLLIN, 0) < 0)
+ POLLIN, 0) < 0)
throw FDMultiplexerException("Unable to add fd back to ports (read): "+stringerror());
continue; // so we don't find ourselves as writable again
}
if(d_iter != d_writeCallbacks.end()) {
d_iter->second.d_callback(d_iter->first, d_iter->second.d_parameter);
if(d_writeCallbacks.count(d_pevents[n].portev_object) && port_associate(d_portfd, PORT_SOURCE_FD, d_pevents[n].portev_object,
- POLLOUT, 0) < 0)
+ POLLOUT, 0) < 0)
throw FDMultiplexerException("Unable to add fd back to ports (write): "+stringerror());
}
const struct dnsheader* packet = reinterpret_cast<const struct dnsheader*>((*iter).d_packet.c_str());
if (packet->qdcount > 0)
{
- // find out type
- const struct dnsrecordheader *header = reinterpret_cast<const struct dnsrecordheader*>((*iter).d_packet.c_str()+sizeof(struct dnsheader));
- uint16_t type = header->d_type;
- std::string domain=questionExpand((*iter).d_packet.c_str(), (*iter).d_packet.size(), type);
- if (pdns_iequals(name,domain))
- {
- iter = d_packetCache.erase(iter);
- count++;
- } else iter++;
+ // find out type
+ const struct dnsrecordheader *header = reinterpret_cast<const struct dnsrecordheader*>((*iter).d_packet.c_str()+sizeof(struct dnsheader));
+ uint16_t type = header->d_type;
+ std::string domain=questionExpand((*iter).d_packet.c_str(), (*iter).d_packet.size(), type);
+ if (pdns_iequals(name,domain))
+ {
+ iter = d_packetCache.erase(iter);
+ count++;
+ } else iter++;
}
}
return count;
uint16_t offset=256*(labellen & ~0xc0) + (unsigned int)serial.at(frompos++) - sizeof(dnsheader)-5;
simpleExpandTo(encoded, offset, rr.content);
- // cerr<<"Oops, fallback, content so far: '"<<rr.content<<"', offset: "<<offset<<", '"<<qname<<"', "<<qt.getName()<<"\n";
+ // cerr<<"Oops, fallback, content so far: '"<<rr.content<<"', offset: "<<offset<<", '"<<qname<<"', "<<qt.getName()<<"\n";
break;
}
rr.content.append(serial.c_str()+frompos, labellen);
if(::arg()["hint-file"].empty()) {
static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "199.7.91.13", "192.203.230.10", "192.5.5.241",
- "192.112.36.4", "128.63.2.53",
- "192.36.148.17","192.58.128.30", "193.0.14.129", "199.7.83.42", "202.12.27.33"};
+ "192.112.36.4", "128.63.2.53",
+ "192.36.148.17","192.58.128.30", "193.0.14.129", "199.7.83.42", "202.12.27.33"};
static const char *ip6s[]={
"2001:503:ba3e::2:30", NULL, NULL, "2001:500:2d::d", NULL,
"2001:500:2f::f", NULL, "2001:500:1::803f:235", "2001:7fe::53",
for(SyncRes::domainmap_t::const_iterator i = t_sstorage->domainmap->begin(); i != t_sstorage->domainmap->end(); ++i) {
for(SyncRes::AuthDomain::records_t::const_iterator j = i->second.d_records.begin(); j != i->second.d_records.end(); ++j)
- broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j->qname));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j->qname));
}
string configname=::arg()["config-dir"]+"/recursor.conf";
// purge again - new zones need to blank out the cache
for(SyncRes::domainmap_t::const_iterator i = newDomainMap->begin(); i != newDomainMap->end(); ++i) {
for(SyncRes::AuthDomain::records_t::const_iterator j = i->second.d_records.begin(); j != i->second.d_records.end(); ++j)
- broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j->qname));
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j->qname));
}
// this is pretty blunt
string searchSuffix = ::arg()["export-etc-hosts-search-suffix"];
string::size_type pos;
while(getline(ifs,line)) {
- pos=line.find('#');
- if(pos!=string::npos)
- line.resize(pos);
- trim(line);
- if(line.empty())
- continue;
- parts.clear();
- stringtok(parts, line, "\t\r\n ");
- if(parts[0].find(':')!=string::npos)
- continue;
-
- for(unsigned int n=1; n < parts.size(); ++n) {
- if(searchSuffix.empty() || parts[n].find('.') != string::npos)
- makeNameToIPZone(newMap, parts[n], parts[0]);
- else {
- string canonic=toCanonic(searchSuffix, parts[n]);
- if(canonic != parts[n]) {
- makeNameToIPZone(newMap, canonic, parts[0]);
+ pos=line.find('#');
+ if(pos!=string::npos)
+ line.resize(pos);
+ trim(line);
+ if(line.empty())
+ continue;
+ parts.clear();
+ stringtok(parts, line, "\t\r\n ");
+ if(parts[0].find(':')!=string::npos)
+ continue;
+
+ for(unsigned int n=1; n < parts.size(); ++n) {
+ if(searchSuffix.empty() || parts[n].find('.') != string::npos)
+ makeNameToIPZone(newMap, parts[n], parts[0]);
+ else {
+ string canonic=toCanonic(searchSuffix, parts[n]);
+ if(canonic != parts[n]) {
+ makeNameToIPZone(newMap, canonic, parts[0]);
}
}
}
- makeIPToNamesZone(newMap, parts);
+ makeIPToNamesZone(newMap, parts);
}
}
}
vector<pair<string::size_type, string::size_type> > fields;
vstringtok(fields, rr.content, " ");
if(fields.size()==4) {
- if(fields[3].second - fields[3].first > 1) // strip dot, unless root
- fields[3].second--;
+ if(fields[3].second - fields[3].first > 1) // strip dot, unless root
+ fields[3].second--;
rr.content=string(rr.content.c_str() + fields[1].first, fields[3].second - fields[1].first);
}
}
if(drc.first.d_type == QType::RRSIG) {
shared_ptr<RRSIGRecordContent> rrc=boost::dynamic_pointer_cast<RRSIGRecordContent>(drc.first.d_content);
if(rrc->d_type == QType::SOA) {
- *theirInception= std::max(*theirInception, rrc->d_siginception);
- *theirExpire = std::max(*theirExpire, rrc->d_sigexpire);
+ *theirInception= std::max(*theirInception, rrc->d_siginception);
+ *theirExpire = std::max(*theirExpire, rrc->d_sigexpire);
}
}
}
}
AXFRRetriever::AXFRRetriever(const ComboAddress& remote,
- const string& domain,
- const string& tsigkeyname,
- const string& tsigalgorithm,
- const string& tsigsecret,
- const ComboAddress* laddr)
+ const string& domain,
+ const string& tsigkeyname,
+ const string& tsigalgorithm,
+ const string& tsigsecret,
+ const ComboAddress* laddr)
: d_tsigkeyname(tsigkeyname), d_tsigsecret(tsigsecret), d_tsigPos(0), d_nonSignedMessages(0)
{
ComboAddress local;
if (laddr != NULL) {
- local = (ComboAddress) (*laddr);
+ local = (ComboAddress) (*laddr);
} else {
- if(remote.sin4.sin_family == AF_INET)
- local=ComboAddress(::arg()["query-local-address"]);
- else if(!::arg()["query-local-address6"].empty())
- local=ComboAddress(::arg()["query-local-address6"]);
- else
- local=ComboAddress("::");
+ if(remote.sin4.sin_family == AF_INET)
+ local=ComboAddress(::arg()["query-local-address"]);
+ else if(!::arg()["query-local-address6"].empty())
+ local=ComboAddress(::arg()["query-local-address6"]);
+ else
+ local=ComboAddress("::");
}
d_sock = -1;
try {
return;
}
} else {
- laddr.sin4.sin_family = 0;
+ laddr.sin4.sin_family = 0;
}
AXFRRetriever retriever(raddr, domain.c_str(), tsigkeyname, tsigalgorithm, tsigsecret,
- (laddr.sin4.sin_family == 0) ? NULL : &laddr);
+ (laddr.sin4.sin_family == 0) ? NULL : &laddr);
bool gotPresigned = false;
bool gotNSEC3 = false;
DomainInfo& di(val.di);
// might've come from the packethandler
if(!di.backend && !B->getDomainInfo(di.zone, di)) {
- L<<Logger::Warning<<"Ignore domain "<< di.zone<<" since it has been removed from our backend"<<endl;
- continue;
+ L<<Logger::Warning<<"Ignore domain "<< di.zone<<" since it has been removed from our backend"<<endl;
+ continue;
}
if(!ssr.d_freshness.count(di.id))
void operator()() const
{
DNSRecordContent*drc = DNSRecordContent::mastermake(QType::A, 1,
- "1.2.3.4");
+ "1.2.3.4");
delete drc;
}
};
for(int records = 0; records < d_records; records++) {
pw.startRecord("outpost.ds9a.nl", d_type);
DNSRecordContent*drc = DNSRecordContent::mastermake(d_type, 1,
- d_content);
+ d_content);
drc->toPacket(pw);
delete drc;
}
// nobody reads what we output, but it appears to be the magic that shuts some nameservers up
static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "199.7.91.13", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53",
- "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
+ "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
static char templ[40];
strncpy(templ,"a.root-servers.net", sizeof(templ) - 1);
rr.content=toLower(rr.content); // this must stay! (the cache can't be case-insensitive on the RHS of records)
tcache[make_pair(i->qname,i->qtype)].insert(rr);
}
- }
+ }
else
; // LOG<<"NO!"<<endl;
}
}
// for ANY answers we *must* have an authoritative answer
else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) &&
- (
- i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
- )
+ (
+ i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) )
+ )
)
{
bool SyncRes::s_doAAAAAdditionalProcessing;
SyncRes::SyncRes(const struct timeval& now) : d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
- d_now(now),
- d_cacheonly(false), d_nocache(false), d_doEDNS0(false), d_lm(s_lm)
-
+ d_now(now),
+ d_cacheonly(false), d_nocache(false), d_doEDNS0(false), d_lm(s_lm)
+
{
if(!t_sstorage) {
t_sstorage = new StaticStorage();
if(mode== EDNSStatus::CONFIRMEDPINGER) { // confirmed pinger!
if(!res->d_pingCorrect) {
L<<Logger::Error<<"Confirmed EDNS-PING enabled host "<<ip.toString()<<" did not send back correct ping"<<endl;
- // perhaps lower some kind of count here, don't want to punnish a downgrader too long!
+ // perhaps lower some kind of count here, don't want to punnish a downgrader too long!
ret = 0;
res->d_rcode = RCode::ServFail;
g_stats.ednsPingMismatches++;
}
else if(mode==EDNSStatus::UNKNOWN || mode==EDNSStatus::EDNSPINGOK || mode == EDNSStatus::EDNSIGNORANT ) {
if(res->d_rcode == RCode::FormErr) {
- // cerr<<"Downgrading to EDNSNOPING because of FORMERR!"<<endl);
+ // cerr<<"Downgrading to EDNSNOPING because of FORMERR!"<<endl);
mode = EDNSStatus::EDNSNOPING;
continue;
}
else if(mode==EDNSStatus::UNKNOWN && (res->d_rcode == RCode::Refused || res->d_rcode == RCode::NotImp) ) { // this "fixes" F5
- // cerr<<"Downgrading an unknown status to EDNSNOPING because of RCODE="<<res->d_rcode<<endl;
+ // cerr<<"Downgrading an unknown status to EDNSNOPING because of RCODE="<<res->d_rcode<<endl;
mode = EDNSStatus::EDNSNOPING;
continue;
}
else if(!res->d_haveEDNS) {
if(mode != EDNSStatus::EDNSIGNORANT) {
mode = EDNSStatus::EDNSIGNORANT;
- // cerr<<"We find that "<<ip.toString()<<" is an EDNS-ignorer, moving to mode 3"<<endl);
+ // cerr<<"We find that "<<ip.toString()<<" is an EDNS-ignorer, moving to mode 3"<<endl);
}
}
}
else if(mode==EDNSStatus::EDNSNOPING) {
if(res->d_rcode == RCode::FormErr) {
- // cerr<<"Downgrading to mode 4, FORMERR!"<<endl);
+ // cerr<<"Downgrading to mode 4, FORMERR!"<<endl);
mode = EDNSStatus::NOEDNS;
continue;
}
DNSResourceRecord rr=*k;
rr.content=k->content;
if(!dottedEndsOn(rr.content, subdomain) || t_RC->get(d_now.tv_sec, rr.content, s_doIPv6 ? QType(QType::ADDR) : QType(QType::A),
- doLog() ? &aset : 0) > 5) {
+ doLog() ? &aset : 0) > 5) {
bestns.insert(rr);
LOG(prefix<<qname<<": NS (with ip, or non-glue) in cache for '"<<subdomain<<"' -> '"<<rr.content<<"'"<<endl);
LOG(prefix<<qname<<": within bailiwick: "<<dottedEndsOn(rr.content, subdomain));
/** returns -1 in case of no results, rcode otherwise */
int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth, bool flawedNSSet, const string &qname, const QType &qtype,
- vector<DNSResourceRecord>&ret,
- int depth, set<GetBestNSAnswer>&beenthere)
+ vector<DNSResourceRecord>&ret,
+ int depth, set<GetBestNSAnswer>&beenthere)
{
string prefix;
if(doLog()) {
}
resolveret=asyncresolveWrapper(*remoteIP, qname, qtype.getCode(),
- doTCP, sendRDQuery, &d_now, &lwr); // <- we go out on the wire!
+ doTCP, sendRDQuery, &d_now, &lwr); // <- we go out on the wire!
if(resolveret != 1) {
if(resolveret==0) {
- LOG(prefix<<qname<<": timeout resolving "<< (doTCP ? "over TCP" : "")<<endl);
- d_timeouts++;
- s_outgoingtimeouts++;
+ LOG(prefix<<qname<<": timeout resolving "<< (doTCP ? "over TCP" : "")<<endl);
+ d_timeouts++;
+ s_outgoingtimeouts++;
}
else if(resolveret==-2) {
- LOG(prefix<<qname<<": hit a local resource limit resolving"<< (doTCP ? " over TCP" : "")<<", probable error: "<<stringerror()<<endl);
- g_stats.resourceLimits++;
+ LOG(prefix<<qname<<": hit a local resource limit resolving"<< (doTCP ? " over TCP" : "")<<", probable error: "<<stringerror()<<endl);
+ g_stats.resourceLimits++;
}
else {
- s_unreachables++; d_unreachables++;
- LOG(prefix<<qname<<": error resolving"<< (doTCP ? " over TCP" : "") <<", possible error: "<<strerror(errno)<< endl);
+ s_unreachables++; d_unreachables++;
+ LOG(prefix<<qname<<": error resolving"<< (doTCP ? " over TCP" : "") <<", possible error: "<<strerror(errno)<< endl);
}
if(resolveret!=-2) { // don't account for resource limits, they are our own fault
- {
-
- t_sstorage->nsSpeeds[*tns].submit(*remoteIP, 1000000, &d_now); // 1 sec
- }
- if(resolveret==-1)
- t_sstorage->throttle.throttle(d_now.tv_sec, make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // unreachable, 1 minute or 100 queries
- else
- t_sstorage->throttle.throttle(d_now.tv_sec, make_tuple(*remoteIP, qname, qtype.getCode()), 10, 5); // timeout
+ {
+
+ t_sstorage->nsSpeeds[*tns].submit(*remoteIP, 1000000, &d_now); // 1 sec
+ }
+ if(resolveret==-1)
+ t_sstorage->throttle.throttle(d_now.tv_sec, make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // unreachable, 1 minute or 100 queries
+ else
+ t_sstorage->throttle.throttle(d_now.tv_sec, make_tuple(*remoteIP, qname, qtype.getCode()), 10, 5); // timeout
}
continue;
}
if(remoteIP->sin4.sin_family==AF_INET6)
lwr.d_usec/=3;
*/
- // cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
+ // cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
t_sstorage->nsSpeeds[*tns].submit(*remoteIP, lwr.d_usec, &d_now);
}
tcache[make_pair(i->qname,i->qtype)].insert(rr);
}
- }
+ }
else
LOG("NO!"<<endl);
}
ne.d_qname=i->qname;
ne.d_ttd=d_now.tv_sec + i->ttl;
-
+
ne.d_name=qname;
ne.d_qtype=QType(0); // this encodes 'whole record'
}
// for ANY answers we *must* have an authoritative answer, unless we are forwarding recursively
else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) &&
- (
- i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) ) || sendRDQuery
- )
+ (
+ i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) ) || sendRDQuery
+ )
)
{
typedef accumulator_set<
double
, stats<boost::accumulators::tag::median(with_p_square_quantile),
- boost::accumulators::tag::mean(immediate)
- >
+ boost::accumulators::tag::mean(immediate)
+ >
> acc_t;
typedef pair<std::string, uint16_t> typedns_t;
BOOST_AUTO_TEST_CASE(test_CIStringCompare) {
- set<std::string, CIStringCompare> nsset;
- nsset.insert("abc");
- nsset.insert("ns.example.com");
- nsset.insert("");
- nsset.insert("def");
- nsset.insert("aBc");
- nsset.insert("ns.example.com");
- BOOST_CHECK_EQUAL(nsset.size(), 4);
-
- ostringstream s;
- for(set<std::string, CIStringCompare>::const_iterator i=nsset.begin();i!=nsset.end();++i) {
- s<<"("<<*i<<")";
- }
- BOOST_CHECK_EQUAL(s.str(), "()(abc)(def)(ns.example.com)");
+ set<std::string, CIStringCompare> nsset;
+ nsset.insert("abc");
+ nsset.insert("ns.example.com");
+ nsset.insert("");
+ nsset.insert("def");
+ nsset.insert("aBc");
+ nsset.insert("ns.example.com");
+ BOOST_CHECK_EQUAL(nsset.size(), 4);
+
+ ostringstream s;
+ for(set<std::string, CIStringCompare>::const_iterator i=nsset.begin();i!=nsset.end();++i) {
+ s<<"("<<*i<<")";
+ }
+ BOOST_CHECK_EQUAL(s.str(), "()(abc)(def)(ns.example.com)");
}
BOOST_AUTO_TEST_CASE(test_CIStringPairCompare) {
- set<typedns_t, CIStringPairCompare> nsset2;
- nsset2.insert(make_pair("ns.example.com", 1));
- nsset2.insert(make_pair("abc", 1));
- nsset2.insert(make_pair("", 1));
- nsset2.insert(make_pair("def", 1));
- nsset2.insert(make_pair("abc", 2));
- nsset2.insert(make_pair("abc", 1));
- nsset2.insert(make_pair("ns.example.com", 0));
- nsset2.insert(make_pair("abc", 2));
- nsset2.insert(make_pair("ABC", 2));
- BOOST_CHECK_EQUAL(nsset2.size(), 6);
-
- ostringstream s;
- for(set<typedns_t, CIStringPairCompare>::const_iterator i=nsset2.begin();i!=nsset2.end();++i) {
- s<<"("<<i->first<<"|"<<i->second<<")";
- }
- BOOST_CHECK_EQUAL(s.str(), "(|1)(abc|1)(abc|2)(def|1)(ns.example.com|0)(ns.example.com|1)");
+ set<typedns_t, CIStringPairCompare> nsset2;
+ nsset2.insert(make_pair("ns.example.com", 1));
+ nsset2.insert(make_pair("abc", 1));
+ nsset2.insert(make_pair("", 1));
+ nsset2.insert(make_pair("def", 1));
+ nsset2.insert(make_pair("abc", 2));
+ nsset2.insert(make_pair("abc", 1));
+ nsset2.insert(make_pair("ns.example.com", 0));
+ nsset2.insert(make_pair("abc", 2));
+ nsset2.insert(make_pair("ABC", 2));
+ BOOST_CHECK_EQUAL(nsset2.size(), 6);
+
+ ostringstream s;
+ for(set<typedns_t, CIStringPairCompare>::const_iterator i=nsset2.begin();i!=nsset2.end();++i) {
+ s<<"("<<i->first<<"|"<<i->second<<")";
+ }
+ BOOST_CHECK_EQUAL(s.str(), "(|1)(abc|1)(abc|2)(def|1)(ns.example.com|0)(ns.example.com|1)");
}
BOOST_AUTO_TEST_CASE(test_pdns_ilexicographical_compare) {
BOOST_AUTO_TEST_SUITE(rcp_generator_cc)
BOOST_AUTO_TEST_CASE(test_xfrIP6) {
- RecordTextReader rtr("::1");
- string rawIPv6;
- rtr.xfrIP6(rawIPv6);
- string loopback6;
- loopback6.append(15, 0);
- loopback6.append(1,1);
- BOOST_CHECK_EQUAL(makeHexDump(rawIPv6), makeHexDump(loopback6));
-
- RecordTextReader rtr2("2a01:4f8:d12:1880::5");
- rtr2.xfrIP6(rawIPv6);
- string ip6("\x2a\x01\x04\xf8\x0d\x12\x18\x80\x00\x00\x00\x00\x00\x00\x00\x05", 16);
- BOOST_CHECK_EQUAL(makeHexDump(rawIPv6), makeHexDump(ip6));
-
-
+ RecordTextReader rtr("::1");
+ string rawIPv6;
+ rtr.xfrIP6(rawIPv6);
+ string loopback6;
+ loopback6.append(15, 0);
+ loopback6.append(1,1);
+ BOOST_CHECK_EQUAL(makeHexDump(rawIPv6), makeHexDump(loopback6));
+
+ RecordTextReader rtr2("2a01:4f8:d12:1880::5");
+ rtr2.xfrIP6(rawIPv6);
+ string ip6("\x2a\x01\x04\xf8\x0d\x12\x18\x80\x00\x00\x00\x00\x00\x00\x00\x05", 16);
+ BOOST_CHECK_EQUAL(makeHexDump(rawIPv6), makeHexDump(ip6));
+
+
}
BOOST_AUTO_TEST_SUITE_END()
#include "base64.hh"
#include "json.hh"
-
-map<string,WebServer::HandlerFunction *>WebServer::d_functions;
-void *WebServer::d_that;
-string WebServer::d_password;
+struct connectionThreadData {
+ WebServer* webServer;
+ Session* client;
+};
int WebServer::B64Decode(const std::string& strInput, std::string& strOutput)
{
return ::B64Decode(strInput, strOutput);
}
-void WebServer::registerHandler(const string&s, HandlerFunction *ptr)
+// url is supposed to start with a slash.
+// url can contain variable names, marked as <variable>; such variables
+// are parsed out during routing and are put into the "urlArgs" map.
+// route() makes no assumptions about the contents of variables except
+// that the following URL segment can't be part of the variable.
+//
+// Examples:
+// registerHandler("/", &index);
+// registerHandler("/foo", &foo);
+// registerHandler("/foo/<bar>/<baz>", &foobarbaz);
+void WebServer::registerHandler(const string& url, HandlerFunction *handler)
{
- d_functions[s]=ptr;
+ std::size_t pos = 0, lastpos = 0;
+
+ HandlerRegistration reg;
+ while ((pos = url.find('<', lastpos)) != std::string::npos) {
+ std::string part = url.substr(lastpos, pos-lastpos);
+ lastpos = pos;
+ pos = url.find('>', pos);
+
+ if (pos == std::string::npos) {
+ throw std::logic_error("invalid url given");
+ }
+
+ std::string paramName = url.substr(lastpos+1, pos-lastpos-1);
+ lastpos = pos+1;
+
+ reg.urlParts.push_back(part);
+ reg.paramNames.push_back(paramName);
+ }
+ std::string remainder = url.substr(lastpos);
+ if (!remainder.empty()) {
+ reg.urlParts.push_back(remainder);
+ reg.paramNames.push_back("");
+ }
+ reg.handler = handler;
+ d_handlers.push_back(reg);
+}
+
+bool WebServer::route(const std::string& url, std::map<std::string, std::string>& urlArgs, HandlerFunction** handler)
+{
+ for (std::list<HandlerRegistration>::iterator reg=d_handlers.begin(); reg != d_handlers.end(); ++reg) {
+ bool matches = true;
+ size_t lastpos = 0, pos = 0;
+ string lastParam;
+ urlArgs.clear();
+ for (std::list<string>::iterator urlPart = reg->urlParts.begin(), param = reg->paramNames.begin();
+ urlPart != reg->urlParts.end() && param != reg->paramNames.end();
+ urlPart++, param++) {
+ if (!urlPart->empty()) {
+ pos = url.find(*urlPart, lastpos);
+ if (pos == std::string::npos) {
+ matches = false;
+ break;
+ }
+ if (!lastParam.empty()) {
+ // store
+ urlArgs[lastParam] = url.substr(lastpos, pos-lastpos);
+ }
+ lastpos = pos + urlPart->size();
+ lastParam = *param;
+ }
+ }
+ if (matches) {
+ if (!lastParam.empty()) {
+ // store trailing parameter
+ urlArgs[lastParam] = url.substr(lastpos, pos-lastpos);
+ } else if (lastpos != url.size()) {
+ matches = false;
+ continue;
+ }
+
+ *handler = reg->handler;
+ return true;
+ }
+ }
+ return false;
}
void WebServer::setCaller(void *that)
d_that=that;
}
-void *WebServer::serveConnection(void *p)
-try {
+static void *WebServerConnectionThreadStart(void *p) {
+ connectionThreadData* data = static_cast<connectionThreadData*>(p);
pthread_detach(pthread_self());
- Session *client=static_cast<Session *>(p);
+ data->webServer->serveConnection(data->client);
+ delete data;
+ return NULL;
+}
+
+void WebServer::serveConnection(Session* client)
+try {
bool want_html=false;
bool want_json=false;
uri=parts[1];
}
- vector<string>variables;
-
parts.clear();
stringtok(parts,uri,"?");
- // L<<"baseUrl: '"<<parts[0]<<"'"<<endl;
-
- vector<string>urlParts;
- stringtok(urlParts,parts[0],"/");
- string baseUrl;
- if(urlParts.empty())
- baseUrl="";
- else
- baseUrl=urlParts[0];
-
- // L<<"baseUrl real: '"<<baseUrl<<"'"<<endl;
+ string baseUrl=parts[0];
+ vector<string>variables;
if(parts.size()>1) {
stringtok(variables,parts[1],"&");
}
stripLine(line);
if(line.empty())
- break;
+ break;
size_t colon = line.find(":");
if(colon==std::string::npos)
- throw HttpBadRequestException();
+ throw HttpBadRequestException();
string header = toLower(line.substr(0, colon));
string value = line.substr(line.find_first_not_of(' ', colon+1));
}
}
else if(header == "content-length" && method=="POST") {
- postlen = atoi(value.c_str());
-// cout<<"Got a post: "<<postlen<<" bytes"<<endl;
+ postlen = atoi(value.c_str());
+// cout<<"Got a post: "<<postlen<<" bytes"<<endl;
}
else if(header == "accept") {
- // json wins over html
- if(value.find("application/json")!=std::string::npos) {
- want_json=true;
- } else if(value.find("text/html")!=std::string::npos) {
- want_html=true;
- }
+ // json wins over html
+ if(value.find("application/json")!=std::string::npos) {
+ want_json=true;
+ } else if(value.find("text/html")!=std::string::npos) {
+ want_html=true;
+ }
}
else
- ; // cerr<<"Ignoring line: "<<line<<endl;
+ ; // cerr<<"Ignoring line: "<<line<<endl;
} while(true);
if(!d_password.empty() && !authOK)
throw HttpUnauthorizedException();
- HandlerFunction *fptr;
- if(d_functions.count(baseUrl) && (fptr=d_functions[baseUrl])) {
+ HandlerFunction *handler;
+ map<string, string> urlArgs;
+ if (route(baseUrl, urlArgs, &handler)) {
bool custom=false;
- string ret=(*fptr)(method, post, varmap, d_that, &custom);
+ string ret=(*handler)(method, post, varmap, d_that, &custom);
if(!custom) {
client->putLine("HTTP/1.1 200 OK\n");
client->putLine("Content-Type: text/html; charset=utf-8\n\n");
}
client->putLine(ret);
- }
- else {
+ } else {
throw HttpNotFoundException();
}
client->close();
delete client;
client=0;
-
- return 0;
}
catch(SessionTimeoutException &e) {
// L<<Logger::Error<<"Timeout in webserver"<<endl;
L<<Logger::Error<<"Launched webserver on " << d_server->d_local.toStringWithPort() <<endl;
while((client=d_server->accept())) {
- pthread_create(&tid, 0 , &serveConnection, (void *)client);
+ // will be freed by thread
+ connectionThreadData *data = new connectionThreadData;
+ data->webServer = this;
+ data->client = client;
+ pthread_create(&tid, 0, &WebServerConnectionThreadStart, (void *)data);
}
}
catch(SessionTimeoutException &e) {
#define WEBSERVER_HH
#include <map>
#include <string>
-
+#include <list>
#include "namespaces.hh"
class Server;
+class Session;
class HttpException
{
public:
WebServer(const string &listenaddress, int port, const string &password="");
void go();
- static void* serveConnection(void *);
+
+ void serveConnection(Session* client);
+
void setCaller(void *that);
+
typedef string HandlerFunction(const string& method, const string& post, const map<string,string>&varmap, void *that, bool *custom);
- void registerHandler(const string &, HandlerFunction *ptr);
+ struct HandlerRegistration {
+ std::list<string> urlParts;
+ std::list<string> paramNames;
+ HandlerFunction *handler;
+ };
+
+ void registerHandler(const string& url, HandlerFunction *handler);
+
private:
static char B64Decode1(char cInChar);
static int B64Decode(const std::string& strInput, std::string& strOutput);
+ bool route(const std::string& url, std::map<std::string, std::string>& urlArgs, HandlerFunction** handler);
+
string d_listenaddress;
int d_port;
- static map<string,HandlerFunction *>d_functions;
- static void *d_that;
- static string d_password;
+ std::list<HandlerRegistration> d_handlers;
+ void* d_that;
+ string d_password;
Server* d_server;
};
#endif /* WEBSERVER_HH */
}
catch(std::exception& e)
{
- return returnJSONError("Following record had a problem: "+rr.qname+" IN " +rr.qtype.getName()+ " " + rr.content+": "+e.what());
+ return returnJSONError("Following record had a problem: "+rr.qname+" IN " +rr.qtype.getName()+ " " + rr.content+": "+e.what());
}
}
// but now what
UeberBackend B;
DomainInfo di;
if(!B.getDomainInfo(zonename, di))
- return returnJSONError("Deleting domain '"+zonename+"' failed: domain does not exist");
+ return returnJSONError("Deleting domain '"+zonename+"' failed: domain does not exist");
if(!di.backend->deleteDomain(zonename))
- return returnJSONError("Deleting domain '"+zonename+"' failed: backend delete failed/unsupported");
+ return returnJSONError("Deleting domain '"+zonename+"' failed: backend delete failed/unsupported");
map<string, string> success; // empty success object
return returnJSONObject(success);
} else {
{
try {
d_ws->setCaller(this);
- d_ws->registerHandler("",&indexfunction);
- d_ws->registerHandler("style.css",&cssfunction);
+ d_ws->registerHandler("/",&indexfunction);
+ d_ws->registerHandler("/style.css",&cssfunction);
if(::arg().mustDo("experimental-json-interface"))
- d_ws->registerHandler("jsonstat", &jsonstat);
+ d_ws->registerHandler("/jsonstat", &jsonstat);
d_ws->go();
}
catch(...) {
if( ( pos = domain2.rfind( g_zonename ) ) == string::npos )
{
- cerr << "Domain " << domain2 << " not part of " << g_zonename << endl;
- return;
+ cerr << "Domain " << domain2 << " not part of " << g_zonename << endl;
+ return;
}
host = stripDot( domain2.substr( 0, pos ) );
if( !g_objects[domain2] )
{
- g_objects[domain2] = true;
-
- cout << "changetype: add" << endl;
- cout << "objectclass: dnsdomain2" << endl;
- cout << "objectclass: domainrelatedobject" << endl;
- cout << "dc: " << host << endl;
- if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; }
- cout << "associateddomain: " << domain2 << endl;
+ g_objects[domain2] = true;
+
+ cout << "changetype: add" << endl;
+ cout << "objectclass: dnsdomain2" << endl;
+ cout << "objectclass: domainrelatedobject" << endl;
+ cout << "dc: " << host << endl;
+ if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; }
+ cout << "associateddomain: " << domain2 << endl;
}
else
{
- cout << "changetype: modify" << endl;
- cout << "add: " << qtype << "Record" << endl;
+ cout << "changetype: modify" << endl;
+ cout << "add: " << qtype << "Record" << endl;
}
cout << qtype << "Record: ";
for( i = parts.size() - 1; i > 0; i-- )
{
- net = parts[i] + net;
- dn = "dc=" + parts[i] + "," + dn;
-
- if( !g_objects[net] )
- {
- g_objects[net] = true;
-
- cout << "dn: " << dn << g_basedn << endl;
- cout << "changetype: add" << endl;
- cout << "objectclass: dnsdomain2" << endl;
- cout << "objectclass: domainrelatedobject" << endl;
- cout << "dc: " << parts[i] << endl;
- cout << "associateddomain: " << net << endl << endl;
- }
-
- net = "." + net;
+ net = parts[i] + net;
+ dn = "dc=" + parts[i] + "," + dn;
+
+ if( !g_objects[net] )
+ {
+ g_objects[net] = true;
+
+ cout << "dn: " << dn << g_basedn << endl;
+ cout << "changetype: add" << endl;
+ cout << "objectclass: dnsdomain2" << endl;
+ cout << "objectclass: domainrelatedobject" << endl;
+ cout << "dc: " << parts[i] << endl;
+ cout << "associateddomain: " << net << endl << endl;
+ }
+
+ net = "." + net;
}
cout << "dn: " << "dc=" << parts[0] << "," << dn << g_basedn << endl;
if( !g_objects[domain2] )
{
- g_objects[domain2] = true;
-
- cout << "changetype: add" << endl;
- cout << "objectclass: dnsdomain2" << endl;
- cout << "objectclass: domainrelatedobject" << endl;
- cout << "dc: " << parts[0] << endl;
- if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; }
- cout << "associateddomain: " << domain2 << endl;
+ g_objects[domain2] = true;
+
+ cout << "changetype: add" << endl;
+ cout << "objectclass: dnsdomain2" << endl;
+ cout << "objectclass: domainrelatedobject" << endl;
+ cout << "dc: " << parts[0] << endl;
+ if( g_dnsttl ) { cout << "dnsttl: " << ttl << endl; }
+ cout << "associateddomain: " << domain2 << endl;
}
else
{
- cout << "changetype: modify" << endl;
- cout << "add: " << qtype << "Record" << endl;
+ cout << "changetype: modify" << endl;
+ cout << "add: " << qtype << "Record" << endl;
}
cout << qtype << "Record: ";
try
{
#if __GNUC__ >= 3
- std::ios_base::sync_with_stdio( false );
+ std::ios_base::sync_with_stdio( false );
#endif
- reportAllTypes();
- args.setCmd( "help", "Provide a helpful message" );
- args.setSwitch( "verbose", "Verbose comments on operation" ) = "no";
- args.setSwitch( "resume", "Continue after errors" ) = "no";
- args.setSwitch( "dnsttl", "Add dnsttl attribute to every entry" ) = "no";
- args.set( "named-conf", "Bind 8 named.conf to parse" ) = "";
- args.set( "zone-file", "Zone file to parse" ) = "";
- args.set( "zone-name", "Specify a zone name if zone is set" ) = "";
- args.set( "basedn", "Base DN to store objects below" ) = "ou=hosts,o=mycompany,c=de";
- args.set( "layout", "How to arrange entries in the directory (simple or as tree)" ) = "simple";
-
- args.parse( argc, argv );
-
- if( argc < 2 || args.mustDo( "help" ) )
- {
- cerr << "Syntax:" << endl << endl;
- cerr << args.helpstring() << endl;
- exit( 1 );
- }
-
- g_basedn = args["basedn"];
- g_dnsttl = args.mustDo( "dnsttl" );
- typedef boost::function<void(unsigned int, const string &, const string &, const string &, int, int)> callback_t;
- callback_t callback = callback_simple;
- if( args["layout"] == "tree" )
- {
- callback=callback_tree;
- }
-
- if( !args["named-conf"].empty() )
- {
- BP.setVerbose( args.mustDo( "verbose" ) );
- BP.parse( args["named-conf"] );
-// ZP.setDirectory( BP.getDirectory() );
- const vector<BindDomainInfo> &domains = BP.getDomains();
-
- for( vector<BindDomainInfo>::const_iterator i = domains.begin(); i != domains.end(); i++ )
- {
- if(i->type!="master" && i->type!="slave") {
- cerr<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name<<"'"<<endl;
- continue;
- }
- try
- {
- if( i->name != "." && i->name != "localhost" && i->name != "0.0.127.in-addr.arpa" )
- {
- cerr << "Parsing file: " << i->filename << ", domain: " << i->name << endl;
- g_zonename = i->name;
- ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
- DNSResourceRecord rr;
- while(zpt.get(rr))
- callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
- }
- }
- catch( PDNSException &ae )
- {
- cerr << "Fatal error: " << ae.reason << endl;
- if( !args.mustDo( "resume" ) )
- {
- return 1;
- }
- }
- }
- }
- else
- {
- if( args["zone-file"].empty() || args["zone-name"].empty() )
- {
- cerr << "Error: At least zone-file and zone-name are required" << endl;
- return 1;
- }
-
- g_zonename = args["zone-name"];
- ZoneParserTNG zpt(args["zone-file"], args["zone-name"]);
- DNSResourceRecord rr;
- while(zpt.get(rr))
- callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
- }
+ reportAllTypes();
+ args.setCmd( "help", "Provide a helpful message" );
+ args.setSwitch( "verbose", "Verbose comments on operation" ) = "no";
+ args.setSwitch( "resume", "Continue after errors" ) = "no";
+ args.setSwitch( "dnsttl", "Add dnsttl attribute to every entry" ) = "no";
+ args.set( "named-conf", "Bind 8 named.conf to parse" ) = "";
+ args.set( "zone-file", "Zone file to parse" ) = "";
+ args.set( "zone-name", "Specify a zone name if zone is set" ) = "";
+ args.set( "basedn", "Base DN to store objects below" ) = "ou=hosts,o=mycompany,c=de";
+ args.set( "layout", "How to arrange entries in the directory (simple or as tree)" ) = "simple";
+
+ args.parse( argc, argv );
+
+ if( argc < 2 || args.mustDo( "help" ) )
+ {
+ cerr << "Syntax:" << endl << endl;
+ cerr << args.helpstring() << endl;
+ exit( 1 );
+ }
+
+ g_basedn = args["basedn"];
+ g_dnsttl = args.mustDo( "dnsttl" );
+ typedef boost::function<void(unsigned int, const string &, const string &, const string &, int, int)> callback_t;
+ callback_t callback = callback_simple;
+ if( args["layout"] == "tree" )
+ {
+ callback=callback_tree;
+ }
+
+ if( !args["named-conf"].empty() )
+ {
+ BP.setVerbose( args.mustDo( "verbose" ) );
+ BP.parse( args["named-conf"] );
+// ZP.setDirectory( BP.getDirectory() );
+ const vector<BindDomainInfo> &domains = BP.getDomains();
+
+ for( vector<BindDomainInfo>::const_iterator i = domains.begin(); i != domains.end(); i++ )
+ {
+ if(i->type!="master" && i->type!="slave") {
+ cerr<<" Warning! Skipping '"<<i->type<<"' zone '"<<i->name<<"'"<<endl;
+ continue;
+ }
+ try
+ {
+ if( i->name != "." && i->name != "localhost" && i->name != "0.0.127.in-addr.arpa" )
+ {
+ cerr << "Parsing file: " << i->filename << ", domain: " << i->name << endl;
+ g_zonename = i->name;
+ ZoneParserTNG zpt(i->filename, i->name, BP.getDirectory());
+ DNSResourceRecord rr;
+ while(zpt.get(rr))
+ callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
+ }
+ }
+ catch( PDNSException &ae )
+ {
+ cerr << "Fatal error: " << ae.reason << endl;
+ if( !args.mustDo( "resume" ) )
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ if( args["zone-file"].empty() || args["zone-name"].empty() )
+ {
+ cerr << "Error: At least zone-file and zone-name are required" << endl;
+ return 1;
+ }
+
+ g_zonename = args["zone-name"];
+ ZoneParserTNG zpt(args["zone-file"], args["zone-name"]);
+ DNSResourceRecord rr;
+ while(zpt.get(rr))
+ callback(0, rr.qname, rr.qtype.getName(), rr.content, rr.ttl, rr.priority);
+ }
}
catch( PDNSException &ae )
{
- cerr << "Fatal error: " << ae.reason << endl;
- return 1;
+ cerr << "Fatal error: " << ae.reason << endl;
+ return 1;
}
catch( std::exception &e )
{
- cerr << "Died because of STL error: " << e.what() << endl;
- return 1;
+ cerr << "Died because of STL error: " << e.what() << endl;
+ return 1;
}
catch( ... )
{
- cerr << "Died because of unknown exception" << endl;
- return 1;
+ cerr << "Died because of unknown exception" << endl;
+ return 1;
}
return 0;
#include <boost/lexical_cast.hpp>
ZoneParserTNG::ZoneParserTNG(const string& fname, const string& zname, const string& reldir) : d_reldir(reldir),
- d_zonename(zname), d_defaultttl(3600),
- d_havedollarttl(false)
+ d_zonename(zname), d_defaultttl(3600),
+ d_havedollarttl(false)
{
d_zonename = toCanonic("", d_zonename);
stackFile(fname);
}
catch(...) {
throw runtime_error("Parsing zone content "+getLineOfFile()+
- ": '"+nextpart+
- "' doesn't look like a qtype, stopping loop");
+ ": '"+nextpart+
+ "' doesn't look like a qtype, stopping loop");
}
}
if(!haveQTYPE)