d.arcount = pw.getHeader()->arcount;
}
-void DNSPacket::setQuestion(int op, const string &qd, int newqtype)
+void DNSPacket::setQuestion(int op, const DNSName &qd, int newqtype)
{
memset(&d,0,sizeof(d));
d.id=Utility::random();
memcpy((void *)&d,(const void *)d_rawpacket.c_str(),12);
qdomain=mdp.d_qname;
- if(!qdomain.empty()) // strip dot
- boost::erase_tail(qdomain, 1);
+ // if(!qdomain.empty()) // strip dot
+ // boost::erase_tail(qdomain, 1);
if(!ntohs(d.qdcount)) {
if(!d_tcp) {
q->getTSIGDetails(trc, keyname, &message);
int64_t now = time(0);
if(abs((int64_t)trc->d_time - now) > trc->d_fudge) {
- L<<Logger::Error<<"Packet for '"<<q->qdomain<<"' denied: TSIG (key '"<<*keyname<<"') time delta "<< abs(trc->d_time - now)<<" > 'fudge' "<<trc->d_fudge<<endl;
+ L<<Logger::Error<<"Packet for '"<<q->qdomain.toString()<<"' denied: TSIG (key '"<<*keyname<<"') time delta "<< abs(trc->d_time - now)<<" > 'fudge' "<<trc->d_fudge<<endl;
return false;
}
- string algoName = toLowerCanonic(trc->d_algoName);
+ string algoName = trc->d_algoName.toString(); // FIXME
if (algoName == "hmac-md5.sig-alg.reg.int")
algoName = "hmac-md5";
string secret64;
if(!B->getTSIGKey(*keyname, &algoName, &secret64)) {
- L<<Logger::Error<<"Packet for domain '"<<q->qdomain<<"' denied: can't find TSIG key with name '"<<*keyname<<"' and algorithm '"<<algoName<<"'"<<endl;
+ L<<Logger::Error<<"Packet for domain '"<<q->qdomain.toString()<<"' denied: can't find TSIG key with name '"<<*keyname<<"' and algorithm '"<<algoName<<"'"<<endl;
return false;
}
if (trc->d_algoName == "hmac-md5")
TSIGHashEnum algo;
if(!getTSIGHashEnum(trc->d_algoName, algo)) {
- L<<Logger::Error<<"Unsupported TSIG HMAC algorithm " << trc->d_algoName << endl;
+ L<<Logger::Error<<"Unsupported TSIG HMAC algorithm " << trc->d_algoName.toString() << endl;
return false;
}
B64Decode(secret64, *secret);
bool result=calculateHMAC(*secret, message, algo) == trc->d_mac;
if(!result) {
- L<<Logger::Error<<"Packet for domain '"<<q->qdomain<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<<trc->d_algoName<<"'"<<endl;
+ L<<Logger::Error<<"Packet for domain '"<<q->qdomain.toString()<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<<trc->d_algoName.toString()<<"'"<<endl;
}
return result;
DNSResourceRecord d_place field */
void addRecord(const DNSResourceRecord &); // adds to 'rrs'
- void setQuestion(int op, const string &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (domain, type, class etc)
+ void setQuestion(int op, const DNSName &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (domain, type, class etc)
DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer
void wrapup(); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer
QType qtype; //!< type of the question 8
- string qdomain; //!< qname of the question 4 - unsure how this is used
- string qdomainwild; //!< wildcard matched by qname, used by LuaPolicyEngine
- string qdomainzone; //!< zone name for the answer (as reflected in SOA for negative responses), used by LuaPolicyEngine
+ DNSName qdomain; //!< qname of the question 4 - unsure how this is used
+ DNSName qdomainwild; //!< wildcard matched by qname, used by LuaPolicyEngine
+ DNSName qdomainzone; //!< zone name for the answer (as reflected in SOA for negative responses), used by LuaPolicyEngine
bool d_tcp;
bool d_dnssecOk;
bool d_havetsig;
vector<uint8_t> d_record;
};
-static const string EncodeDNSLabel(const string& input)
+//FIXME lots of overlap with DNSPacketWriter::xfrName
+static const string EncodeDNSLabel(const DNSName& input)
{
- if(input.length() == 1 && input[0]=='.') // otherwise we encode .. (long story)
+ if(!input.countLabels()) // otherwise we encode .. (long story)
return string (1, 0);
- labelparts_t parts;
- bool unescapedSomething = labeltokUnescape(parts, input);
+ auto parts = input.getRawLabels();
string ret;
- if(!unescapedSomething) {
- for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
- ret.append(1, i->second - i->first);
- ret.append(input.c_str() + i->first, i->second - i->first);
- }
+ for(auto &label: parts) {
+ ret.append(1, label.size());
+ ret.append(label);
+ }
- } else {
- for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
- string part(input.c_str() + i->first, i->second - i->first);
- boost::replace_all(part, "\\\\", "\\");
- boost::replace_all(part, "\\.", ".");
-
- ret.append(1, part.length());
- ret.append(part);
- }
- }
ret.append(1, 0);
return ret;
}
class IPSECKEYRecordContent : public DNSRecordContent
{
public:
- IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const DNSName& publickey);
+ IPSECKEYRecordContent(uint16_t preference, uint8_t gatewaytype, uint8_t algo, const DNSName& gateway, const string& publickey);
includeboilerplate(IPSECKEY)
private:
uint8_t d_preference, d_gatewaytype, d_algorithm;
- DNSName d_gateway, d_publickey;
+ DNSName d_gateway;
+ string d_publickey;
uint32_t d_ip4;
string d_ip6;
};
return calculateSHAHMAC(key, text, hash);
}
-string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigOffset, const string& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset)
+string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigOffset, const DNSName& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset)
{
string message;
string packet(opacket);
dw.xfrName(keyname, false);
dw.xfr16BitInt(QClass::ANY); // class
dw.xfr32BitInt(0); // TTL
- dw.xfrName(toLower(trc.d_algoName), false);
+ // dw.xfrName(toLower(trc.d_algoName), false); //FIXME
+ dw.xfrName(trc.d_algoName, false);
}
uint32_t now = trc.d_time;
return message;
}
-void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const string& tsigkeyname, const string& tsigsecret, const string& tsigprevious, bool timersonly)
+void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const DNSName& tsigkeyname, const string& tsigsecret, const string& tsigprevious, bool timersonly)
{
TSIGHashEnum algo;
if (!getTSIGHashEnum(trc->d_algoName, algo)) {
string calculateSHAHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash);
string calculateHMAC(const std::string& key, const std::string& text, TSIGHashEnum hash);
-string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigoffset, const string& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset=0);
-void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const string& tsigkeyname, const string& tsigsecret, const string& tsigprevious, bool timersonly);
+string makeTSIGMessageFromTSIGPacket(const string& opacket, unsigned int tsigoffset, const DNSName& keyname, const TSIGRecordContent& trc, const string& previous, bool timersonly, unsigned int dnsHeaderOffset=0);
+void addTSIG(DNSPacketWriter& pw, TSIGRecordContent* trc, const DNSName& tsigkeyname, const string& tsigsecret, const string& tsigprevious, bool timersonly);
uint64_t signatureCacheSize(const std::string& str);
#endif
#include <boost/foreach.hpp>
#include <limits.h>
-DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode)
+DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const DNSName& qname, uint16_t qtype, uint16_t qclass, uint8_t opcode)
: d_pos(0), d_content(content), d_qname(qname), d_canonic(false), d_lowerCase(false)
{
d_content.clear();
return (dnsheader*)&*d_content.begin();
}
-void DNSPacketWriter::startRecord(const string& name, uint16_t qtype, uint32_t ttl, uint16_t qclass, Place place, bool compress)
+void DNSPacketWriter::startRecord(const DNSName& name, uint16_t qtype, uint32_t ttl, uint16_t qclass, Place place, bool compress)
{
if(!d_record.empty())
commit();
d_stuff = 0;
d_rollbackmarker=d_content.size();
- if(compress && !d_recordqname.empty() && pdns_iequals(d_qname, d_recordqname)) { // don't do the whole label compression thing if we *know* we can get away with "see question" - except when compressing the root
+ if(compress && d_recordqname.countLabels() && d_qname==d_recordqname) { // don't do the whole label compression thing if we *know* we can get away with "see question" - except when compressing the root
static unsigned char marker[2]={0xc0, 0x0c};
d_content.insert(d_content.end(), (const char *) &marker[0], (const char *) &marker[2]);
}
return ret;
}
-//! tokenize a label into parts, the parts describe a begin offset and an end offset
-bool labeltokUnescape(labelparts_t& parts, const string& label)
-{
- string::size_type epos = label.size(), lpos(0), pos;
- bool unescapedSomething = false;
- const char* ptr=label.c_str();
-
- parts.clear();
-
- for(pos = 0 ; pos < epos; ++pos) {
- if(ptr[pos]=='\\') {
- pos++;
- unescapedSomething = true;
- continue;
- }
- if(ptr[pos]=='.') {
- parts.push_back(make_pair(lpos, pos));
- lpos=pos+1;
- }
- }
+// //! tokenize a label into parts, the parts describe a begin offset and an end offset
+// bool labeltokUnescape(labelparts_t& parts, const string& label)
+// {
+// string::size_type epos = label.size(), lpos(0), pos;
+// bool unescapedSomething = false;
+// const char* ptr=label.c_str();
+
+// parts.clear();
+
+// for(pos = 0 ; pos < epos; ++pos) {
+// if(ptr[pos]=='\\') {
+// pos++;
+// unescapedSomething = true;
+// continue;
+// }
+// if(ptr[pos]=='.') {
+// parts.push_back(make_pair(lpos, pos));
+// lpos=pos+1;
+// }
+// }
- if(lpos < pos)
- parts.push_back(make_pair(lpos, pos));
- return unescapedSomething;
-}
+// if(lpos < pos)
+// parts.push_back(make_pair(lpos, pos));
+// return unescapedSomething;
+// }
// this is the absolute hottest function in the pdns recursor
-void DNSPacketWriter::xfrName(const DNSName& Label, bool compress)
+void DNSPacketWriter::xfrName(const DNSName& name, bool compress)
{
- string label = d_lowerCase ? toLower(Label) : Label;
- labelparts_t parts;
+ // string label = d_lowerCase ? toLower(Label) : Label;
+ // FIXME: we ignore d_lowerCase for now
+ std::vector<std::string> parts = name.getRawLabels();
+ // labelparts_t parts;
if(d_canonic)
compress=false;
- string::size_type labellen = label.size();
- if(labellen==1 && label[0]=='.') { // otherwise we encode '..'
+ // string::size_type labellen = label.size();
+ if(!parts.size()) { // otherwise we encode '..'
d_record.push_back(0);
return;
}
- bool unescaped=labeltokUnescape(parts, label);
+ // bool unescaped=labeltokUnescape(parts, label);
// d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example
unsigned int pos=d_content.size() + d_record.size() + d_stuff;
- string chopped;
- bool deDot = labellen && (label[labellen-1]=='.'); // make sure we don't store trailing dots in the labelmap
+ // bool deDot = labellen && (label[labellen-1]=='.'); // make sure we don't store trailing dots in the labelmap
unsigned int startRecordSize=d_record.size();
unsigned int startPos;
- for(labelparts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) {
- if(deDot)
- chopped.assign(label.c_str() + i->first, labellen - i->first -1);
- else
- chopped.assign(label.c_str() + i->first);
+ for(auto &label: parts) {
+ // if(deDot)
+ // chopped.assign(label.c_str() + i->first, labellen - i->first -1);
+ // else
+ // chopped.assign(label.c_str() + i->first);
lmap_t::iterator li=d_labelmap.end();
// see if we've written out this domain before
// cerr<<"Searching for compression pointer to '"<<chopped<<"', "<<d_labelmap.size()<<" cmp-records"<<endl;
- if(compress && (li=find(d_labelmap, chopped))!=d_labelmap.end()) {
+ if(compress && (li=find(d_labelmap, label))!=d_labelmap.end()) {
// cerr<<"\tFound a compression pointer to '"<<chopped<<"': "<<li->second<<endl;
- if (d_record.size() - startRecordSize + chopped.size() > 253) // chopped does not include a length octet for the first label and the root label
+ if (d_record.size() - startRecordSize + label.size() > 253) // chopped does not include a length octet for the first label and the root label
throw MOADNSException("DNSPacketWriter::xfrName() found overly large (compressed) name");
uint16_t offset=li->second;
offset|=0xc000;
if(li==d_labelmap.end() && pos< 16384) {
// cerr<<"\tStoring a compression pointer to '"<<chopped<<"': "<<pos<<endl;
- d_labelmap.push_back(make_pair(chopped, pos)); // if untrue, we need to count - also, don't store offsets > 16384, won't work
+ d_labelmap.push_back(make_pair(label, pos)); // if untrue, we need to count - also, don't store offsets > 16384, won't work
}
startPos=pos;
- if(unescaped) {
- string part(label.c_str() + i -> first, i->second - i->first);
-
- // FIXME: this relies on the semi-canonical escaped output from getName
- boost::replace_all(part, "\\.", ".");
- boost::replace_all(part, "\\032", " ");
- boost::replace_all(part, "\\\\", "\\");
-
- d_record.push_back(part.size());
- unsigned int len=d_record.size();
- d_record.resize(len + part.size());
- memcpy(((&*d_record.begin()) + len), part.c_str(), part.size());
- pos+=(part.size())+1;
- }
- else {
- char labelsize=(char)(i->second - i->first);
+ // if(unescaped) {
+ // string part(label.c_str() + i -> first, i->second - i->first);
+
+ // // FIXME: this relies on the semi-canonical escaped output from getName
+ // boost::replace_all(part, "\\.", ".");
+ // boost::replace_all(part, "\\032", " ");
+ // boost::replace_all(part, "\\\\", "\\");
+
+ // d_record.push_back(part.size());
+ // unsigned int len=d_record.size();
+ // d_record.resize(len + part.size());
+ // memcpy(((&*d_record.begin()) + len), part.c_str(), part.size());
+ // pos+=(part.size())+1;
+ // }
+ // else {
+ char labelsize=label.size();
d_record.push_back(labelsize);
unsigned int len=d_record.size();
- d_record.resize(len + i->second - i->first);
- memcpy(((&*d_record.begin()) + len), label.c_str() + i-> first, i->second - i->first);
- pos+=(i->second - i->first)+1;
- }
+ d_record.resize(len + labelsize);
+ memcpy(((&*d_record.begin()) + len), label.c_str(), labelsize); // FIXME do not want memcpy
+ pos+=labelsize+1;
+ // }
if(pos - startPos == 1)
throw MOADNSException("DNSPacketWriter::xfrName() found empty label in the middle of name");
enum Place {ANSWER=1, AUTHORITY=2, ADDITIONAL=3};
//! Start a DNS Packet in the vector passed, with question qname, qtype and qclass
- DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t qtype, uint16_t qclass=QClass::IN, uint8_t opcode=0);
+ DNSPacketWriter(vector<uint8_t>& content, const DNSName& qname, uint16_t qtype, uint16_t qclass=QClass::IN, uint8_t opcode=0);
/** Start a new DNS record within this packet for namq, qtype, ttl, class and in the requested place. Note that packets can only be written in natural order -
ANSWER, AUTHORITY, ADDITIONAL */
- void startRecord(const string& name, uint16_t qtype, uint32_t ttl=3600, uint16_t qclass=QClass::IN, Place place=ANSWER, bool compress=true);
+ void startRecord(const DNSName& name, uint16_t qtype, uint32_t ttl=3600, uint16_t qclass=QClass::IN, Place place=ANSWER, bool compress=true);
/** Shorthand way to add an Opt-record, for example for EDNS0 purposes */
typedef vector<pair<uint16_t,std::string> > optvect_t;
private:
vector <uint8_t>& d_content;
vector <uint8_t> d_record;
- string d_qname;
- string d_recordqname;
+ DNSName d_qname;
+ DNSName d_recordqname;
uint16_t d_recordqtype, d_recordqclass;
uint32_t d_recordttl;
lmap_t d_labelmap;
};
typedef vector<pair<string::size_type, string::size_type> > labelparts_t;
-bool labeltokUnescape(labelparts_t& parts, const string& label);
+// bool labeltokUnescape(labelparts_t& parts, const DNSName& label);
std::vector<string> segmentDNSText(const string& text); // from dnslabeltext.rl
std::deque<string> segmentDNSName(const string& input ); // from dnslabeltext.rl
#endif
string value;
bool haveSomething;
{
- MapCombo& mc=getMap(pcReverse(p->qdomain));
+ MapCombo& mc=getMap(pcReverse(p->qdomain.toString())); // FIXME
TryReadLock l(&mc.d_mut); // take a readlock here
if(!l.gotIt()) {
S.inc("deferred-cache-lookup");
}
uint16_t maxReplyLen = p->d_tcp ? 0xffff : p->getMaxReplyLen();
- haveSomething=getEntryLocked(p->qdomain, p->qtype, PacketCache::PACKETCACHE, value, -1, recursive, maxReplyLen, p->d_dnssecOk, p->hasEDNS(), &age);
+ haveSomething=getEntryLocked(p->qdomain.toString() /*FIXME*/, p->qtype, PacketCache::PACKETCACHE, value, -1, recursive, maxReplyLen, p->d_dnssecOk, p->hasEDNS(), &age);
}
if(haveSomething) {
(*d_statnumhit)++;
if(minttl<ourttl)
ourttl=minttl;
}
- insert(q->qdomain, q->qtype, PacketCache::PACKETCACHE, r->getString(), ourttl, -1, recursive,
+ insert(q->qdomain.toString() /*FIXME*/, q->qtype, PacketCache::PACKETCACHE, r->getString(), ourttl, -1, recursive,
maxReplyLen, q->d_dnssecOk, q->hasEDNS());
}