}
}
-bool Bind2Backend::startTransaction(const string &qname, int id)
+bool Bind2Backend::startTransaction(const DNSName &qname, int id)
{
if(id < 0) {
d_transaction_tmpname.clear();
bool Bind2Backend::feedRecord(const DNSResourceRecord &r, string *ordername)
{
- string qname=r.qname;
+ string qname=r.qname.toString();
BB2DomainInfo bbd;
safeGetBBDomainInfo(d_transaction_id, &bbd);
else
hashed="";
}
- insertRecord(*bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed);
+ insertRecord(*bbd, rr.qname.toString(), rr.qtype, rr.content, rr.ttl, hashed);
}
fixupAuth(bbd->d_records.getWRITABLE());
doEmptyNonTerminals(*bbd, nsec3zone, ns3pr);
rr.qname=nt.first+"."+bbd.d_name+".";
if(nsec3zone)
hashed=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rr.qname));
- insertRecord(bbd, rr.qname, rr.qtype, rr.content, rr.ttl, hashed, &nt.second);
+ insertRecord(bbd, rr.qname.toString(), rr.qtype, rr.content, rr.ttl, hashed, &nt.second);
}
}
}
}
-bool Bind2Backend::findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
+bool Bind2Backend::findBeforeAndAfterUnhashed(BB2DomainInfo& bbd, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
{
- string domain=toLower(qname);
+ string domain=qname.toString();
shared_ptr<const recordstorage_t> records = bbd.d_records.get();
recordstorage_t::const_iterator iter = records->upper_bound(domain);
}
}
-void Bind2Backend::lookup(const QType &qtype, const string &qname, DNSPacket *pkt_p, int zoneId )
+void Bind2Backend::lookup(const QType &qtype, const DNSName &qname, DNSPacket *pkt_p, int zoneId )
{
d_handle.reset();
- string domain=toLower(qname);
+ string domain=qname.toString();
static bool mustlog=::arg().mustDo("query-logging");
if(mustlog)
return false;
}
if(d_handle.mustlog)
- L<<Logger::Warning<<"Returning: '"<<r.qtype.getName()<<"' of '"<<r.qname<<"', content: '"<<r.content<<"'"<<endl;
+ L<<Logger::Warning<<"Returning: '"<<r.qtype.getName()<<"' of '"<<r.qname.toString()<<"', content: '"<<r.content<<"'"<<endl;
return true;
}
~Bind2Backend();
void getUnfreshSlaveInfos(vector<DomainInfo> *unfreshDomains);
void getUpdatedMasters(vector<DomainInfo> *changedDomains);
- bool getDomainInfo(const string &domain, DomainInfo &di);
+ bool getDomainInfo(const DNSName &domain, DomainInfo &di);
time_t getCtime(const string &fname);
// DNSSEC
- virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
- void lookup(const QType &, const string &qdomain, DNSPacket *p=0, int zoneId=-1);
- bool list(const string &target, int id, bool include_disabled=false);
+ virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after);
+ void lookup(const QType &, const DNSName &qdomain, DNSPacket *p=0, int zoneId=-1);
+ bool list(const DNSName &target, int id, bool include_disabled=false);
bool get(DNSResourceRecord &);
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
void setFresh(uint32_t domain_id);
void setNotified(uint32_t id, uint32_t serial);
- bool startTransaction(const string &qname, int id);
+ bool startTransaction(const DNSName &qname, int id);
bool feedRecord(const DNSResourceRecord &r, string *ordername=0);
bool commitTransaction();
bool abortTransaction();
- void alsoNotifies(const string &domain, set<string> *ips);
+ void alsoNotifies(const DNSName &domain, set<string> *ips);
// the DNSSEC related (getDomainMetadata has broader uses too)
- virtual bool getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta);
- virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
- virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
- virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
- virtual bool removeDomainKey(const string& name, unsigned int id);
- virtual int addDomainKey(const string& name, const KeyData& key);
- virtual bool activateDomainKey(const string& name, unsigned int id);
- virtual bool deactivateDomainKey(const string& name, unsigned int id);
- virtual bool getTSIGKey(const string& name, string* algorithm, string* content);
- virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content);
- virtual bool deleteTSIGKey(const string& name);
+ virtual bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta);
+ virtual bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta);
+ virtual bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta);
+ virtual bool getDomainKeys(const DNSName& name, unsigned int kind, std::vector<KeyData>& keys);
+ virtual bool removeDomainKey(const DNSName& name, unsigned int id);
+ virtual int addDomainKey(const DNSName& name, const KeyData& key);
+ virtual bool activateDomainKey(const DNSName& name, unsigned int id);
+ virtual bool deactivateDomainKey(const DNSName& name, unsigned int id);
+ virtual bool getTSIGKey(const DNSName& name, string* algorithm, string* content);
+ virtual bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content);
+ virtual bool deleteTSIGKey(const DNSName& name);
virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
virtual bool doesDNSSEC();
// end of DNSSEC
void insertRecord(BB2DomainInfo& bbd, const string &qname, const QType &qtype, const string &content, int ttl, const std::string& hashed=string(), bool *auth=0);
void rediscover(string *status=0);
- bool isMaster(const string &name, const string &ip);
+ bool isMaster(const DNSName &name, const string &ip);
// for supermaster support
- bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
+ bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
static pthread_mutex_t s_supermaster_config_lock;
- bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account);
+ bool createSlaveDomain(const string &ip, const DNSName &domain, const string &nameserver, const string &account);
private:
void setupDNSSEC();
RandomBackend(const string &suffix="")
{
setArgPrefix("random"+suffix);
- d_ourname=getArg("hostname");
+ d_ourname=DNSName(getArg("hostname"));
}
- bool list(const string &target, int id, bool include_disabled) {
+ bool list(const DNSName &target, int id, bool include_disabled) {
return false; // we don't support AXFR
}
- void lookup(const QType &type, const string &qdomain, DNSPacket *p, int zoneId)
+ void lookup(const QType &type, const DNSName &qdomain, DNSPacket *p, int zoneId)
{
- if((type.getCode()!=QType::ANY && type.getCode()!=QType::A) || !pdns_iequals(qdomain, d_ourname)) // we only know about random.example.com A by default
+ if((type.getCode()!=QType::ANY && type.getCode()!=QType::A) || qdomain==d_ourname) // we only know about random.example.com A by default
d_answer=""; // no answer
else {
ostringstream os;
private:
string d_answer;
- string d_ourname;
+ DNSName d_ourname;
};
/* SECOND PART */
return true;
}
-bool GSQLBackend::updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
+bool GSQLBackend::updateEmptyNonTerminals(uint32_t domain_id, const DNSName& zonename, set<DNSName>& insert, set<DNSName>& erase, bool remove)
{
if(remove) {
try {
}
else
{
- BOOST_FOREACH(const string qname, erase) {
+ for(auto &qname: erase) {
try {
d_deleteEmptyNonTerminalQuery_stmt->
bind("domain_id", domain_id)->
reset();
}
catch (SSqlException &e) {
- throw PDNSException("GSQLBackend unable to delete empty non-terminal rr "+qname+" from domain_id "+itoa(domain_id)+": "+e.txtReason());
+ throw PDNSException("GSQLBackend unable to delete empty non-terminal rr "+qname.toString()+" from domain_id "+itoa(domain_id)+": "+e.txtReason());
return false;
}
}
}
- BOOST_FOREACH(const string qname, insert) {
+ for(auto &qname: insert) {
try {
d_insertEmptyNonTerminalQuery_stmt->
bind("domain_id", domain_id)->
reset();
}
catch (SSqlException &e) {
- throw PDNSException("GSQLBackend unable to insert empty non-terminal rr "+qname+" in domain_id "+itoa(domain_id)+": "+e.txtReason());
+ throw PDNSException("GSQLBackend unable to insert empty non-terminal rr "+qname.toString()+" in domain_id "+itoa(domain_id)+": "+e.txtReason());
return false;
}
}
bind("qtype",r.qtype.getName())->
bind("domain_id",r.domain_id)->
bind("disabled",r.disabled)->
- bind("qname",toLower(r.qname));
+ bind("qname",stripDot(r.qname.toString())); // FIXME lowercase?
if (ordername == NULL)
d_InsertRecordOrderQuery_stmt->bindNull("ordername");
else
bind("qtype",r.qtype.getName())->
bind("domain_id",r.domain_id)->
bind("disabled",r.disabled)->
- bind("qname",toLower(r.qname))->
+ bind("qname",stripDot(r.qname.toString()))->
bind("auth", (r.auth || !d_dnssecQueries))->
execute()->
reset();
virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth);
virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type);
virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname);
- virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert ,set<string>& erase, bool remove);
+ virtual bool updateEmptyNonTerminals(uint32_t domain_id, const DNSName& zonename, set<DNSName>& insert ,set<DNSName>& erase, bool remove);
virtual bool doesDNSSEC();
virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
virtual SSqlStatement* bind(const string& name, long long value)=0;;
virtual SSqlStatement* bind(const string& name, unsigned long long value)=0;
virtual SSqlStatement* bind(const string& name, const std::string& value)=0;
+ virtual SSqlStatement* bind(const string& name, const DNSName& value)=0;
virtual SSqlStatement* bindNull(const string& name)=0;
virtual SSqlStatement* execute()=0;;
virtual bool hasNextRow()=0;
void makeNotifySockets();
void queueNotifyDomain(const DNSName &domain, UeberBackend *B);
int d_nsock4, d_nsock6;
- map<pair<string,string>,time_t>d_holes;
+ map<pair<DNSName,string>,time_t>d_holes;
pthread_mutex_t d_holelock;
void launchRetrievalThreads();
void suck(const DNSName &domain, const string &remote);
AtomicCounter DNSSECKeeper::s_ops;
time_t DNSSECKeeper::s_last_prune;
-bool DNSSECKeeper::isSecuredZone(const std::string& zone)
+bool DNSSECKeeper::isSecuredZone(const DNSName& zone)
{
if(isPresigned(zone))
return true;
return false;
}
-bool DNSSECKeeper::isPresigned(const std::string& name)
+bool DNSSECKeeper::isPresigned(const DNSName& name)
{
string meta;
getFromMeta(name, "PRESIGNED", meta);
return meta=="1";
}
-bool DNSSECKeeper::addKey(const std::string& name, bool keyOrZone, int algorithm, int bits, bool active)
+bool DNSSECKeeper::addKey(const DNSName& name, bool keyOrZone, int algorithm, int bits, bool active)
{
if(!bits) {
if(algorithm <= 10)
s_metacache.clear();
}
-void DNSSECKeeper::clearCaches(const std::string& name)
+void DNSSECKeeper::clearCaches(const DNSName& name)
{
{
WriteLock l(&s_keycachelock);
}
-bool DNSSECKeeper::addKey(const std::string& name, const DNSSECPrivateKey& dpk, bool active)
+bool DNSSECKeeper::addKey(const DNSName& name, const DNSSECPrivateKey& dpk, bool active)
{
clearCaches(name);
DNSBackend::KeyData kd;
make_pair(!b.second.keyOrZone, b.second.id);
}
-DNSSECPrivateKey DNSSECKeeper::getKeyById(const std::string& zname, unsigned int id)
+DNSSECPrivateKey DNSSECKeeper::getKeyById(const DNSName& zname, unsigned int id)
{
vector<DNSBackend::KeyData> keys;
d_keymetadb->getDomainKeys(zname, 0, keys);
return dpk;
}
- throw runtime_error("Can't find a key with id "+lexical_cast<string>(id)+" for zone '"+zname+"'");
+ throw runtime_error("Can't find a key with id "+lexical_cast<string>(id)+" for zone '"+zname.toString()+"'");
}
-bool DNSSECKeeper::removeKey(const std::string& zname, unsigned int id)
+bool DNSSECKeeper::removeKey(const DNSName& zname, unsigned int id)
{
clearCaches(zname);
return d_keymetadb->removeDomainKey(zname, id);
}
-bool DNSSECKeeper::deactivateKey(const std::string& zname, unsigned int id)
+bool DNSSECKeeper::deactivateKey(const DNSName& zname, unsigned int id)
{
clearCaches(zname);
return d_keymetadb->deactivateDomainKey(zname, id);
}
-bool DNSSECKeeper::activateKey(const std::string& zname, unsigned int id)
+bool DNSSECKeeper::activateKey(const DNSName& zname, unsigned int id)
{
clearCaches(zname);
return d_keymetadb->activateDomainKey(zname, id);
}
-void DNSSECKeeper::getFromMeta(const std::string& zname, const std::string& key, std::string& value)
+void DNSSECKeeper::getFromMeta(const DNSName& zname, const std::string& key, std::string& value)
{
value.clear();
unsigned int now = time(0);
return (uint64_t)-1;
}
-bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
+bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
{
string value;
getFromMeta(zname, "NSEC3PARAM", value);
delete tmp;
if (ns3p->d_iterations > maxNSEC3Iterations) {
ns3p->d_iterations = maxNSEC3Iterations;
- L<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<zname<<"' is above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl;
+ L<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<zname.toString()<<"' is above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl;
}
}
if(narrow) {
return true;
}
-bool DNSSECKeeper::setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& ns3p, const bool& narrow)
+bool DNSSECKeeper::setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& ns3p, const bool& narrow)
{
static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations");
if (ns3p.d_iterations > maxNSEC3Iterations)
- throw runtime_error("Can't set NSEC3PARAM for zone '"+zname+"': number of NSEC3 iterations is above 'max-nsec3-iterations'");
+ throw runtime_error("Can't set NSEC3PARAM for zone '"+zname.toString()+"': number of NSEC3 iterations is above 'max-nsec3-iterations'");
clearCaches(zname);
string descr = ns3p.getZoneRepresentation();
return false;
}
-bool DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname)
+bool DNSSECKeeper::unsetNSEC3PARAM(const DNSName& zname)
{
clearCaches(zname);
return (d_keymetadb->setDomainMetadata(zname, "NSEC3PARAM", vector<string>()) && d_keymetadb->setDomainMetadata(zname, "NSEC3NARROW", vector<string>()));
}
-bool DNSSECKeeper::setPresigned(const std::string& zname)
+bool DNSSECKeeper::setPresigned(const DNSName& zname)
{
clearCaches(zname);
vector<string> meta;
return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", meta);
}
-bool DNSSECKeeper::unsetPresigned(const std::string& zname)
+bool DNSSECKeeper::unsetPresigned(const DNSName& zname)
{
clearCaches(zname);
return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", vector<string>());
}
-DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const std::string& zone, boost::tribool allOrKeyOrZone, bool useCache)
+DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, boost::tribool allOrKeyOrZone, bool useCache)
{
unsigned int now = time(0);
return retkeyset;
}
-bool DNSSECKeeper::secureZone(const std::string& name, int algorithm, int size)
+bool DNSSECKeeper::secureZone(const DNSName& name, int algorithm, int size)
{
clearCaches(name); // just to be sure ;)
return addKey(name, true, algorithm, size);
}
-bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const std::string& signer, const std::string& qname,
- const std::string& wildcardname, const QType& qtype,
+bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname,
+ const DNSName& wildcardname, const QType& qtype,
DNSPacketWriter::Place signPlace, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL)
{
vector<DNSResourceRecord> sigs;
- if(db.getDirectRRSIGs(toLower(signer), toLower(wildcardname.empty() ? qname : wildcardname), qtype, sigs)) {
+ if(db.getDirectRRSIGs(signer, wildcardname.countLabels() ? wildcardname : qname, qtype, sigs)) {
BOOST_FOREACH(DNSResourceRecord &rr, sigs) {
- if (!wildcardname.empty())
- rr.qname = toLower(qname);
rr.d_place = (DNSResourceRecord::Place)signPlace;
rr.ttl = signTTL;
rrsigs.push_back(rr);
DLOG(L<<"Could not get SOA for domain"<<endl);
return false;
}
- db.lookup(QType(QType::RRSIG), wildcardname.empty() ? qname : wildcardname, NULL, sd.domain_id);
+ db.lookup(QType(QType::RRSIG), wildcardname.countLabels() ? wildcardname : qname, 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+".")) {
+ if(parts[0] == qtype.getName() && DNSName(parts[7])==signer) {
// cerr<<"Got it"<<endl;
- if (!wildcardname.empty())
+ if (wildcardname.countLabels())
rr.qname = qname;
rr.d_place = (DNSResourceRecord::Place)signPlace;
rr.ttl = signTTL;
return true;
}
-bool DNSSECKeeper::TSIGGrantsAccess(const string& zone, const string& keyname)
+bool DNSSECKeeper::TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname)
{
vector<string> allowed;
d_keymetadb->getDomainMetadata(zone, "TSIG-ALLOW-AXFR", allowed);
BOOST_FOREACH(const string& dbkey, allowed) {
- if(pdns_iequals(dbkey, keyname))
+ if(DNSName(dbkey)==keyname)
return true;
}
return false;
}
-bool DNSSECKeeper::getTSIGForAccess(const string& zone, const string& master, string* keyname)
+bool DNSSECKeeper::getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname)
{
vector<string> keynames;
d_keymetadb->getDomainMetadata(zone, "AXFR-MASTER-TSIG", keynames);
- keyname->clear();
+ keyname->trimToLabels(0);
// XXX FIXME this should check for a specific master!
BOOST_FOREACH(const string& dbkey, keynames) {
- *keyname=dbkey;
+ *keyname=DNSName(dbkey);
return true;
}
return false;
{
ostringstream o;
// nameservername hostmaster serial-number [refresh [retry [expire [ minimum] ] ] ]
- o<<d.nameserver<<" "<< d.hostmaster <<" "<< d.serial <<" "<< d.refresh << " "<< d.retry << " "<< d.expire << " "<< d.default_ttl;
+ o<<d.nameserver.toString()<<" "<< d.hostmaster.toString() <<" "<< d.serial <<" "<< d.refresh << " "<< d.retry << " "<< d.expire << " "<< d.default_ttl;
return o.str();
}
#include <boost/serialization/string.hpp>
#include <boost/serialization/version.hpp>
#include "qtype.hh"
+#include "dnsname.hh"
#include <time.h>
#include <sys/types.h>
class DNSBackend;
+class DNSName; // FIXME
struct SOAData
{
SOAData() : ttl(0), serial(0), refresh(0), retry(0), expire(0), domain_id(-1), db(0), scopeMask(0) {};
- string qname;
- string nameserver;
- string hostmaster;
+ DNSName qname;
+ DNSName nameserver;
+ DNSName hostmaster;
uint32_t ttl;
uint32_t serial;
uint32_t refresh;
QType qtype; //!< qtype of this record, ie A, CNAME, MX etc
uint16_t qclass; //!< class of this record
- string qname; //!< the name of this record, for example: www.powerdns.com
- string wildcardname;
+ DNSName qname; //!< the name of this record, for example: www.powerdns.com
+ DNSName wildcardname;
string content; //!< what this record points to. Example: 10.1.2.3
uint32_t ttl; //!< Time To Live of this record
uint32_t signttl; //!< If non-zero, use this TTL as original TTL in the RRSIG
#include "dnspacket.hh"
#include "dns.hh"
-bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target, const int best_match_len)
+bool DNSBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len)
{
bool found=false;
- string subdomain(target);
+ DNSName subdomain(target);
do {
- if( best_match_len >= (int)subdomain.length() )
+ if( best_match_len >= (int)subdomain.toString().length() )
break;
if( this->getSOA( subdomain, *sd, p ) ) {
sd->qname = subdomain;
- if(p->qtype.getCode() == QType::DS && pdns_iequals(subdomain, target)) {
+ if(p->qtype.getCode() == QType::DS && subdomain==target) {
// Found authoritative zone but look for parent zone with 'DS' record.
found=true;
} else
return true;
}
}
- while( chopOff( subdomain ) ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
+ while( subdomain.chopOff() ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
return found;
}
\param domain Domain we want to get the SOA details of
\param sd SOAData which is filled with the SOA details
*/
-bool DNSBackend::getSOA(const string &domain, SOAData &sd, DNSPacket *p)
+bool DNSBackend::getSOA(const DNSName &domain, SOAData &sd, DNSPacket *p)
{
this->lookup(QType(QType::SOA),domain,p);
if(!hits)
return false;
sd.qname = domain;
- if(sd.nameserver.empty())
+ if(!sd.nameserver.countLabels())
sd.nameserver=arg()["default-soa-name"];
- if(sd.hostmaster.empty()) {
+ if(!sd.hostmaster.countLabels()) {
if (!arg().isEmpty("default-soa-mail")) {
sd.hostmaster=arg()["default-soa-mail"];
- attodot(sd.hostmaster);
+ // attodot(sd.hostmaster); FIXME
}
else
sd.hostmaster="hostmaster."+domain;
}
if(!sd.serial) { // magic time!
- DLOG(L<<Logger::Warning<<"Doing SOA serial number autocalculation for "<<rr.qname<<endl);
+ DLOG(L<<Logger::Warning<<"Doing SOA serial number autocalculation for "<<rr.qname.toString()<<endl);
time_t serial;
if (calculateSOASerial(domain, sd, serial)) {
sd.serial = serial;
//DLOG(L<<"autocalculated soa serialnumber for "<<rr.qname<<" is "<<newest<<endl);
} else {
- DLOG(L<<"soa serialnumber calculation failed for "<<rr.qname<<endl);
+ DLOG(L<<"soa serialnumber calculation failed for "<<rr.qname.toString()<<endl);
}
}
return true;
}
-bool DNSBackend::getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after)
+bool DNSBackend::getBeforeAndAfterNames(uint32_t id, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after)
{
- string lcqname=toLower(qname);
- string lczonename=toLower(zonename);
- lcqname=makeRelative(lcqname, lczonename);
+ // string lcqname=toLower(qname); FIXME tolower?
+ // string lczonename=toLower(zonename); FIXME tolower?
+ // lcqname=makeRelative(lcqname, lczonename);
- lcqname=labelReverse(lcqname);
- string dnc;
- bool ret = this->getBeforeAndAfterNamesAbsolute(id, lcqname, dnc, before, after);
+ // lcqname=labelReverse(lcqname);
+ DNSName dnc;
+ bool ret = this->getBeforeAndAfterNamesAbsolute(id, qname, dnc, before, after);
- before=dotConcat(labelReverse(before), lczonename);
- after=dotConcat(labelReverse(after), lczonename);
+ // before=dotConcat(labelReverse(before), lczonename); FIXME
+ // after=dotConcat(labelReverse(after), lczonename); FIXME
return ret;
}
* \param sd Information about the SOA record already available
* \param serial Output parameter. Only inspected when we return true
*/
-bool DNSBackend::calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial)
+bool DNSBackend::calculateSOASerial(const DNSName& domain, const SOAData& sd, time_t& serial)
{
// we do this by listing the domain and taking the maximum last modified timestamp
time_t newest=0;
if(!(this->list(domain, sd.domain_id))) {
- DLOG(L<<Logger::Warning<<"Backend error trying to determine magic serial number of zone '"<<domain<<"'"<<endl);
+ DLOG(L<<Logger::Warning<<"Backend error trying to determine magic serial number of zone '"<<domain.toString()<<"'"<<endl);
return false;
}
* presumably quicker to just substring the zone down to size */
soa->qname = inZone.substr( inZone.length() - foundkey.length(), string::npos );
- DLOG(L<<Logger::Error<<"Successfully got record: " <<foundkey << " : " << querykey.substr( 0, foundkey.length() ) << " : " << soa->qname<<endl);
+ DLOG(L<<Logger::Error<<"Successfully got record: " <<foundkey << " : " << querykey.substr( 0, foundkey.length() ) << " : " << soa->qname.toString()<<endl);
return GET_AUTH_SUCCESS;
}
#include <vector>
#include "namespaces.hh"
#include "comment.hh"
+#include "dnsname.hh"
class DNSBackend;
struct DomainInfo
{
DomainInfo() : backend(0) {}
uint32_t id;
- string zone;
+ DNSName zone;
vector<string> masters;
uint32_t notified_serial;
uint32_t serial;
};
struct TSIGKey {
- std::string name;
- std::string algorithm;
+ DNSName name;
+ DNSName algorithm;
std::string key;
};
{
public:
//! lookup() initiates a lookup. A lookup without results should not throw!
- virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
+ virtual void lookup(const QType &qtype, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
//! Initiates a list of the specified domain
if the backend does not consider itself responsible for the id passed.
\param domain_id ID of which a list is requested
*/
- virtual bool list(const string &target, int domain_id, bool include_disabled=false)=0;
+ virtual bool list(const DNSName &target, int domain_id, bool include_disabled=false)=0;
virtual ~DNSBackend(){};
//! fills the soadata struct with the SOA details. Returns false if there is no SOA.
- virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
+ virtual bool getSOA(const DNSName &name, SOAData &soadata, DNSPacket *p=0);
//! Calculates a SOA serial for the zone and stores it in the third argument.
- virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
+ virtual bool calculateSOASerial(const DNSName& domain, const SOAData& sd, time_t& serial);
- virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
+ virtual bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
{
return false;
}
- virtual bool listSubZone(const string &zone, int domain_id)
+ virtual bool listSubZone(const DNSName &zone, int domain_id)
{
return false;
}
bool isDnssecDomainMetadata (const string& name) {
return (name == "PRESIGNED" || name == "NSEC3PARAM" || name == "NSEC3NARROW");
}
- virtual bool getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta) { return false; };
- virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
- virtual bool getDomainMetadataOne(const string& name, const std::string& kind, std::string& value)
+ virtual bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) { return false; };
+ virtual bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
+ virtual bool getDomainMetadataOne(const DNSName& name, const std::string& kind, std::string& value)
{
std::vector<std::string> meta;
if (getDomainMetadata(name, kind, meta)) {
return false;
}
- virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
- virtual bool setDomainMetadataOne(const string& name, const std::string& kind, const std::string& value)
+ virtual bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
+ virtual bool setDomainMetadataOne(const DNSName& name, const std::string& kind, const std::string& value)
{
const std::vector<std::string> meta(1, value);
return setDomainMetadata(name, kind, meta);
virtual void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) { }
/** Determines if we are authoritative for a zone, and at what level */
- virtual bool getAuth(DNSPacket *p, SOAData *sd, const string &target, const int best_match_len);
+ virtual bool getAuth(DNSPacket *p, SOAData *sd, const DNSName &target, const int best_match_len);
struct KeyData {
unsigned int id;
std::string content;
};
- virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) { return false;}
- virtual bool removeDomainKey(const string& name, unsigned int id) { return false; }
- virtual int addDomainKey(const string& name, const KeyData& key){ return -1; }
- virtual bool activateDomainKey(const string& name, unsigned int id) { return false; }
- virtual bool deactivateDomainKey(const string& name, unsigned int id) { return false; }
+ virtual bool getDomainKeys(const DNSName& name, unsigned int kind, std::vector<KeyData>& keys) { return false;}
+ virtual bool removeDomainKey(const DNSName& name, unsigned int id) { return false; }
+ virtual int addDomainKey(const DNSName& name, const KeyData& key){ return -1; }
+ virtual bool activateDomainKey(const DNSName& name, unsigned int id) { return false; }
+ virtual bool deactivateDomainKey(const DNSName& name, unsigned int id) { return false; }
- virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; }
- virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content) { return false; }
- virtual bool deleteTSIGKey(const string& name) { return false; }
+ virtual bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content) { return false; }
+ virtual bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) { return false; }
+ virtual bool deleteTSIGKey(const DNSName& name) { return false; }
virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; }
- virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
+ virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
{
std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl;
abort();
return false;
}
- virtual bool getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after);
+ virtual bool getBeforeAndAfterNames(uint32_t id, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after);
- virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
+ virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const DNSName& zonename, const DNSName& qname, bool auth)
{
return false;
}
- virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth)
+ virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const DNSName& qname, const std::string& ordername, bool auth)
{
return false;
}
- virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
+ virtual bool updateEmptyNonTerminals(uint32_t domain_id, const DNSName& zonename, set<DNSName>& insert, set<DNSName>& erase, bool remove)
{
return false;
}
- virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
+ virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const DNSName& qname, bool auth)
{
return false;
}
- virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type)
+ virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName& qname, const std::string& type)
{
return false;
}
- virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
+ virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const DNSName& qname)
{
return false;
}
{
}
- virtual bool replaceComments(const uint32_t domain_id, const string& qname, const QType& qt, const vector<Comment>& comments)
+ virtual bool replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments)
{
return false;
}
//! returns true if master ip is master for domain name.
- virtual bool isMaster(const string &name, const string &ip)
+ virtual bool isMaster(const DNSName &name, const string &ip)
{
return false;
}
//! starts the transaction for updating domain qname (FIXME: what is id?)
- virtual bool startTransaction(const string &qname, int id=-1)
+ virtual bool startTransaction(const DNSName &qname, int id=-1)
{
return false;
}
{
return false; // no problem!
}
- virtual bool feedEnts(int domain_id, map<string,bool> &nonterm)
+ virtual bool feedEnts(int domain_id, map<DNSName,bool> &nonterm)
{
return false;
}
- virtual bool feedEnts3(int domain_id, const string &domain, map<string,bool> &nonterm, unsigned int times, const string &salt, bool narrow)
+ virtual bool feedEnts3(int domain_id, const DNSName &domain, map<DNSName,bool> &nonterm, unsigned int times, const string &salt, bool narrow)
{
return false;
}
//! if this returns true, DomainInfo di contains information about the domain
- virtual bool getDomainInfo(const string &domain, DomainInfo &di)
+ virtual bool getDomainInfo(const DNSName &domain, DomainInfo &di)
{
return false;
}
}
//! get a list of IP addresses that should also be notified for a domain
- virtual void alsoNotifies(const string &domain, set<string> *ips)
+ virtual void alsoNotifies(const DNSName &domain, set<string> *ips)
{
}
}
//! Called when the Master of a domain should be changed
- virtual bool setMaster(const string &domain, const string &ip)
+ virtual bool setMaster(const DNSName &domain, const string &ip)
{
return false;
}
//! Called when the Kind of a domain should be changed (master -> native and similar)
- virtual bool setKind(const string &domain, const DomainInfo::DomainKind kind)
+ virtual bool setKind(const DNSName &domain, const DomainInfo::DomainKind kind)
{
return false;
}
//! Called when the Account of a domain should be changed
- virtual bool setAccount(const string &domain, const string &account)
+ virtual bool setAccount(const DNSName &domain, const string &account)
{
return false;
}
void setArgPrefix(const string &prefix);
//! determine if ip is a supermaster or a domain
- virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
+ virtual bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
{
return false;
}
//! called by PowerDNS to create a new domain
- virtual bool createDomain(const string &domain)
+ virtual bool createDomain(const DNSName &domain)
{
return false;
}
//! called by PowerDNS to create a slave record for a superMaster
- virtual bool createSlaveDomain(const string &ip, const string &domain, const string &nameserver, const string &account)
+ virtual bool createSlaveDomain(const string &ip, const DNSName &domain, const string &nameserver, const string &account)
{
return false;
}
//! called to delete a domain, incl. all metadata, zone contents, etc.
- virtual bool deleteDomain(const string &domain)
+ virtual bool deleteDomain(const DNSName &domain)
{
return false;
}
//! called to get a NSECx record from backend
- virtual bool getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, string &before, DNSResourceRecord &rr)
+ virtual bool getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, DNSName &before, DNSResourceRecord &rr)
{
return false;
}
//! called to get RRSIG record(s) from backend
- virtual bool getDirectRRSIGs(const string &signer, const string &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs)
+ virtual bool getDirectRRSIGs(const DNSName &signer, const DNSName &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs)
{
return false;
}
#include <set>
#include <deque>
#include <strings.h>
-#include "misc.hh"
+// #include "dns.hh"
// #include <ext/vstring.h>
r->d_haveednssubnet = d_haveednssubnet;
r->d_haveednssection = d_haveednssection;
- if(!d_tsigkeyname.empty()) {
+ if(d_tsigkeyname.countLabels()) {
r->d_tsigkeyname = d_tsigkeyname;
r->d_tsigprevious = d_tsigprevious;
r->d_trc = d_trc;
return 0;
}
-void DNSPacket::setTSIGDetails(const TSIGRecordContent& tr, const string& keyname, const string& secret, const string& previous, bool timersonly)
+void DNSPacket::setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly)
{
d_trc=tr;
d_tsigkeyname = keyname;
d_tsigtimersonly=timersonly;
}
-bool DNSPacket::getTSIGDetails(TSIGRecordContent* trc, string* keyname, string* message) const
+bool DNSPacket::getTSIGDetails(TSIGRecordContent* trc, DNSName* keyname, string* message) const
{
MOADNSParser mdp(d_rawpacket);
gotit=true;
*keyname = i->first.d_label;
- if(!keyname->empty())
- keyname->resize(keyname->size()-1); // drop the trailing dot
}
}
if(!gotit)
return true;
}
-bool DNSPacket::getTKEYRecord(TKEYRecordContent *tr, string *keyname) const
+bool DNSPacket::getTKEYRecord(TKEYRecordContent *tr, DNSName *keyname) const
{
MOADNSParser mdp(d_rawpacket);
bool gotit=false;
d_rawpacket.replace(0,12,(char *)&d,12); // copy in d
}
-bool checkForCorrectTSIG(const DNSPacket* q, UeberBackend* B, string* keyname, string* secret, TSIGRecordContent* trc)
+bool checkForCorrectTSIG(const DNSPacket* q, UeberBackend* B, DNSName* keyname, string* secret, TSIGRecordContent* trc)
{
string message;
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.toString()<<"' 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->toString()<<"') time delta "<< abs(trc->d_time - now)<<" > 'fudge' "<<trc->d_fudge<<endl;
return false;
}
- string algoName = trc->d_algoName.toString(); // FIXME
- if (algoName == "hmac-md5.sig-alg.reg.int")
- algoName = "hmac-md5";
+ DNSName algoName = trc->d_algoName; // FIXME
+ if (algoName == DNSName("hmac-md5.sig-alg.reg.int"))
+ algoName = DNSName("hmac-md5");
if (algoName == "gss-tsig") {
if (!gss_verify_signature(*keyname, message, trc->d_mac)) {
string secret64;
if(!B->getTSIGKey(*keyname, &algoName, &secret64)) {
- L<<Logger::Error<<"Packet for domain '"<<q->qdomain.toString()<<"' 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->toString()<<"' and algorithm '"<<algoName.toString()<<"'"<<endl;
return false;
}
- if (trc->d_algoName == "hmac-md5")
- trc->d_algoName += ".sig-alg.reg.int.";
+ if (trc->d_algoName == DNSName("hmac-md5"))
+ trc->d_algoName += DNSName("sig-alg.reg.int.");
TSIGHashEnum algo;
if(!getTSIGHashEnum(trc->d_algoName, algo)) {
B64Decode(secret64, *secret);
bool result=calculateHMAC(*secret, message, algo) == trc->d_mac;
if(!result) {
- L<<Logger::Error<<"Packet for domain '"<<q->qdomain.toString()<<"' denied: TSIG signature mismatch using '"<<*keyname<<"' and algorithm '"<<trc->d_algoName.toString()<<"'"<<endl;
+ L<<Logger::Error<<"Packet for domain '"<<q->qdomain.toString()<<"' denied: TSIG signature mismatch using '"<<keyname->toString()<<"' and algorithm '"<<trc->d_algoName.toString()<<"'"<<endl;
}
return result;
string d_peer_principal;
TSIGHashEnum d_tsig_algo;
- bool getTSIGDetails(TSIGRecordContent* tr, string* keyname, string* message) const;
- void setTSIGDetails(const TSIGRecordContent& tr, const string& keyname, const string& secret, const string& previous, bool timersonly=false);
- bool getTKEYRecord(TKEYRecordContent* tr, string* keyname) const;
+ bool getTSIGDetails(TSIGRecordContent* tr, DNSName* keyname, string* message) const;
+ void setTSIGDetails(const TSIGRecordContent& tr, const DNSName& keyname, const string& secret, const string& previous, bool timersonly=false);
+ bool getTKEYRecord(TKEYRecordContent* tr, DNSName* keyname) const;
vector<DNSResourceRecord>& getRRS() { return d_rrs; }
TSIGRecordContent d_trc;
bool d_haveednssection;
EDNSSubnetOpts d_eso;
string d_tsigsecret;
- string d_tsigkeyname;
+ DNSName d_tsigkeyname;
string d_tsigprevious;
bool d_tsigtimersonly;
virtual std::string getZoneRepresentation() const = 0;
virtual ~DNSRecordContent() {}
virtual void toPacket(DNSPacketWriter& pw)=0;
- virtual string serialize(const string& qname, bool canonic=false, bool lowerCase=false) // it would rock if this were const, but it is too hard
+ virtual string serialize(const DNSName& qname, bool canonic=false, bool lowerCase=false) // it would rock if this were const, but it is too hard
{
vector<uint8_t> packet;
string empty;
string lcontent=toLower(content);
string rcontent=toLower(rhs.content);
- string llabel=toLower(qname);
- string rlabel=toLower(rhs.qname);
-
return
- tie(llabel, qtype, lcontent, ttl) ==
- tie(rlabel, rhs.qtype, rcontent, rhs.ttl);
+ tie(qname, qtype, lcontent, ttl) ==
+ tie(rhs.qname, rhs.qtype, rcontent, rhs.ttl);
}
auth=true;
disabled=false;
qname = p.d_label;
- if(!qname.empty())
- boost::erase_tail(qname, 1); // strip .
+ // if(!qname.empty())
+ // boost::erase_tail(qname, 1); // strip .
qtype = p.d_type;
ttl = p.d_ttl;
return now;
}
-std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const std::string& qname)
+std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const DNSName& qname)
{
string toHash;
- toHash.assign(simpleCompress(toLower(qname)));
+ toHash.assign(qname.toDNSString());
toHash.append(salt);
// cerr<<makeHexDump(toHash)<<endl;
};
bool sharedDNSSECCompare(const std::shared_ptr<DNSRecordContent>& a, const shared_ptr<DNSRecordContent>& b);
-string getMessageForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, std::vector<std::shared_ptr<DNSRecordContent> >& signRecords);
+string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, std::vector<std::shared_ptr<DNSRecordContent> >& signRecords);
-DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordContent& drc, int digest=1);
+DSRecordContent makeDSFromDNSKey(const DNSName& qname, const DNSKEYRecordContent& drc, int digest=1);
-int countLabels(const std::string& signQName);
-
class RSAContext;
class DNSSECKeeper;
struct DNSSECPrivateKey;
-void fillOutRRSIG(DNSSECPrivateKey& dpk, const std::string& signQName, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& toSign);
+void fillOutRRSIG(DNSSECPrivateKey& dpk, const DNSName& signQName, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& toSign);
uint32_t getStartOfWeek();
-void addSignature(DNSSECKeeper& dk, UeberBackend& db, const std::string& signer, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace,
+void addSignature(DNSSECKeeper& dk, UeberBackend& db, const DNSName& signer, const DNSName signQName, const DNSName& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace,
vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned, uint32_t origTTL);
-int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL,
+int getRRSIGsForRRSET(DNSSECKeeper& dk, const DNSName& signer, const DNSName signQName, uint16_t signQType, uint32_t signTTL,
vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent> &rrc);
-std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const std::string& qname);
+std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const DNSName& qname);
void decodeDERIntegerSequence(const std::string& input, vector<string>& output);
class DNSPacket;
void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const std::set<string, CIStringCompare>& authMap, vector<DNSResourceRecord>& rrs);
if(d_ourDB)
delete d_keymetadb;
}
- bool isSecuredZone(const std::string& zone);
+ bool isSecuredZone(const DNSName& zone);
static uint64_t dbdnssecCacheSizes(const std::string& str);
- keyset_t getKeys(const std::string& zone, boost::tribool allOrKeyOrZone = boost::indeterminate, bool useCache = true);
- DNSSECPrivateKey getKeyById(const std::string& zone, unsigned int id);
- bool addKey(const std::string& zname, bool keyOrZone, int algorithm=5, int bits=0, bool active=true);
- bool addKey(const std::string& zname, const DNSSECPrivateKey& dpk, bool active=true);
- bool removeKey(const std::string& zname, unsigned int id);
- bool activateKey(const std::string& zname, unsigned int id);
- bool deactivateKey(const std::string& zname, unsigned int id);
-
- bool secureZone(const std::string& fname, int algorithm, int size);
-
- bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
- bool setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
- bool unsetNSEC3PARAM(const std::string& zname);
+ keyset_t getKeys(const DNSName& zone, boost::tribool allOrKeyOrZone = boost::indeterminate, bool useCache = true);
+ DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id);
+ bool addKey(const DNSName& zname, bool keyOrZone, int algorithm=5, int bits=0, bool active=true);
+ bool addKey(const DNSName& zname, const DNSSECPrivateKey& dpk, bool active=true);
+ bool removeKey(const DNSName& zname, unsigned int id);
+ bool activateKey(const DNSName& zname, unsigned int id);
+ bool deactivateKey(const DNSName& zname, unsigned int id);
+
+ bool secureZone(const DNSName& fname, int algorithm, int size);
+
+ bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
+ bool setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
+ bool unsetNSEC3PARAM(const DNSName& zname);
void clearAllCaches();
- void clearCaches(const std::string& name);
- bool getPreRRSIGs(UeberBackend& db, const std::string& signer, const std::string& qname, const std::string& wildcardname, const QType& qtype, DNSPacketWriter::Place, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL);
- bool isPresigned(const std::string& zname);
- bool setPresigned(const std::string& zname);
- bool unsetPresigned(const std::string& zname);
-
- bool TSIGGrantsAccess(const string& zone, const string& keyname);
- bool getTSIGForAccess(const string& zone, const string& master, string* keyname);
+ void clearCaches(const DNSName& name);
+ bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSPacketWriter::Place, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL);
+ bool isPresigned(const DNSName& zname);
+ bool setPresigned(const DNSName& zname);
+ bool unsetPresigned(const DNSName& zname);
+
+ bool TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname);
+ bool getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname);
void startTransaction()
{
(*d_keymetadb->backends.begin())->commitTransaction();
}
- void getFromMeta(const std::string& zname, const std::string& key, std::string& value);
+ void getFromMeta(const DNSName& zname, const std::string& key, std::string& value);
private:
return d_ttd;
}
- string d_domain;
+ DNSName d_domain;
unsigned int d_ttd;
mutable keys_t d_keys;
};
return d_ttd;
}
- string d_domain;
+ DNSName d_domain;
unsigned int d_ttd;
mutable std::string d_key, d_value;
typedef multi_index_container<
KeyCacheEntry,
indexed_by<
- ordered_unique<member<KeyCacheEntry, std::string, &KeyCacheEntry::d_domain>, CIStringCompare >,
+ ordered_unique<member<KeyCacheEntry, DNSName, &KeyCacheEntry::d_domain> >,
sequenced<>
>
> keycache_t;
ordered_unique<
composite_key<
METACacheEntry,
- member<METACacheEntry, std::string, &METACacheEntry::d_domain> ,
+ member<METACacheEntry, DNSName, &METACacheEntry::d_domain> ,
member<METACacheEntry, std::string, &METACacheEntry::d_key>
- >, composite_key_compare<CIStringCompare, CIStringCompare> >,
+ >, composite_key_compare<std::less<DNSName>, CIStringCompare> >,
sequenced<>
>
> metacache_t;
uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
// for SOA-EDIT
uint32_t calculateEditSOA(SOAData sd, const string& kind);
-bool editSOA(DNSSECKeeper& dk, const string& qname, DNSPacket* dp);
+bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp);
bool editSOARecord(DNSResourceRecord& rr, const string& kind);
// for SOA-EDIT-DNSUPDATE/API
uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind);
/* 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,
+int getRRSIGsForRRSET(DNSSECKeeper& dk, const DNSName& signer, const DNSName signQName, uint16_t signQType, uint32_t signTTL,
vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs)
{
if(toSign.empty())
RRSIGRecordContent rrc;
rrc.d_type=signQType;
- rrc.d_labels=countLabels(signQName);
+ rrc.d_labels=signQName.countLabels();
rrc.d_originalttl=signTTL;
rrc.d_siginception=startOfWeek - 7*86400; // XXX should come from zone metadata
rrc.d_sigexpire=startOfWeek + 14*86400;
- rrc.d_signer = signer.empty() ? "." : toLower(signer);
+ rrc.d_signer = signer;
rrc.d_tag = 0;
// we sign the RRSET in toSign + the rrc w/o hash
}
// this is the entrypoint from DNSPacket
-void addSignature(DNSSECKeeper& dk, UeberBackend& db, const std::string& signer, const std::string signQName, const std::string& wildcardname, uint16_t signQType,
+void addSignature(DNSSECKeeper& dk, UeberBackend& db, const DNSName& signer, const DNSName signQName, const DNSName& wildcardname, uint16_t signQType,
uint32_t signTTL, DNSPacketWriter::Place signPlace,
vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned, uint32_t origTTL)
{
dk.getPreRRSIGs(db, signer, signQName, wildcardname, QType(signQType), signPlace, outsigned, origTTL); // does it all
}
else {
- if(getRRSIGsForRRSET(dk, signer, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs) < 0) {
+ if(getRRSIGsForRRSET(dk, signer, wildcardname.countLabels() ? wildcardname : signQName, signQType, signTTL, toSign, rrcs) < 0) {
// cerr<<"Error signing a record!"<<endl;
return;
}
return tie(a.d_place, a.qtype) < tie(b.d_place, b.qtype);
}
-static bool getBestAuthFromSet(const set<string, CIStringCompare>& authSet, const string& name, string& auth)
+static bool getBestAuthFromSet(const set<DNSName>& authSet, const DNSName& name, DNSName& auth)
{
- auth.clear();
- string sname(name);
+ auth.trimToLabels(0);
+ DNSName sname(name);
do {
if(authSet.find(sname) != authSet.end()) {
auth = sname;
return true;
}
}
- while(chopOff(sname));
+ while(sname.chopOff());
return false;
}
-void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<string, CIStringCompare>& authSet, vector<DNSResourceRecord>& rrs)
+void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set<DNSName>& authSet, vector<DNSResourceRecord>& rrs)
{
stable_sort(rrs.begin(), rrs.end(), rrsigncomp);
- string signQName, wildcardQName;
+ DNSName signQName, wildcardQName;
uint16_t signQType=0;
uint32_t signTTL=0;
uint32_t origTTL=0;
vector<DNSResourceRecord> signedRecords;
- string signer;
+ DNSName signer;
for(vector<DNSResourceRecord>::const_iterator pos = rrs.begin(); pos != rrs.end(); ++pos) {
if(pos != rrs.begin() && (signQType != pos->qtype.getCode() || signQName != pos->qname)) {
if(getBestAuthFromSet(authSet, signQName, signer))
for (vector<DomainInfo>::const_iterator di=domains.begin(); di != domains.end(); di++) {
if (di->kind == kindFilter || kindFilter == -1) {
- ret<<di->zone<<endl;
+ ret<<di->zone.toString()<<endl;
count++;
}
}
for(set<string>::const_iterator j=nsset.begin();j!=nsset.end();++j) {
vector<string> nsips=fns.lookup(*j, B);
if(nsips.empty())
- L<<Logger::Warning<<"Unable to queue notification of domain '"<<domain<<"': nameservers do not resolve!"<<endl;
+ L<<Logger::Warning<<"Unable to queue notification of domain '"<<domain.toString()<<"': nameservers do not resolve!"<<endl;
else
for(vector<string>::const_iterator k=nsips.begin();k!=nsips.end();++k) {
const ComboAddress caIp(*k, 53);
if(!d_preventSelfNotification || !AddressIsUs(caIp)) {
if(!d_onlyNotify.match(&caIp))
- L<<Logger::Info<<"Skipped notification of domain '"<<domain<<"' to "<<*j<<" because it does not match only-notify."<<endl;
+ L<<Logger::Info<<"Skipped notification of domain '"<<domain.toString()<<"' to "<<*j<<" because it does not match only-notify."<<endl;
else
ips.insert(caIp.toStringWithPort());
}
}
for(set<string>::const_iterator j=ips.begin();j!=ips.end();++j) {
- L<<Logger::Warning<<"Queued notification of domain '"<<domain<<"' to "<<*j<<endl;
+ L<<Logger::Warning<<"Queued notification of domain '"<<domain.toString()<<"' to "<<*j<<endl;
d_nq.add(domain,*j);
hasQueuedItem=true;
}
for(set<string>::const_iterator j=alsoNotify.begin();j!=alsoNotify.end();++j) {
try {
const ComboAddress caIp(*j, 53);
- L<<Logger::Warning<<"Queued also-notification of domain '"<<domain<<"' to "<<caIp.toStringWithPort()<<endl;
+ L<<Logger::Warning<<"Queued also-notification of domain '"<<domain.toString()<<"' to "<<caIp.toStringWithPort()<<endl;
if (!ips.count(caIp.toStringWithPort())) {
ips.insert(caIp.toStringWithPort());
d_nq.add(domain, caIp.toStringWithPort());
hasQueuedItem=true;
}
catch(PDNSException &e) {
- L<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<domain<<"'. Warning: "<<e.reason<<endl;
+ L<<Logger::Warning<<"Unparseable IP in ALSO-NOTIFY metadata of domain '"<<domain.toString()<<"'. Warning: "<<e.reason<<endl;
}
}
if (!hasQueuedItem)
- L<<Logger::Warning<<"Request to queue notification for domain '"<<domain<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
+ L<<Logger::Warning<<"Request to queue notification for domain '"<<domain.toString()<<"' was processed, but no valid nameservers or ALSO-NOTIFYs found. Not notifying!"<<endl;
}
DomainInfo di;
UeberBackend B;
if(!B.getDomainInfo(domain, di)) {
- L<<Logger::Error<<"No such domain '"<<domain<<"' in our database"<<endl;
+ L<<Logger::Error<<"No such domain '"<<domain.toString()<<"' in our database"<<endl;
return false;
}
queueNotifyDomain(domain, &B);
{
cerr<<"Waiting for notification responses: "<<endl;
BOOST_FOREACH(NotificationRequest& nr, d_nqueue) {
- cerr<<nr.domain<<", "<<nr.ip<<endl;
+ cerr<<nr.domain.toString()<<", "<<nr.ip<<endl;
}
}
for(vector<DomainInfo>::const_iterator i=cmdomains.begin();i!=cmdomains.end();++i) {
extern PacketCache PC;
- PC.purge(i->zone); // fixes cvstrac ticket #30
+ PC.purge(i->zone.toString()); // fixes cvstrac ticket #30
queueNotifyDomain(i->zone,P->getBackend());
i->backend->setNotified(i->id,i->serial);
}
}
// send out possible new notifications
- string domain, ip;
+ DNSName domain;
+ string ip;
uint16_t id;
bool purged;
drillHole(domain, ip);
}
catch(ResolverException &re) {
- L<<Logger::Error<<"Error trying to resolve '"+ip+"' for notifying '"+domain+"' to server: "+re.reason<<endl;
+ L<<Logger::Error<<"Error trying to resolve '"+ip+"' for notifying '"+domain.toString()+"' to server: "+re.reason<<endl;
}
}
else
- L<<Logger::Error<<Logger::NTLog<<"Notification for "<<domain<<" to "<<ip<<" failed after retries"<<endl;
+ L<<Logger::Error<<Logger::NTLog<<"Notification for "<<domain.toString()<<" to "<<ip<<" failed after retries"<<endl;
}
return d_nq.earliest();
}
-void CommunicatorClass::sendNotification(int sock, const string& domain, const ComboAddress& remote, uint16_t id)
+void CommunicatorClass::sendNotification(int sock, const DNSName& domain, const ComboAddress& remote, uint16_t id)
{
vector<uint8_t> packet;
DNSPacketWriter pw(packet, domain, QType::SOA, 1, Opcode::Notify);
return true;
}
+// FIXME remove this
+inline bool pdns_iequals(const DNSName& a, const DNSName& b) __attribute__((pure));
+inline bool pdns_iequals(const DNSName& a, const DNSName& b)
+{
+ return a==b;
+}
+
inline bool pdns_iequals_ch(const char a, const char b) __attribute__((pure));
inline bool pdns_iequals_ch(const char a, const char b)
{
return dom[dom.size()-1]=='.';
}
+inline string toCanonic(const DNSName& zone, const string& domain)
+{
+ return toCanonic(zone.toString(), domain);
+}
+
inline string toCanonic(const string& zone, const string& domain)
{
if(domain.length()==1 && domain[0]=='@')
string value;
bool haveSomething;
{
- MapCombo& mc=getMap(pcReverse(p->qdomain.toString())); // FIXME
+ MapCombo& mc=getMap(pcReverse(p->qdomain));
TryReadLock l(&mc.d_mut); // take a readlock here
if(!l.gotIt()) {
S.inc("deferred-cache-lookup");
}
// universal key appears to be: qname, qtype, kind (packet, query cache), optionally zoneid, meritsRecursion
-void PacketCache::insert(const string &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID,
+void PacketCache::insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID,
bool meritsRecursion, unsigned int maxReplyLen, bool dnssecOk, bool EDNS)
{
if(!((++d_ops) % 300000)) {
return delcount;
}
// called from ueberbackend
-bool PacketCache::getEntry(const string &qname, const QType& qtype, CacheEntryType cet, string& value, int zoneID, bool meritsRecursion,
+bool PacketCache::getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, string& value, int zoneID, bool meritsRecursion,
unsigned int maxReplyLen, bool dnssecOk, bool hasEDNS, unsigned int *age)
{
if(d_ttl<0)
}
-bool PacketCache::getEntryLocked(const string &qname, const QType& qtype, CacheEntryType cet, string& value, int zoneID, bool meritsRecursion,
+bool PacketCache::getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, string& value, int zoneID, bool meritsRecursion,
unsigned int maxReplyLen, bool dnssecOK, bool hasEDNS, unsigned int *age)
{
uint16_t qt = qtype.getCode();
}
-string PacketCache::pcReverse(const string &content)
+string PacketCache::pcReverse(const DNSName &DNcontent)
{
typedef vector<pair<unsigned int, unsigned int> > parts_t;
parts_t parts;
+ string content = DNcontent.toString();
vstringtok(parts,toLower(content), ".");
string ret;
ret.reserve(content.size()+1);
void insert(DNSPacket *q, DNSPacket *r, bool recursive, unsigned int maxttl=UINT_MAX); //!< We copy the contents of *p into our cache. Do not needlessly call this to insert questions already in the cache as it wastes resources
- void insert(const string &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID=-1, bool meritsRecursion=false,
+ void insert(const DNSName &qname, const QType& qtype, CacheEntryType cet, const string& value, unsigned int ttl, int zoneID=-1, bool meritsRecursion=false,
unsigned int maxReplyLen=512, bool dnssecOk=false, bool EDNS=false);
int get(DNSPacket *p, DNSPacket *q, bool recursive); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method.
- bool getEntry(const string &content, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
+ bool getEntry(const DNSName &qname, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
bool meritsRecursion=false, unsigned int maxReplyLen=512, bool dnssecOk=false, bool hasEDNS=false, unsigned int *age=0);
int size(); //!< number of entries in the cache
map<char,int> getCounts();
private:
- bool getEntryLocked(const string &content, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
+ bool getEntryLocked(const DNSName &qname, const QType& qtype, CacheEntryType cet, string& entry, int zoneID=-1,
bool meritsRecursion=false, unsigned int maxReplyLen=512, bool dnssecOk=false, bool hasEDNS=false, unsigned int *age=0);
- string pcReverse(const string &content);
+ string pcReverse(const DNSName &content);
struct CacheEntry
{
CacheEntry() { qtype = ctype = 0; zoneID = -1; meritsRecursion=false; dnssecOk=false; hasEDNS=false;}
// This is our chaos class requests handler. Return 1 if content was added, 0 if it wasn't
-int PacketHandler::doChaosRequest(DNSPacket *p, DNSPacket *r, string &target)
+int PacketHandler::doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target)
{
DNSResourceRecord rr;
return 0;
}
-vector<DNSResourceRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const string &target)
+vector<DNSResourceRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target)
{
vector<DNSResourceRecord> ret;
DNSResourceRecord rr;
- string subdomain(target);
+ DNSName subdomain(target);
do {
if(subdomain == sd.qname) // stop at SOA
break;
}
if(!ret.empty())
return ret;
- } while( chopOff( subdomain ) ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
+ } while( subdomain.chopOff() ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
return ret;
}
-vector<DNSResourceRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, string &target)
+vector<DNSResourceRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target)
{
vector<DNSResourceRecord> ret;
DNSResourceRecord rr;
string prefix;
- string subdomain(target);
+ DNSName subdomain(target);
do {
- DLOG(L<<"Attempting DNAME lookup for "<<subdomain<<", sd.qname="<<sd.qname<<endl);
+ DLOG(L<<"Attempting DNAME lookup for "<<subdomain.toString()<<", sd.qname="<<sd.qname.toString()<<endl);
B.lookup(QType(QType::DNAME), subdomain, p, sd.domain_id);
while(B.get(rr)) {
if(subdomain == sd.qname) // stop at SOA
break;
- } while( chopOff( subdomain ) ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
+ } while( subdomain.chopOff() ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
return ret;
}
// Return best matching wildcard or next closer name
-bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const string &target, string &wildcard, vector<DNSResourceRecord>* ret)
+bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSResourceRecord>* ret)
{
ret->clear();
DNSResourceRecord rr;
- string subdomain(target);
+ DNSName subdomain(target);
bool haveSomething=false;
wildcard=subdomain;
- while( chopOff( subdomain ) && !haveSomething ) {
+ while( subdomain.chopOff() && !haveSomething ) {
if (subdomain.empty()) {
B.lookup(QType(QType::ANY), "*", p, sd.domain_id);
} else {
// we now have a copy, push_back on packet might reallocate!
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) && !retargeted) { // drop AA in case of non-SOA-level NS answer, except for root referral
+ if(r->d.aa && i->qname.countLabels() && i->qtype.getCode()==QType::NS && !B.getSOA(i->qname,sd,p) && !retargeted) { // drop AA in case of non-SOA-level NS answer, except for root referral
r->setA(false);
// i->d_place=DNSResourceRecord::AUTHORITY; // XXX FIXME
}
}
while(B.get(rr)) {
if(rr.domain_id!=i->domain_id && ::arg()["out-of-zone-additional-processing"]=="no") {
- DLOG(L<<Logger::Warning<<"Not including out-of-zone additional processing of "<<i->qname<<" ("<<rr.qname<<")"<<endl);
+ DLOG(L<<Logger::Warning<<"Not including out-of-zone additional processing of "<<i->qname.toString()<<" ("<<rr.qname.toString()<<")"<<endl);
continue; // not adding out-of-zone additional data
}
- if(rr.auth && !endsOn(rr.qname, soadata.qname)) // don't sign out of zone data using the main key
+ if(rr.auth && !rr.qname.isPartOf(soadata.qname)) // don't sign out of zone data using the main key
rr.auth=false;
rr.d_place=DNSResourceRecord::ADDITIONAL;
r->addRecord(rr);
}
-void PacketHandler::emitNSEC(const std::string& begin, const std::string& end, const std::string& toNSEC, const SOAData& sd, DNSPacket *r, int mode)
+void PacketHandler::emitNSEC(const DNSName& begin, const DNSName& end, const DNSName& toNSEC, const SOAData& sd, DNSPacket *r, int mode)
{
// cerr<<"We should emit '"<<begin<<"' - ('"<<toNSEC<<"') - '"<<end<<"'"<<endl;
NSECRecordContent nrc;
r->addRecord(rr);
}
-void emitNSEC3(UeberBackend& B, const NSEC3PARAMRecordContent& ns3prc, const SOAData& sd, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode)
+void emitNSEC3(UeberBackend& B, const NSEC3PARAMRecordContent& ns3prc, const SOAData& sd, const DNSName& unhashed, const DNSName& begin, const DNSName& end, const DNSName& toNSEC3, DNSPacket *r, int mode)
{
// cerr<<"We should emit NSEC3 '"<<toBase32Hex(begin)<<"' - ('"<<toNSEC3<<"') - '"<<toBase32Hex(end)<<"' (unhashed: '"<<unhashed<<"')"<<endl;
NSEC3RecordContent n3rc;
n3rc.d_algorithm = 1; // SHA1, fixed in PowerDNS for now
DNSResourceRecord rr;
- if(!unhashed.empty()) {
+ if(unhashed.countLabels()) {
B.lookup(QType(QType::ANY), unhashed, NULL, sd.domain_id);
while(B.get(rr)) {
if(rr.qtype.getCode() && (rr.qtype.getCode() == QType::NS || rr.auth)) // skip empty non-terminals
r->addRecord(rr);
}
-void PacketHandler::emitNSEC3(const NSEC3PARAMRecordContent& ns3prc, const SOAData& sd, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode)
+void PacketHandler::emitNSEC3(const NSEC3PARAMRecordContent& ns3prc, const SOAData& sd, const DNSName& unhashed, const DNSName& begin, const DNSName& end, const DNSName& toNSEC3, DNSPacket *r, int mode)
{
::emitNSEC3(B, ns3prc, sd, unhashed, begin, end, toNSEC3, r, mode);
mode 4 = Name Error Responses
mode 5 = Direct NSEC request
*/
-void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, const string& wildcard, const string& auth, int mode)
+void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, int mode)
{
if(!p->d_dnssecOk && mode != 5)
return;
return ret;
}
-void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd)
+void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd)
{
DNSResourceRecord rr;
rr.qname=sd.qname;
r->setRcode(RCode::NXDomain);
}
-void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd, int mode)
+void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd, int mode)
{
DNSResourceRecord rr;
rr.qname=sd.qname;
}
-bool PacketHandler::addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const string& dsname)
+bool PacketHandler::addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DNSName& dsname)
{
//cerr<<"Trying to find a DS for '"<<dsname<<"', domain_id = "<<sd.domain_id<<endl;
B.lookup(QType(QType::DS), dsname, p, sd.domain_id);
return gotOne;
}
-bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target, bool retargeted)
+bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target, bool retargeted)
{
vector<DNSResourceRecord> rrset = getBestReferralNS(p, sd, target);
if(rrset.empty())
return true;
}
-void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target)
+void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target)
{
if(!p->d_dnssecOk)
return; // Don't send dnssec info to non validating resolvers.
}
}
-bool PacketHandler::tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target)
+bool PacketHandler::tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target)
{
if(!d_doDNAME)
return false;
}
return false;
}
-bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata)
+bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata)
{
retargeted = nodata = false;
string bestmatch;
string subdomain="";
string soa;
int retargetcount=0;
- set<string, CIStringCompare> authSet;
+ set<DNSName> authSet;
vector<DNSResourceRecord> rrset;
bool weDone=0, weRedirected=0, weHaveUnauth=0;
int trySuperMaster(DNSPacket *p);
int processNotify(DNSPacket *);
void addRootReferral(DNSPacket *r);
- int doChaosRequest(DNSPacket *p, DNSPacket *r, string &target);
+ int doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target);
bool addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd);
bool addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd);
int doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& sd, bool retargeted);
- void addNSECX(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string &auth, int mode);
- void addNSEC(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string& auth, int mode);
- void addNSEC3(DNSPacket *p, DNSPacket* r, const string &target, const string &wildcard, const std::string& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
- void emitNSEC(const std::string& before, const std::string& after, const std::string& toNSEC, const SOAData& sd, DNSPacket *r, int mode);
- void emitNSEC3(const NSEC3PARAMRecordContent &ns3rc, const SOAData& sd, const std::string& unhashed, const std::string& begin, const std::string& end, const std::string& toNSEC3, DNSPacket *r, int mode);
+ void addNSECX(DNSPacket *p, DNSPacket* r, const DNSName &target, const DNSName &wildcard, const DNSName &auth, int mode);
+ void addNSEC(DNSPacket *p, DNSPacket* r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, int mode);
+ void addNSEC3(DNSPacket *p, DNSPacket* r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
+ void emitNSEC(const DNSName& before, const DNSName& after, const DNSName& toNSEC, const SOAData& sd, DNSPacket *r, int mode);
+ void emitNSEC3(const NSEC3PARAMRecordContent &ns3rc, const SOAData& sd, const DNSName& unhashed, const DNSName& begin, const DNSName& end, const DNSName& toNSEC3, DNSPacket *r, int mode);
int processUpdate(DNSPacket *p);
int forwardPacket(const string &msgPrefix, DNSPacket *p, DomainInfo *di);
uint performUpdate(const string &msgPrefix, const DNSRecord *rr, DomainInfo *di, bool isPresigned, bool* narrow, bool* haveNSEC3, NSEC3PARAMRecordContent *ns3pr, bool *updatedSerial);
int checkUpdatePrerequisites(const DNSRecord *rr, DomainInfo *di);
void increaseSerial(const string &msgPrefix, const DomainInfo *di, bool haveNSEC3, bool narrow, const NSEC3PARAMRecordContent *ns3pr);
- void makeNXDomain(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd);
- void makeNOError(DNSPacket* p, DNSPacket* r, const std::string& target, const std::string& wildcard, SOAData& sd, int mode);
- vector<DNSResourceRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const string &target);
- vector<DNSResourceRecord> getBestDNAMESynth(DNSPacket *p, SOAData& sd, string &target);
- bool tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target);
- bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target, bool retargeted);
-
- bool getBestWildcard(DNSPacket *p, SOAData& sd, const string &target, string &wildcard, vector<DNSResourceRecord>* ret);
- bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, string &target, string &wildcard, bool& retargeted, bool& nodata);
- bool addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const string& dsname);
- void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const string &target);
+ void makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd);
+ void makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, SOAData& sd, int mode);
+ vector<DNSResourceRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target);
+ vector<DNSResourceRecord> getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target);
+ bool tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target);
+ bool tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target, bool retargeted);
+
+ bool getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSResourceRecord>* ret);
+ bool tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata);
+ bool addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DNSName& dsname);
+ void completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target);
void tkeyHandler(DNSPacket *p, DNSPacket *r); //<! process TKEY record, and adds TKEY record to (r)eply, or error code.
// irritatingly enough, rectifyZone needs its own ueberbackend and can't therefore benefit from transactions outside its scope
// I think this has to do with interlocking transactions between B and DK, but unsure.
-bool rectifyZone(DNSSECKeeper& dk, const std::string& zone)
+bool rectifyZone(DNSSECKeeper& dk, const DNSName& zone)
{
if(dk.isPresigned(zone)){
- cerr<<"Rectify presigned zone '"<<zone<<"' is not allowed/necessary."<<endl;
+ cerr<<"Rectify presigned zone '"<<zone.toString()<<"' is not allowed/necessary."<<endl;
return false;
}
SOAData sd;
if(!B.getSOAUncached(zone, sd)) {
- cerr<<"No SOA known for '"<<zone<<"', is such a zone in the database?"<<endl;
+ cerr<<"No SOA known for '"<<zone.toString()<<"', is such a zone in the database?"<<endl;
return false;
}
sd.db->list(zone, sd.domain_id);
DNSResourceRecord rr;
- set<string> qnames, nsset, dsnames, insnonterm, delnonterm;
- map<string,bool> nonterm;
+ set<DNSName> qnames, nsset, dsnames, insnonterm, delnonterm;
+ map<DNSName,bool> nonterm;
bool doent=true;
while(sd.db->get(rr)) {
if (rr.qtype.getCode())
{
qnames.insert(rr.qname);
- if(rr.qtype.getCode() == QType::NS && !pdns_iequals(rr.qname, zone))
+ if(rr.qtype.getCode() == QType::NS && rr.qname!=zone)
nsset.insert(rr.qname);
if(rr.qtype.getCode() == QType::DS)
dsnames.insert(rr.qname);
cerr<<"Adding NSEC ordering information "<<endl;
else if(!narrow) {
if(!isOptOut)
- cerr<<"Adding NSEC3 hashed ordering information for '"<<zone<<"'"<<endl;
+ cerr<<"Adding NSEC3 hashed ordering information for '"<<zone.toString()<<"'"<<endl;
else
- cerr<<"Adding NSEC3 opt-out hashed ordering information for '"<<zone<<"'"<<endl;
+ cerr<<"Adding NSEC3 opt-out hashed ordering information for '"<<zone.toString()<<"'"<<endl;
} else
cerr<<"Erasing NSEC3 ordering since we are narrow, only setting 'auth' fields"<<endl;
}
uint32_t maxent = ::arg().asNum("max-ent-entries");
dononterm:;
- BOOST_FOREACH(const string& qname, qnames)
+ BOOST_FOREACH(const DNSName& qname, qnames)
{
bool auth=true;
- string shorter(qname);
+ DNSName shorter(qname);
if(realrr) {
do {
auth=false;
break;
}
- } while(chopOff(shorter));
+ } while(shorter.chopOff());
}
if(haveNSEC3)
if(!narrow && (realrr || !isOptOut || nonterm.find(qname)->second)) {
hashed=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, qname));
if(g_verbose)
- cerr<<"'"<<qname<<"' -> '"<< hashed <<"'"<<endl;
+ cerr<<"'"<<qname.toString()<<"' -> '"<< hashed <<"'"<<endl;
sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, qname, hashed, auth);
}
else {
if(doent)
{
shorter=qname;
- while(!pdns_iequals(shorter, zone) && chopOff(shorter))
+ while(shorter!=zone && shorter.chopOff())
{
if(!qnames.count(shorter))
{
if(!(maxent))
{
- cerr<<"Zone '"<<zone<<"' has too many empty non terminals."<<endl;
+ cerr<<"Zone '"<<zone.toString()<<"' has too many empty non terminals."<<endl;
insnonterm.clear();
delnonterm.clear();
doent=false;
delnonterm.erase(shorter);
if (!nonterm.count(shorter)) {
- nonterm.insert(pair<string, bool>(shorter, auth));
+ nonterm.insert(pair<DNSName, bool>(shorter, auth));
--maxent;
} else if (auth)
nonterm[shorter]=true;
{
realrr=false;
qnames.clear();
- pair<string,bool> nt;
+ pair<DNSName,bool> nt;
BOOST_FOREACH(nt, nonterm){
qnames.insert(nt.first);
}
B.getAllDomains(&domainInfo);
BOOST_FOREACH(DomainInfo di, domainInfo) {
- cerr<<"Rectifying "<<di.zone<<": ";
+ cerr<<"Rectifying "<<di.zone.toString()<<": ";
rectifyZone(dk, di.zone);
}
cout<<"Rectified "<<domainInfo.size()<<" zones."<<endl;
}
-int checkZone(DNSSECKeeper &dk, UeberBackend &B, const std::string& zone)
+int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone)
{
SOAData sd;
if(!B.getSOAUncached(zone, sd)) {
- cout<<"[error] No SOA record present, or active, in zone '"<<zone<<"'"<<endl;
- cout<<"Checked 0 records of '"<<zone<<"', 1 errors, 0 warnings."<<endl;
+ cout<<"[error] No SOA record present, or active, in zone '"<<zone.toString()<<"'"<<endl;
+ cout<<"Checked 0 records of '"<<zone.toString()<<"', 1 errors, 0 warnings."<<endl;
return 1;
}
bool hasNsAtApex = false;
- set<string> records, cnames, noncnames, glue, checkglue;
+ set<DNSName> cnames, noncnames, glue, checkglue;
+ set<string> records;
map<string, unsigned int> ttl;
ostringstream content;
tmp = drc->getZoneRepresentation();
if (rr.qtype.getCode() != QType::AAAA) {
if (!pdns_iequals(tmp, rr.content)) {
- cout<<"[Warning] Parsed and original record content are not equal: "<<rr.qname<<" IN " <<rr.qtype.getName()<< " '" << rr.content<<"' (Content parsed as '"<<tmp<<"')"<<endl;
+ cout<<"[Warning] Parsed and original record content are not equal: "<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<< " '" << rr.content<<"' (Content parsed as '"<<tmp<<"')"<<endl;
numwarnings++;
}
} else {
struct in6_addr tmpbuf;
if (inet_pton(AF_INET6, rr.content.c_str(), &tmpbuf) != 1 || rr.content.find('.') != string::npos) {
- cout<<"[Warning] Following record is not a valid IPv6 address: "<<rr.qname<<" IN " <<rr.qtype.getName()<< " '" << rr.content<<"'"<<endl;
+ cout<<"[Warning] Following record is not a valid IPv6 address: "<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<< " '" << rr.content<<"'"<<endl;
numwarnings++;
}
}
}
catch(std::exception& e)
{
- cout<<"[Error] Following record had a problem: '"<<rr.qname<<"' of type " <<rr.qtype.getName()<< " '" << rr.content<<"'"<<endl;
+ cout<<"[Error] Following record had a problem: "<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<< " " << rr.content<<endl;
cout<<"[Error] Error was: "<<e.what()<<endl;
numerrors++;
continue;
}
- if(!endsOn(rr.qname, zone)) {
- cout<<"[Warning] Record '"<<rr.qname<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone<<"' is out-of-zone."<<endl;
+ if(!rr.qname.isPartOf(zone)) {
+ cout<<"[Warning] Record '"<<rr.qname.toString()<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone.toString()<<"' is out-of-zone."<<endl;
numwarnings++;
continue;
}
content.str("");
- content<<rr.qname<<" "<<rr.qtype.getName()<<" "<<rr.content;
+ content<<rr.qname.toString()<<" "<<rr.qtype.getName()<<" "<<rr.content;
if (records.count(toLower(content.str()))) {
- cout<<"[Error] Duplicate record found in rrset: '"<<rr.qname<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"'"<<endl;
+ cout<<"[Error] Duplicate record found in rrset: '"<<rr.qname.toString()<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"'"<<endl;
numerrors++;
continue;
} else
records.insert(toLower(content.str()));
content.str("");
- content<<rr.qname<<" "<<rr.qtype.getName();
+ content<<rr.qname.toString()<<" "<<rr.qtype.getName();
if (rr.qtype.getCode() == QType::RRSIG) {
RRSIGRecordContent rrc(rr.content);
content<<" ("<<DNSRecordContent::NumberToType(rrc.d_type)<<")";
}
ret = ttl.insert(pair<string, unsigned int>(toLower(content.str()), rr.ttl));
if (ret.second == false && ret.first->second != rr.ttl) {
- cout<<"[Error] TTL mismatch in rrset: '"<<rr.qname<<" IN " <<rr.qtype.getName()<<" "<<rr.content<<"' ("<<ret.first->second<<" != "<<rr.ttl<<")"<<endl;
+ cout<<"[Error] TTL mismatch in rrset: '"<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<<" "<<rr.content<<"' ("<<ret.first->second<<" != "<<rr.ttl<<")"<<endl;
numerrors++;
continue;
}
- if (isSecure && isOptOut && (rr.qname.size() && rr.qname[0] == '*') && (rr.qname.size() < 2 || rr.qname[1] == '.' )) {
- cout<<"[Warning] wildcard record '"<<rr.qname<<" IN " <<rr.qtype.getName()<<" "<<rr.content<<"' is insecure"<<endl;
- cout<<"[Info] Wildcard records in opt-out zones are insecure. Disable the opt-out flag for this zone to avoid this warning. Command: pdnssec set-nsec3 "<<zone<<endl;
+ if (isSecure && isOptOut && (rr.qname.countLabels() && rr.qname.getRawLabels()[0] == "*")) {
+ cout<<"[Warning] wildcard record '"<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<<" "<<rr.content<<"' is insecure"<<endl;
+ cout<<"[Info] Wildcard records in opt-out zones are insecure. Disable the opt-out flag for this zone to avoid this warning. Command: pdnssec set-nsec3 "<<zone.toString()<<endl;
numwarnings++;
}
- if(pdns_iequals(rr.qname, zone)) {
+ if(rr.qname==zone) {
if (rr.qtype.getCode() == QType::NS) {
hasNsAtApex=true;
} else if (rr.qtype.getCode() == QType::DS) {
- cout<<"[Warning] DS at apex in zone '"<<zone<<"', should not be here."<<endl;
+ cout<<"[Warning] DS at apex in zone '"<<zone.toString()<<"', should not be here."<<endl;
numwarnings++;
}
} else {
if (rr.qtype.getCode() == QType::SOA) {
- cout<<"[Error] SOA record not at apex '"<<rr.qname<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone<<"'"<<endl;
+ cout<<"[Error] SOA record not at apex '"<<rr.qname.toString()<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone.toString()<<"'"<<endl;
numerrors++;
continue;
} else if (rr.qtype.getCode() == QType::DNSKEY) {
- cout<<"[Warning] DNSKEY record not at apex '"<<rr.qname<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone<<"', should not be here."<<endl;
+ cout<<"[Warning] DNSKEY record not at apex '"<<rr.qname.toString()<<" IN "<<rr.qtype.getName()<<" "<<rr.content<<"' in zone '"<<zone.toString()<<"', should not be here."<<endl;
numwarnings++;
} else if (rr.qtype.getCode() == QType::NS && endsOn(rr.content, rr.qname)) {
checkglue.insert(toLower(rr.content));
}
if (rr.qtype.getCode() == QType::CNAME) {
- if (!cnames.count(toLower(rr.qname)))
- cnames.insert(toLower(rr.qname));
+ if (!cnames.count(rr.qname))
+ cnames.insert(rr.qname);
else {
- cout<<"[Error] Duplicate CNAME found at '"<<rr.qname<<"'"<<endl;
+ cout<<"[Error] Duplicate CNAME found at '"<<rr.qname.toString()<<"'"<<endl;
numerrors++;
continue;
}
} else {
if (rr.qtype.getCode() == QType::RRSIG) {
if(!presigned) {
- cout<<"[Error] RRSIG found at '"<<rr.qname<<"' in non-presigned zone. These do not belong in the database."<<endl;
+ cout<<"[Error] RRSIG found at '"<<rr.qname.toString()<<"' in non-presigned zone. These do not belong in the database."<<endl;
numerrors++;
continue;
}
} else
- noncnames.insert(toLower(rr.qname));
+ noncnames.insert(rr.qname);
}
if(rr.qtype.getCode() == QType::NSEC || rr.qtype.getCode() == QType::NSEC3)
{
- cout<<"[Error] NSEC or NSEC3 found at '"<<rr.qname<<"'. These do not belong in the database."<<endl;
+ cout<<"[Error] NSEC or NSEC3 found at '"<<rr.qname.toString()<<"'. These do not belong in the database."<<endl;
numerrors++;
continue;
}
{
if(rr.ttl != sd.default_ttl)
{
- cout<<"[Warning] DNSKEY TTL of "<<rr.ttl<<" at '"<<rr.qname<<"' differs from SOA minimum of "<<sd.default_ttl<<endl;
+ cout<<"[Warning] DNSKEY TTL of "<<rr.ttl<<" at '"<<rr.qname.toString()<<"' differs from SOA minimum of "<<sd.default_ttl<<endl;
numwarnings++;
}
}
else
{
- cout<<"[Warning] DNSKEY at '"<<rr.qname<<"' in non-presigned zone will mostly be ignored and can cause problems."<<endl;
+ cout<<"[Warning] DNSKEY at '"<<rr.qname.toString()<<"' in non-presigned zone will mostly be ignored and can cause problems."<<endl;
numwarnings++;
}
}
- if (rr.qname[rr.qname.size()-1] == '.') {
- cout<<"[Error] Record '"<<rr.qname<<"' has a trailing dot. PowerDNS will ignore this record!"<<endl;
- numerrors++;
- }
+ // if (rr.qname[rr.qname.size()-1] == '.') {
+ // cout<<"[Error] Record '"<<rr.qname.toString()<<"' has a trailing dot. PowerDNS will ignore this record!"<<endl;
+ // numerrors++;
+ // }
if ( (rr.qtype.getCode() == QType::NS || rr.qtype.getCode() == QType::SRV || rr.qtype.getCode() == QType::MX || rr.qtype.getCode() == QType::CNAME) &&
rr.content[rr.content.size()-1] == '.') {
- cout<<"[Warning] The record "<<rr.qname<<" with type "<<rr.qtype.getName()<<" has a trailing dot in the content ("<<rr.content<<"). Your backend might not work well with this."<<endl;
+ cout<<"[Warning] The record "<<rr.qname.toString()<<" with type "<<rr.qtype.getName()<<" has a trailing dot in the content ("<<rr.content<<"). Your backend might not work well with this."<<endl;
numwarnings++;
}
if(rr.auth == 0 && rr.qtype.getCode()!=QType::NS && rr.qtype.getCode()!=QType::A && rr.qtype.getCode()!=QType::AAAA)
{
- cout<<"[Error] Following record is auth=0, run pdnssec rectify-zone?: "<<rr.qname<<" IN " <<rr.qtype.getName()<< " " << rr.content<<endl;
+ cout<<"[Error] Following record is auth=0, run pdnssec rectify-zone?: "<<rr.qname.toString()<<" IN " <<rr.qtype.getName()<< " " << rr.content<<endl;
numerrors++;
}
}
- for(set<string>::const_iterator i = cnames.begin(); i != cnames.end(); i++) {
- if (noncnames.find(*i) != noncnames.end()) {
- cout<<"[Error] CNAME "<<*i<<" found, but other records with same label exist."<<endl;
+ for(auto &i: cnames) {
+ if (noncnames.find(i) != noncnames.end()) {
+ cout<<"[Error] CNAME "<<i.toString()<<" found, but other records with same label exist."<<endl;
numerrors++;
}
}
if(!hasNsAtApex) {
- cout<<"[Error] No NS record at zone apex in zone '"<<zone<<"'"<<endl;
+ cout<<"[Error] No NS record at zone apex in zone '"<<zone.toString()<<"'"<<endl;
numerrors++;
}
for(const auto &qname : checkglue) {
if (!glue.count(qname)) {
- cerr<<"[Warning] Missing glue for '"<<qname<<"' in zone '"<<zone<<"'"<<endl;
+ cerr<<"[Warning] Missing glue for '"<<qname.toString()<<"' in zone '"<<zone.toString()<<"'"<<endl;
numwarnings++;
}
}
- cout<<"Checked "<<numrecords<<" records of '"<<zone<<"', "<<numerrors<<" errors, "<<numwarnings<<" warnings."<<endl;
+ cout<<"Checked "<<numrecords<<" records of '"<<zone.toString()<<"', "<<numerrors<<" errors, "<<numwarnings<<" warnings."<<endl;
return numerrors;
}
return 0;
}
-int increaseSerial(const string& zone, DNSSECKeeper &dk)
+int increaseSerial(const DNSName& zone, DNSSECKeeper &dk)
{
UeberBackend B("default");
SOAData sd;
if(!B.getSOAUncached(zone, sd)) {
- cout<<"No SOA for zone '"<<zone<<"'"<<endl;
+ cout<<"No SOA for zone '"<<zone.toString()<<"'"<<endl;
return -1;
}
}
if (rrs.size() > 1) {
- cerr<<rrs.size()<<" SOA records found for "<<zone<<"!"<<endl;
+ cerr<<rrs.size()<<" SOA records found for "<<zone.toString()<<"!"<<endl;
return -1;
}
if (rrs.size() < 1) {
- cerr<<zone<<" not found!"<<endl;
+ cerr<<zone.toString()<<" not found!"<<endl;
}
if (soaEditKind.empty()) {
if(!narrow) {
string hashed=toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, rrs[0].qname));
if(g_verbose)
- cerr<<"'"<<rrs[0].qname<<"' -> '"<< hashed <<"'"<<endl;
+ cerr<<"'"<<rrs[0].qname.toString()<<"' -> '"<< hashed <<"'"<<endl;
sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, rrs[0].qname, hashed, 1);
}
else {
sd.db->commitTransaction();
- cout<<"SOA serial for zone "<<zone<<" set to "<<sd.serial<<endl;
+ cout<<"SOA serial for zone "<<zone.toString()<<" set to "<<sd.serial<<endl;
return 0;
}
-int deleteZone(const string &zone) {
+int deleteZone(const DNSName &zone) {
UeberBackend B;
DomainInfo di;
if (! B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' not found!"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' not found!"<<endl;
return 1;
}
if(di.backend->deleteDomain(zone))
return 0;
- cerr<<"Failed to delete domain '"+zone+"'"<<endl;;
+ cerr<<"Failed to delete domain '"<<zone.toString()<<"'"<<endl;;
return 1;
}
-int listZone(const string &zone) {
+int listZone(const DNSName &zone) {
UeberBackend B;
DomainInfo di;
if (! B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' not found!"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' not found!"<<endl;
return 1;
}
di.backend->list(zone, di.id);
if ( (rr.qtype.getCode() == QType::NS || rr.qtype.getCode() == QType::SRV || rr.qtype.getCode() == QType::MX || rr.qtype.getCode() == QType::CNAME) && !rr.content.empty() && rr.content[rr.content.size()-1] != '.')
rr.content.append(1, '.');
- cout<<rr.qname<<".\t"<<rr.ttl<<"\tIN\t"<<rr.qtype.getName()<<"\t"<<rr.content<<endl;
+ cout<<rr.qname.toString()<<".\t"<<rr.ttl<<"\tIN\t"<<rr.qtype.getName()<<"\t"<<rr.content<<endl;
}
}
return 0;
}
-int loadZone(string zone, const string& fname) {
+int loadZone(DNSName zone, const string& fname) {
UeberBackend B;
DomainInfo di;
if (B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' exists already, replacing contents"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' exists already, replacing contents"<<endl;
}
else {
- cerr<<"Creating '"<<zone<<"'"<<endl;
+ cerr<<"Creating '"<<zone.toString()<<"'"<<endl;
B.createDomain(zone);
if(!B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' was not created!"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' was not created!"<<endl;
return 1;
}
}
DNSResourceRecord rr;
if(!db->startTransaction(zone, di.id)) {
- cerr<<"Unable to start transaction for load of zone '"<<zone<<"'"<<endl;
+ cerr<<"Unable to start transaction for load of zone '"<<zone.toString()<<"'"<<endl;
return 1;
}
rr.domain_id=di.id;
while(zpt.get(rr)) {
- if(!endsOn(stripDot(rr.qname), zone) && rr.qname!=zone) {
- cerr<<"File contains record named '"<<rr.qname<<"' which is not part of zone '"<<zone<<"'"<<endl;
+ if(!rr.qname.isPartOf(zone) && rr.qname!=zone) {
+ cerr<<"File contains record named '"<<rr.qname.toString()<<"' which is not part of zone '"<<zone.toString()<<"'"<<endl;
return 1;
}
- rr.qname=stripDot(rr.qname);
db->feedRecord(rr);
}
db->commitTransaction();
return 0;
}
-int createZone(const string &zone) {
+int createZone(const DNSName &zone) {
UeberBackend B;
DomainInfo di;
if (B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' exists already"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' exists already"<<endl;
return 1;
}
- cerr<<"Creating '"<<zone<<"'"<<endl;
+ cerr<<"Creating '"<<zone.toString()<<"'"<<endl;
B.createDomain(zone);
if(!B.getDomainInfo(zone, di)) {
- cerr<<"Domain '"<<zone<<"' was not created!"<<endl;
+ cerr<<"Domain '"<<zone.toString()<<"' was not created!"<<endl;
return 1;
}
return 1;
int count = 0;
for (vector<DomainInfo>::const_iterator di=domains.begin(); di != domains.end(); di++) {
if (di->kind == kindFilter || kindFilter == -1) {
- cout<<di->zone<<endl;
+ cout<<di->zone.toString()<<endl;
count++;
}
}
RRSIGRecordContent rrc;
DSRecordContent dsrc;
vector<shared_ptr<DNSRecordContent> > toSign;
- string qname, apex;
+ DNSName qname, apex;
dsrc.d_digesttype=0;
while(zpt.get(rr)) {
if(rr.qtype.getCode() == QType::DNSKEY) {
string msg = getMessageForRRSET(qname, rrc, toSign);
cerr<<"Verify: "<<DNSCryptoKeyEngine::makeFromPublicKeyString(drc.d_algorithm, drc.d_key)->verify(msg, rrc.d_signature)<<endl;
if(dsrc.d_digesttype) {
- cerr<<"Calculated DS: "<<apex<<" IN DS "<<makeDSFromDNSKey(apex, drc, dsrc.d_digesttype).getZoneRepresentation()<<endl;
- cerr<<"Original DS: "<<apex<<" IN DS "<<dsrc.getZoneRepresentation()<<endl;
+ cerr<<"Calculated DS: "<<apex.toString()<<" IN DS "<<makeDSFromDNSKey(apex, drc, dsrc.d_digesttype).getZoneRepresentation()<<endl;
+ cerr<<"Original DS: "<<apex.toString()<<" IN DS "<<dsrc.getZoneRepresentation()<<endl;
}
#if 0
DNSCryptoKeyEngine*key=DNSCryptoKeyEngine::makeFromISCString(drc, "Private-key-format: v1.2\n"
#endif
}
-bool disableDNSSECOnZone(DNSSECKeeper& dk, const string& zone)
+bool disableDNSSECOnZone(DNSSECKeeper& dk, const DNSName& zone)
{
UeberBackend B("default");
DomainInfo di;
DNSSECKeeper::keyset_t keyset=dk.getKeys(zone);
if(keyset.empty()) {
- cerr << "No keys for zone '"<<zone<<"'."<<endl;
+ cerr << "No keys for zone '"<<zone.toString()<<"'."<<endl;
}
else {
BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type value, keyset) {
dk.unsetPresigned(zone);
return true;
}
-bool showZone(DNSSECKeeper& dk, const std::string& zone)
+bool showZone(DNSSECKeeper& dk, const DNSName& zone)
{
UeberBackend B("default");
DomainInfo di;
cout <<"Zone is " << (dk.isPresigned(zone) ? "" : "not ") << "presigned"<<endl;
if(keyset.empty()) {
- cerr << "No keys for zone '"<<zone<<"'."<<endl;
+ cerr << "No keys for zone '"<<zone.toString()<<"'."<<endl;
}
else {
if(!haveNSEC3)
cout<<"ID = "<<value.second.id<<" ("<<(value.second.keyOrZone ? "KSK" : "ZSK")<<"), tag = "<<value.first.getDNSKEY().getTag();
cout<<", algo = "<<(int)value.first.d_algorithm<<", bits = "<<value.first.getKey()->getBits()<<"\tActive: "<<value.second.active<< " ( " + algname + " ) "<<endl;
if(value.second.keyOrZone || ::arg().mustDo("direct-dnskey") || g_verbose)
- cout<<(value.second.keyOrZone ? "KSK" : "ZSK")<<" DNSKEY = "<<zone<<" IN DNSKEY "<< value.first.getDNSKEY().getZoneRepresentation() << " ; ( " + algname + " )" << endl;
+ cout<<(value.second.keyOrZone ? "KSK" : "ZSK")<<" DNSKEY = "<<zone.toString()<<" IN DNSKEY "<< value.first.getDNSKEY().getZoneRepresentation() << " ; ( " + algname + " )" << endl;
if(value.second.keyOrZone || g_verbose) {
- cout<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 1).getZoneRepresentation() << " ; ( SHA1 digest )" << endl;
- cout<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 2).getZoneRepresentation() << " ; ( SHA256 digest )" << endl;
+ cout<<"DS = "<<zone.toString()<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 1).getZoneRepresentation() << " ; ( SHA1 digest )" << endl;
+ cout<<"DS = "<<zone.toString()<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 2).getZoneRepresentation() << " ; ( SHA256 digest )" << endl;
try {
string output=makeDSFromDNSKey(zone, value.first.getDNSKEY(), 3).getZoneRepresentation();
- cout<<"DS = "<<zone<<" IN DS "<< output << " ; ( GOST R 34.11-94 digest )" << endl;
+ cout<<"DS = "<<zone.toString()<<" IN DS "<< output << " ; ( GOST R 34.11-94 digest )" << endl;
}
catch(...)
{
}
try {
string output=makeDSFromDNSKey(zone, value.first.getDNSKEY(), 4).getZoneRepresentation();
- cout<<"DS = "<<zone<<" IN DS "<< output << " ; ( SHA-384 digest )" << endl;
+ cout<<"DS = "<<zone.toString()<<" IN DS "<< output << " ; ( SHA-384 digest )" << endl;
}
catch(...)
{
return true;
}
-bool secureZone(DNSSECKeeper& dk, const std::string& zone)
+bool secureZone(DNSSECKeeper& dk, const DNSName& zone)
{
// parse attribute
vector<string> k_algos;
}
if(dk.isSecuredZone(zone)) {
- cerr << "Zone '"<<zone<<"' already secure, remove keys with pdnssec remove-zone-key if needed"<<endl;
+ cerr << "Zone '"<<zone.toString()<<"' already secure, remove keys with pdnssec remove-zone-key if needed"<<endl;
return false;
}
DomainInfo di;
UeberBackend B("default");
if(!B.getDomainInfo(zone, di) || !di.backend) { // di.backend and B are mostly identical
- cout<<"Can't find a zone called '"<<zone<<"'"<<endl;
+ cout<<"Can't find a zone called '"<<zone.toString()<<"'"<<endl;
return false;
}
if(di.kind == DomainInfo::Slave)
{
cout<<"Warning! This is a slave domain! If this was a mistake, please run"<<endl;
- cout<<"pdnssec disable-dnssec "<<zone<<" right now!"<<endl;
+ cout<<"pdnssec disable-dnssec "<<zone.toString()<<" right now!"<<endl;
}
if (k_size)
// run secure-zone with first default algorith, then add keys
if(!dk.secureZone(zone, shorthand2algorithm(k_algos[0]), k_size)) {
- cerr<<"No backend was able to secure '"<<zone<<"', most likely because no DNSSEC"<<endl;
+ cerr<<"No backend was able to secure '"<<zone.toString()<<"', most likely because no DNSSEC"<<endl;
cerr<<"capable backends are loaded, or because the backends have DNSSEC disabled."<<endl;
cerr<<"For the Generic SQL backends, set the 'gsqlite3-dnssec', 'gmysql-dnssec' or"<<endl;
cerr<<"'gpgsql-dnssec' flag. Also make sure the schema has been updated for DNSSEC!"<<endl;
DNSSECKeeper::keyset_t zskset=dk.getKeys(zone, false);
if(!zskset.empty()) {
- cerr<<"There were ZSKs already for zone '"<<zone<<"', no need to add more"<<endl;
+ cerr<<"There were ZSKs already for zone '"<<zone.toString()<<"', no need to add more"<<endl;
return false;
}
// rectifyZone(dk, zone);
// showZone(dk, zone);
- cout<<"Zone "<<zone<<" secured"<<endl;
+ cout<<"Zone "<<zone.toString()<<" secured"<<endl;
return true;
}
-void testSchema(DNSSECKeeper& dk, const std::string& zone)
+void testSchema(DNSSECKeeper& dk, const DNSName& zone)
{
cout<<"Note: test-schema will try to create the zone, but it will not remove it."<<endl;
cout<<"Please clean up after this."<<endl;
UeberBackend B("default");
cout<<"Picking first backend - if this is not what you want, edit launch line!"<<endl;
DNSBackend *db = B.backends[0];
- cout<<"Creating slave domain "<<zone<<endl;
+ cout<<"Creating slave domain "<<zone.toString()<<endl;
db->createSlaveDomain("127.0.0.1", zone, "", "_testschema");
cout<<"Slave domain created"<<endl;
cout<<"Rectifying zone"<<endl;
rectifyZone(dk, zone);
cout<<"Checking underscore ordering"<<endl;
- string before, after;
+ DNSName before, after;
db->getBeforeAndAfterNames(di.id, zone, "z."+zone, before, after);
- cout<<"got '"<<before<<"' < 'z."<<zone<<"' < '"<<after<<"'"<<endl;
+ cout<<"got '"<<before.toString()<<"' < 'z."<<zone.toString()<<"' < '"<<after.toString()<<"'"<<endl;
if(before != "_underscore."+zone)
{
- cout<<"before is wrong, got '"<<before<<"', expected '_underscore."<<zone<<"', aborting"<<endl;
+ cout<<"before is wrong, got '"<<before.toString()<<"', expected '_underscore."<<zone.toString()<<"', aborting"<<endl;
return;
}
if(after != zone)
{
- cout<<"after is wrong, got '"<<after<<"', expected '"<<zone<<"', aborting"<<endl;
+ cout<<"after is wrong, got '"<<after.toString()<<"', expected '"<<zone.toString()<<"', aborting"<<endl;
return;
}
cout<<"[+] ordername sorting is correct for names starting with _"<<endl;
cout<<endl;
- cout<<"End of tests, please remove "<<zone<<" from domains+records"<<endl;
+ cout<<"End of tests, please remove "<<zone.toString()<<" from domains+records"<<endl;
}
int main(int argc, char** argv)
unsigned int zonesSecured=0, zoneErrors=0;
BOOST_FOREACH(DomainInfo di, domainInfo) {
if(!dk.isSecuredZone(di.zone)) {
- cout<<"Securing "<<di.zone<<": ";
+ cout<<"Securing "<<di.zone.toString()<<": ";
if (secureZone(dk, di.zone)) {
zonesSecured++;
if (cmds.size() == 2) {
bool narrow = cmds.size() > 3 && cmds[3]=="narrow";
NSEC3PARAMRecordContent ns3pr(nsec3params);
- string zone=cmds[1];
+ DNSName zone(cmds[1]);
if(!dk.isSecuredZone(zone)) {
- cerr<<"Zone '"<<zone<<"' is not secured, can't set NSEC3 parameters"<<endl;
+ cerr<<"Zone '"<<zone.toString()<<"' is not secured, can't set NSEC3 parameters"<<endl;
exit(EXIT_FAILURE);
}
dk.setNSEC3PARAM(zone, ns3pr, narrow);
cerr<<"Syntax: pdnssec hash-zone-record ZONE RNAME"<<endl;
return 0;
}
- string& zone=cmds[1];
+ DNSName zone(cmds[1]);
string& record=cmds[2];
NSEC3PARAMRecordContent ns3pr;
bool narrow;
if(!dk.getNSEC3PARAM(zone, &ns3pr, &narrow)) {
- cerr<<"The '"<<zone<<"' zone does not use NSEC3"<<endl;
+ cerr<<"The '"<<zone.toString()<<"' zone does not use NSEC3"<<endl;
return 0;
}
if(narrow) {
- cerr<<"The '"<<zone<<"' zone uses narrow NSEC3, but calculating hash anyhow"<<endl;
+ cerr<<"The '"<<zone.toString()<<"' zone uses narrow NSEC3, but calculating hash anyhow"<<endl;
}
cout<<toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, record))<<endl;
UeberBackend B("default");
if (B.getTSIGKeys(keys)) {
BOOST_FOREACH(const struct TSIGKey &key, keys) {
- cout << key.name << " " << key.algorithm << " " << key.key << endl;
+ cout << key.name.toString() << " " << key.algorithm.toString() << " " << key.key << endl;
}
}
return 0;
uint changedRecords = 0;
DNSResourceRecord rec;
vector<DNSResourceRecord> rrset, recordsToDelete;
- set<string> delnonterm, insnonterm; // used to (at the end) fix ENT records.
+ set<DNSName> delnonterm, insnonterm; // used to (at the end) fix ENT records.
if (rr->d_class == QClass::IN) { // 3.4.2.2 QClass::IN means insert or update
// because we added a record, we need to fix DNSSEC data.
- string shorter(rrLabel);
+ DNSName shorter(rrLabel);
bool auth=newRec.auth;
bool fixDS = (rrType == QType::DS);
insnonterm.insert(shorter);
if (foundShorter)
break; // if we find a shorter record, we can stop searching
- } while(chopOff(shorter));
+ } while(shorter.chopOff());
}
if(*haveNSEC3)
// If we've removed a delegate, we need to reset ordername/auth for some records.
if (rrType == QType::NS && rrLabel != di->zone) {
- vector<string> belowOldDelegate, nsRecs, updateAuthFlag;
+ vector<DNSName> belowOldDelegate, nsRecs, updateAuthFlag;
di->backend->listSubZone(rrLabel, di->id);
while (di->backend->get(rec)) {
if (rec.qtype.getCode()) // skip ENT records, they are always auth=false
nsRecs.push_back(rec.qname);
}
- for(vector<string>::const_iterator belowOldDel=belowOldDelegate.begin(); belowOldDel!= belowOldDelegate.end(); belowOldDel++)
+ for(auto &belowOldDel: belowOldDelegate)
{
bool isBelowDelegate = false;
for(vector<string>::const_iterator ns=nsRecs.begin(); ns!= nsRecs.end(); ns++) {
} else if (!foundOtherWithSameName) {
// If we didn't have to insert an ENT, we might have deleted a record at very deep level
// and we must then clean up the ENT's above the deleted record.
- string shorter(rrLabel);
+ DNSName shorter(rrLabel);
while (shorter != di->zone) {
- chopOff(shorter);
+ shorter.chopOff();
bool foundRealRR = false;
bool foundEnt = false;
{
vector<DNSResourceRecord>& rrs = dp->getRRS();
BOOST_FOREACH(DNSResourceRecord& rr, rrs) {
- if(rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname,qname)) {
+ if(rr.qtype.getCode() == QType::SOA && rr.qname == qname) {
string kind;
dk.getFromMeta(qname, "SOA-EDIT", kind);
return editSOARecord(rr, kind);
{
++d_submitted;
// check if we have a full RRSET to sign
- if(!d_rrsetToSign->empty() && (d_rrsetToSign->begin()->qtype.getCode() != rr.qtype.getCode() || !pdns_iequals(d_rrsetToSign->begin()->qname, rr.qname)))
+ if(!d_rrsetToSign->empty() && (d_rrsetToSign->begin()->qtype.getCode() != rr.qtype.getCode() || d_rrsetToSign->begin()->qname != rr.qname))
{
dedupRRSet();
sendRRSetToWorker();
pthread_mutex_unlock(&d_mut);
}
-bool UeberBackend::getDomainInfo(const string &domain, DomainInfo &di)
+bool UeberBackend::getDomainInfo(const DNSName &domain, DomainInfo &di)
{
for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
if((*i)->getDomainInfo(domain, di))
return false;
}
-bool UeberBackend::createDomain(const string &domain)
+bool UeberBackend::createDomain(const DNSName &domain)
{
BOOST_FOREACH(DNSBackend* mydb, backends) {
if(mydb->createDomain(domain)) {
return false;
}
-int UeberBackend::addDomainKey(const string& name, const DNSBackend::KeyData& key)
+int UeberBackend::addDomainKey(const DNSName& name, const DNSBackend::KeyData& key)
{
int ret;
BOOST_FOREACH(DNSBackend* db, backends) {
}
return -1;
}
-bool UeberBackend::getDomainKeys(const string& name, unsigned int kind, std::vector<DNSBackend::KeyData>& keys)
+bool UeberBackend::getDomainKeys(const DNSName& name, unsigned int kind, std::vector<DNSBackend::KeyData>& keys)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getDomainKeys(name, kind, keys))
return false;
}
-bool UeberBackend::getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta)
+bool UeberBackend::getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getAllDomainMetadata(name, meta))
return false;
}
-bool UeberBackend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+bool UeberBackend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getDomainMetadata(name, kind, meta))
return false;
}
-bool UeberBackend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+bool UeberBackend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->setDomainMetadata(name, kind, meta))
return false;
}
-bool UeberBackend::activateDomainKey(const string& name, unsigned int id)
+bool UeberBackend::activateDomainKey(const DNSName& name, unsigned int id)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->activateDomainKey(name, id))
return false;
}
-bool UeberBackend::deactivateDomainKey(const string& name, unsigned int id)
+bool UeberBackend::deactivateDomainKey(const DNSName& name, unsigned int id)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->deactivateDomainKey(name, id))
return false;
}
-bool UeberBackend::removeDomainKey(const string& name, unsigned int id)
+bool UeberBackend::removeDomainKey(const DNSName& name, unsigned int id)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->removeDomainKey(name, id))
}
-bool UeberBackend::getTSIGKey(const string& name, string* algorithm, string* content)
+bool UeberBackend::getTSIGKey(const DNSName& name, DNSName* algorithm, string* content)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getTSIGKey(name, algorithm, content))
}
-bool UeberBackend::setTSIGKey(const string& name, const string& algorithm, const string& content)
+bool UeberBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->setTSIGKey(name, algorithm, content))
return false;
}
-bool UeberBackend::deleteTSIGKey(const string& name)
+bool UeberBackend::deleteTSIGKey(const DNSName& name)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->deleteTSIGKey(name))
return true;
}
-bool UeberBackend::getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, string &before, DNSResourceRecord &rr)
+bool UeberBackend::getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, DNSName &before, DNSResourceRecord &rr)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getDirectNSECx(id, hashed, qtype, before, rr))
return false;
}
-bool UeberBackend::getDirectRRSIGs(const string &signer, const string &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs)
+bool UeberBackend::getDirectRRSIGs(const DNSName &signer, const DNSName &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs)
{
BOOST_FOREACH(DNSBackend* db, backends) {
if(db->getDirectRRSIGs(signer, qname, qtype, rrsigs))
}
}
-bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const string &target)
+bool UeberBackend::getAuth(DNSPacket *p, SOAData *sd, const DNSName &target)
{
int best_match_len = -1;
bool from_cache = false; // Was this result fetched from the cache?
// find the best match from the cache. If DS then we need to find parent so
// dont bother with caching as it confuses matters.
if( sd->db != (DNSBackend *)-1 && d_cache_ttl && p->qtype != QType::DS ) {
- string subdomain(target);
+ DNSName subdomain(target);
int cstat, loops = 0;
do {
d_question.qtype = QType::SOA;
return true;
from_cache = true;
- best_match_len = sd->qname.length();
+ best_match_len = sd->qname.countLabels();
break;
}
loops++;
}
- while( chopOff( subdomain ) ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
+ while( subdomain.chopOff() ); // 'www.powerdns.org' -> 'powerdns.org' -> 'org' -> ''
}
for(vector<DNSBackend *>::const_iterator i=backends.begin(); i!=backends.end();++i)
if((*i)->getAuth(p, sd, target, best_match_len)) {
- best_match_len = sd->qname.length();
+ best_match_len = sd->qname.countLabels(); // FIXME
from_cache = false;
// Shortcut for the case that we got a direct hit - no need to go
// through the other backends then.
- if( best_match_len == (int)target.length() )
+ if( best_match_len == (int)target.countLabels() )
goto auth_found;
}
return true;
}
-bool UeberBackend::getSOA(const string &domain, SOAData &sd, DNSPacket *p)
+bool UeberBackend::getSOA(const DNSName &domain, SOAData &sd, DNSPacket *p)
{
d_question.qtype=QType::SOA;
d_question.qname=domain;
return getSOAUncached(domain, sd, p);
}
-bool UeberBackend::getSOAUncached(const string &domain, SOAData &sd, DNSPacket *p)
+bool UeberBackend::getSOAUncached(const DNSName &domain, SOAData &sd, DNSPacket *p)
{
d_question.qtype=QType::SOA;
d_question.qname=domain;
return false;
}
-bool UeberBackend::superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
+bool UeberBackend::superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db)
{
for(vector<DNSBackend *>::const_iterator i=backends.begin();i!=backends.end();++i)
if((*i)->superMasterBackend(ip, domain, nsset, nameserver, account, db))
PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, ostr.str(), store_ttl, q.zoneId);
}
-void UeberBackend::alsoNotifies(const string &domain, set<string> *ips)
+void UeberBackend::alsoNotifies(const DNSName &domain, set<string> *ips)
{
for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
(*i)->alsoNotifies(domain,ips);
}
// this handle is more magic than most
-void UeberBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int zoneId)
+void UeberBackend::lookup(const QType &qtype,const DNSName &qname, DNSPacket *pkt_p, int zoneId)
{
if(stale) {
L<<Logger::Error<<"Stale ueberbackend received question, signalling that we want to be recycled"<<endl;
throw PDNSException("We are stale, please recycle");
}
- DLOG(L<<"UeberBackend received question for "<<qtype.getName()<<" of "<<qname<<endl);
+ DLOG(L<<"UeberBackend received question for "<<qtype.getName()<<" of "<<qname.toString()<<endl);
if(!d_go) {
pthread_mutex_lock(&d_mut);
while (d_go==false) {
return false;
}
if(!d_handle.get(rr)) {
- if(!d_ancount && !d_handle.qname.empty()) // don't cache axfr
+ if(!d_ancount && d_handle.qname.countLabels()) // don't cache axfr
addNegCache(d_question);
addCache(d_question, d_answers);
return true;
}
-bool UeberBackend::list(const string &target, int domain_id, bool include_disabled)
+bool UeberBackend::list(const DNSName &target, int domain_id, bool include_disabled)
{
L<<Logger::Error<<"UeberBackend::list called, should NEVER EVER HAPPEN"<<endl;
exit(1);
~UeberBackend();
typedef DNSBackend *BackendMaker(); //!< typedef for functions returning pointers to new backends
- bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
+ bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
/** Tracks all created UeberBackend instances for us. We use this vector to notify
existing threads of new modules
//! DNSPacket who asked this question
DNSPacket *pkt_p;
- string qname;
+ DNSName qname;
QType qtype;
private:
static AtomicCounter instances;
};
- void lookup(const QType &, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
+ void lookup(const QType &, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
- bool getAuth(DNSPacket *p, SOAData *sd, const string &target);
- bool getSOA(const string &domain, SOAData &sd, DNSPacket *p=0);
- bool getSOAUncached(const string &domain, SOAData &sd, DNSPacket *p=0); // same, but ignores cache
- bool list(const string &target, int domain_id, bool include_disabled=false);
+ bool getAuth(DNSPacket *p, SOAData *sd, const DNSName &target);
+ bool getSOA(const DNSName &domain, SOAData &sd, DNSPacket *p=0);
+ bool getSOAUncached(const DNSName &domain, SOAData &sd, DNSPacket *p=0); // same, but ignores cache
+ bool list(const DNSName &target, int domain_id, bool include_disabled=false);
bool get(DNSResourceRecord &r);
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
static DNSBackend *maker(const map<string,string> &);
void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
void getUpdatedMasters(vector<DomainInfo>* domains);
- bool getDomainInfo(const string &domain, DomainInfo &di);
- bool createDomain(const string &domain);
+ bool getDomainInfo(const DNSName &domain, DomainInfo &di);
+ bool createDomain(const DNSName &domain);
- int addDomainKey(const string& name, const DNSBackend::KeyData& key);
- bool getDomainKeys(const string& name, unsigned int kind, std::vector<DNSBackend::KeyData>& keys);
- bool getAllDomainMetadata(const string& name, std::map<std::string, std::vector<std::string> >& meta);
- bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
- bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
-
- bool removeDomainKey(const string& name, unsigned int id);
- bool activateDomainKey(const string& name, unsigned int id);
- bool deactivateDomainKey(const string& name, unsigned int id);
-
- bool getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, string &before, DNSResourceRecord &rr);
- bool getDirectRRSIGs(const string &signer, const string &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs);
-
- bool getTSIGKey(const string& name, string* algorithm, string* content);
- bool setTSIGKey(const string& name, const string& algorithm, const string& content);
- bool deleteTSIGKey(const string& name);
+ int addDomainKey(const DNSName& name, const DNSBackend::KeyData& key);
+ bool getDomainKeys(const DNSName& name, unsigned int kind, std::vector<DNSBackend::KeyData>& keys);
+ bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta);
+ bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta);
+ bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta);
+
+ bool removeDomainKey(const DNSName& name, unsigned int id);
+ bool activateDomainKey(const DNSName& name, unsigned int id);
+ bool deactivateDomainKey(const DNSName& name, unsigned int id);
+
+ bool getDirectNSECx(uint32_t id, const string &hashed, const QType &qtype, DNSName &before, DNSResourceRecord &rr);
+ bool getDirectRRSIGs(const DNSName &signer, const DNSName &qname, const QType &qtype, vector<DNSResourceRecord> &rrsigs);
+
+ bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content);
+ bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content);
+ bool deleteTSIGKey(const DNSName& name);
bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
- void alsoNotifies(const string &domain, set<string> *ips);
+ void alsoNotifies(const DNSName &domain, set<string> *ips);
void rediscover(string* status=0);
void reload();
private:
struct Question
{
QType qtype;
- string qname;
+ DNSName qname;
int zoneId;
}d_question;
vector<DNSResourceRecord> d_answers;
throw HttpMethodNotAllowedException();
}
-static string makeDotted(string in) {
- if (in.empty()) {
- return ".";
- }
- if (in[in.size()-1] != '.') {
- return in + ".";
- }
- return in;
-}
+// static string makeDotted(string in) {
+// if (in.empty()) {
+// return ".";
+// }
+// if (in[in.size()-1] != '.') {
+// return in + ".";
+// }
+// return in;
+// }
static void apiServerZoneExport(HttpRequest* req, HttpResponse* resp) {
string zonename = apiZoneIdToName(req->parameters["id"]);
switch(rr.qtype.getCode()) {
case QType::SOA:
fillSOAData(rr.content, sd);
- sd.nameserver = makeDotted(sd.nameserver);
- sd.hostmaster = makeDotted(sd.hostmaster);
+ sd.nameserver = sd.nameserver.toString();
+ sd.hostmaster = sd.hostmaster.toString();
content = serializeSOAData(sd);
break;
case QType::MX:
case QType::CNAME:
case QType::NS:
case QType::AFSDB:
- content = makeDotted(rr.content);
+ content = rr.content.toString()
break;
default:
break;
}
ss <<
- makeDotted(rr.qname) << "\t" <<
+ rr.qname.toString() << "\t" <<
rr.ttl << "\t" <<
rr.qtype.getName() << "\t" <<
content <<
// reverse and append arpa domain
ptr->qname = string(tmp.rbegin(), tmp.rend()) + ".ip6.arpa";
} else {
- throw ApiException("Unsupported PTR source '" + rr.qname + "' type '" + rr.qtype.getName() + "'");
+ throw ApiException("Unsupported PTR source '" + rr.qname.toString() + "' type '" + rr.qtype.getName() + "'");
}
ptr->qtype = "PTR";
ptr->ttl = rr.ttl;
ptr->disabled = rr.disabled;
- ptr->content = rr.qname;
+ ptr->content = rr.qname.toString();
}
static void patchZone(HttpRequest* req, HttpResponse* resp) {
rr.domain_id = di.id;
if (rr.qname != qname || rr.qtype != qtype)
- throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" "+rr.content+": Record wrongly bundled with RRset " + qname + "/" + qtype.getName());
+ throw ApiException("Record "+rr.qname+"/"+rr.qtype.getName()+" "+rr.content+": Record wrongly bundled with RRset " + qname.toString() + "/" + qtype.getName());
if (rr.qtype.getCode() == QType::SOA && pdns_iequals(rr.qname, zonename)) {
soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
-ZoneParserTNG::ZoneParserTNG(const string& fname, const string& zname, const string& reldir) : d_reldir(reldir),
+ZoneParserTNG::ZoneParserTNG(const string& fname, const DNSName& zname, const string& reldir) : d_reldir(reldir),
d_zonename(zname), d_defaultttl(3600),
d_havedollarttl(false)
{
- d_zonename = toCanonic("", d_zonename);
stackFile(fname);
}
-ZoneParserTNG::ZoneParserTNG(const vector<string> zonedata, const string& zname):
+ZoneParserTNG::ZoneParserTNG(const vector<string> zonedata, const DNSName& zname):
d_zonename(zname), d_defaultttl(3600),
d_havedollarttl(false)
{
- d_zonename = toCanonic("", d_zonename);
d_zonedata = zonedata;
d_zonedataline = d_zonedata.begin();
d_fromfile = false;
stackFile(fname);
}
else if(pdns_iequals(command, "$ORIGIN") && parts.size() > 1) {
- d_zonename = toCanonic("", makeString(d_line, parts[1]));
+ d_zonename = DNSName(toCanonic(string(""), makeString(d_line, parts[1])));
}
else if(pdns_iequals(command, "$GENERATE") && parts.size() > 2) {
// $GENERATE 1-127 $ CNAME $.0
else {
rr.qname=makeString(d_line, parts[0]);
parts.pop_front();
- if(rr.qname.empty() || rr.qname[0]==';')
+ if(!rr.qname.countLabels() || rr.qname.toString()[0]==';')
goto retry;
}
if(rr.qname=="@")
rr.qname=d_zonename;
- else if(!isCanonical(rr.qname)) {
- if(d_zonename.empty() || d_zonename[0]!='.') // prevent us from adding a double dot
- rr.qname.append(1,'.');
-
- rr.qname.append(d_zonename);
- }
+ else
+ rr.qname += d_zonename;
d_prevqname=rr.qname;
if(parts.empty())
trim(rr.content);
if(equals(rr.content, "@"))
- rr.content=d_zonename;
+ rr.content=d_zonename.toString();
if(findAndElide(rr.content, '(')) { // have found a ( and elided it
if(!findAndElide(rr.content, ')')) {
class ZoneParserTNG
{
public:
- ZoneParserTNG(const string& fname, const string& zname="", const string& reldir="");
- ZoneParserTNG(const vector<string> zonedata, const string& zname);
+ ZoneParserTNG(const string& fname, const DNSName& zname="", const string& reldir="");
+ ZoneParserTNG(const vector<string> zonedata, const DNSName& zname);
~ZoneParserTNG();
bool get(DNSResourceRecord& rr, std::string* comment=0);
string getLineOfFile();
string d_reldir;
string d_line;
- string d_prevqname;
- string d_zonename;
+ DNSName d_prevqname;
+ DNSName d_zonename;
vector<string> d_zonedata;
vector<string>::iterator d_zonedataline;
int d_defaultttl;