void setupDNSSEC();
void setupStatements();
void freeStatements();
- void release(SSqlStatement**);
static bool safeGetBBDomainInfo(int id, BB2DomainInfo* bbd);
static void safePutBBDomainInfo(const BB2DomainInfo& bbd);
static bool safeGetBBDomainInfo(const DNSName& name, BB2DomainInfo* bbd);
d_getTSIGKeysQuery_stmt = d_dnssecdb->prepare("select name,algorithm,secret from tsigkeys", 0);
}
-void Bind2Backend::release(SSqlStatement** stmt) {
- delete *stmt;
- *stmt = NULL;
-}
-
void Bind2Backend::freeStatements()
{
d_getAllDomainMetadataQuery_stmt.reset();
bool gPgSQLBackend::inTransaction()
{
- const auto* db = dynamic_cast<SPgSQL*>(d_db);
+ const auto* db = dynamic_cast<SPgSQL*>(d_db.get());
if (db) {
return db->in_trx();
}
CoWrapper::CoWrapper(const string &command, int timeout, int abiVersion)
{
- d_cp=0;
d_command=command;
d_timeout=timeout;
d_abiVersion = abiVersion;
CoWrapper::~CoWrapper()
{
- if(d_cp)
- delete d_cp;
}
-
void CoWrapper::launch()
{
if(d_cp)
throw ArgException("pipe-command is not specified");
if(isUnixSocket(d_command)) {
- d_cp = new UnixRemote(d_command, d_timeout);
+ d_cp = std::unique_ptr<CoRemote>(new UnixRemote(d_command, d_timeout));
}
else {
- auto coprocess = new CoProcess(d_command, d_timeout);
+ auto coprocess = std::unique_ptr<CoProcess>(new CoProcess(d_command, d_timeout));
coprocess->launch();
- d_cp = coprocess;
+ d_cp = std::move(coprocess);
}
d_cp->send("HELO\t"+std::to_string(d_abiVersion));
return;
}
catch(PDNSException &ae) {
- delete d_cp;
- d_cp=0;
+ d_cp.reset();
throw;
}
}
}
catch(PDNSException &ae) {
g_log<<Logger::Warning<<kBackendId<<" Unable to receive data from coprocess. "<<ae.reason<<endl;
- delete d_cp;
- d_cp=0;
+ d_cp.reset();
throw;
}
}
PipeBackend::PipeBackend(const string &suffix)
{
d_disavow=false;
- d_regex=nullptr;
signal(SIGCHLD, SIG_IGN);
setArgPrefix("pipe"+suffix);
try {
return;
try {
- d_regex=getArg("regex").empty() ? 0 : new Regex(getArg("regex"));
+ if (!getArg("regex").empty()) {
+ d_regex = std::unique_ptr<Regex>(new Regex(getArg("regex")));
+ }
d_regexstr=getArg("regex");
d_abiVersion = getArgAsNum("abi-version");
d_coproc=unique_ptr<CoWrapper> (new CoWrapper(getArg("command"), getArgAsNum("timeout"), getArgAsNum("abi-version")));
void PipeBackend::cleanup()
{
d_coproc.reset(0);
- delete d_regex;
+ d_regex.reset();
d_regexstr = string();
d_abiVersion = 0;
}
void send(const string &line);
void receive(string &line);
private:
- CoRemote* d_cp;
+ std::unique_ptr<CoRemote> d_cp;
string d_command;
void launch();
int d_timeout;
private:
void launch();
void cleanup();
- unique_ptr<CoWrapper> d_coproc;
+ std::unique_ptr<CoWrapper> d_coproc;
+ std::unique_ptr<Regex> d_regex;
DNSName d_qname;
QType d_qtype;
- Regex* d_regex;
string d_regexstr;
bool d_disavow;
int d_abiVersion;
#include "namespaces.hh"
-void* carbonDumpThread(void*)
+void carbonDumpThread()
try
{
setThreadName("pdns/carbonDump");
}
sleep(arg().asNum("carbon-interval"));
}
- return 0;
}
catch(std::exception& e)
{
g_log<<Logger::Error<<"Carbon thread died: "<<e.what()<<endl;
- return 0;
}
catch(PDNSException& e)
{
g_log<<Logger::Error<<"Carbon thread died, PDNSException: "<<e.reason<<endl;
- return 0;
}
catch(...)
{
g_log<<Logger::Error<<"Carbon thread died"<<endl;
- return 0;
}
}
}
-bool AuthPacketCache::get(DNSPacket *p, DNSPacket *cached)
+bool AuthPacketCache::get(DNSPacket& p, DNSPacket& cached)
{
if(!d_ttl) {
return false;
cleanupIfNeeded();
- uint32_t hash = canHashPacket(p->getString());
- p->setHash(hash);
+ uint32_t hash = canHashPacket(p.getString());
+ p.setHash(hash);
string value;
bool haveSomething;
time_t now = time(nullptr);
- auto& mc = getMap(p->qdomain);
+ auto& mc = getMap(p.qdomain);
{
TryReadLock rl(&mc.d_mut);
if(!rl.gotIt()) {
return false;
}
- haveSomething = getEntryLocked(mc.d_map, p->getString(), hash, p->qdomain, p->qtype.getCode(), p->d_tcp, now, value);
+ haveSomething = getEntryLocked(mc.d_map, p.getString(), hash, p.qdomain, p.qtype.getCode(), p.d_tcp, now, value);
}
if (!haveSomething) {
return false;
}
- if(cached->noparse(value.c_str(), value.size()) < 0) {
+ if(cached.noparse(value.c_str(), value.size()) < 0) {
return false;
}
(*d_statnumhit)++;
- cached->spoofQuestion(p); // for correct case
- cached->qdomain = p->qdomain;
- cached->qtype = p->qtype;
+ cached.spoofQuestion(p); // for correct case
+ cached.qdomain = p.qdomain;
+ cached.qtype = p.qtype;
return true;
}
return iter->tcp == tcp && iter->qtype == qtype && iter->qname == qname && queryMatches(iter->query, query, qname);
}
-void AuthPacketCache::insert(DNSPacket *q, DNSPacket *r, unsigned int maxTTL)
+void AuthPacketCache::insert(DNSPacket& q, DNSPacket& r, unsigned int maxTTL)
{
if(!d_ttl) {
return;
cleanupIfNeeded();
- if (ntohs(q->d.qdcount) != 1) {
+ if (ntohs(q.d.qdcount) != 1) {
return; // do not try to cache packets with multiple questions
}
- if (q->qclass != QClass::IN) // we only cache the INternet
+ if (q.qclass != QClass::IN) // we only cache the INternet
return;
uint32_t ourttl = std::min(d_ttl, maxTTL);
return;
}
- uint32_t hash = q->getHash();
+ uint32_t hash = q.getHash();
time_t now = time(nullptr);
CacheEntry entry;
entry.hash = hash;
entry.created = now;
entry.ttd = now + ourttl;
- entry.qname = q->qdomain;
- entry.qtype = q->qtype.getCode();
- entry.value = r->getString();
- entry.tcp = r->d_tcp;
- entry.query = q->getString();
+ entry.qname = q.qdomain;
+ entry.qtype = q.qtype.getCode();
+ entry.value = r.getString();
+ entry.tcp = r.d_tcp;
+ entry.query = q.getString();
auto& mc = getMap(entry.qname);
{
AuthPacketCache(size_t mapsCount=1024);
~AuthPacketCache();
- void insert(DNSPacket *q, DNSPacket *r, uint32_t maxTTL); //!< 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(DNSPacket& q, DNSPacket& r, uint32_t maxTTL); //!< 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
- bool get(DNSPacket *p, DNSPacket *q); //!< 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 get(DNSPacket& p, DNSPacket& q); //!< You need to spoof in the right ID with the DNSPacket.spoofID() method.
void cleanup(); //!< force the cache to preen itself from expired packets
uint64_t purge();
virtual ~GSQLBackend()
{
freeStatements();
- if(d_db)
- delete d_db;
+ d_db.reset();
}
void setDB(SSql *db)
{
freeStatements();
- delete d_db;
- d_db=db;
+ d_db=std::unique_ptr<SSql>(db);
if (d_db) {
d_db->setLog(::arg().mustDo("query-logging"));
allocateStatements();
unique_ptr<SSqlStatement> d_SearchCommentsQuery_stmt;
protected:
- SSql *d_db{nullptr};
+ std::unique_ptr<SSql> d_db{nullptr};
bool d_dnssecQueries;
bool d_inTransaction{false};
};
static bool g_quiet;
-static void* recvThread(const vector<Socket*>* sockets)
+static void* recvThread(const vector<std::unique_ptr<Socket>>* sockets)
{
vector<pollfd> rfds, fds;
for(const auto& s : *sockets) {
memcpy(&packet->at(packetSize - sizeof(addr)), &addr, sizeof(addr));
}
-static void sendPackets(const vector<Socket*>* sockets, const vector<vector<uint8_t>* >& packets, int qps, ComboAddress dest, const Netmask& ecsRange)
+static void sendPackets(const vector<std::unique_ptr<Socket>>& sockets, const vector<vector<uint8_t>* >& packets, int qps, ComboAddress dest, const Netmask& ecsRange)
{
unsigned int burst=100;
const auto nsecPerBurst=1*(unsigned long)(burst*1000000000.0/qps);
}
fillMSGHdr(&u.msgh, &u.iov, nullptr, 0, (char*)&(*p)[0], p->size(), &dest);
- if((ret=sendmsg((*sockets)[count % sockets->size()]->getHandle(),
+ if((ret=sendmsg(sockets[count % sockets.size()]->getHandle(),
&u.msgh, 0)))
if(ret < 0)
unixDie("sendmsg");
cout<<"Generated "<<unknown.size()<<" ready to use queries"<<endl;
}
- vector<Socket*> sockets;
+ vector<std::unique_ptr<Socket>> sockets;
ComboAddress dest;
try {
dest = ComboAddress(g_vm["destination"].as<string>(), 53);
return EXIT_FAILURE;
}
for(int i=0; i < 24; ++i) {
- Socket *sock = new Socket(dest.sin4.sin_family, SOCK_DGRAM);
+ auto sock = make_unique<Socket>(dest.sin4.sin_family, SOCK_DGRAM);
// sock->connect(dest);
setSocketSendBuffer(sock->getHandle(), 2000000);
setSocketReceiveBuffer(sock->getHandle(), 2000000);
- sockets.push_back(sock);
+ sockets.push_back(std::move(sock));
}
new thread(recvThread, &sockets);
uint32_t qps;
DTime dt;
dt.set();
- sendPackets(&sockets, toSend, qps, dest, ecsRange);
+ sendPackets(sockets, toSend, qps, dest, ecsRange);
const auto udiff = dt.udiffNoReset();
const auto realqps=toSend.size()/(udiff/1000000.0);
#include "threadname.hh"
#include "misc.hh"
+#include <thread>
+
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
#endif
StatBag S; //!< Statistics are gathered across PDNS via the StatBag class S
AuthPacketCache PC; //!< This is the main PacketCache, shared across all threads
AuthQueryCache QC;
-DNSProxy *DP;
-DynListener *dl;
+std::unique_ptr<DNSProxy> DP{nullptr};
+std::unique_ptr<DynListener> dl{nullptr};
CommunicatorClass Communicator;
shared_ptr<UDPNameserver> N;
int avg_latency;
try
{
int totcount=0;
- for(DNSDistributor* d : g_distributors) {
+ for(const auto& d : g_distributors) {
if(!d)
continue;
totcount += d->getQueueSize(); // this does locking and other things, so don't get smart
return !!p;
}
-void sendout(DNSPacket* a)
+static void sendout(std::unique_ptr<DNSPacket>& a)
{
if(!a)
return;
- N->send(a);
+ N->send(*a);
int diff=a->d_dt.udiff();
avg_latency=(int)(0.999*avg_latency+0.001*diff);
- delete a;
}
//! The qthread receives questions over the internet via the Nameserver class, and hands them to the Distributor for further processing
-void *qthread(void *number)
+static void qthread(unsigned int num)
try
{
setThreadName("pdns/receiver");
- DNSPacket *P;
- DNSDistributor *distributor = DNSDistributor::Create(::arg().asNum("distributor-threads", 1)); // the big dispatcher!
- int num = (int)(unsigned long)number;
- g_distributors[num] = distributor;
+ g_distributors[num] = DNSDistributor::Create(::arg().asNum("distributor-threads", 1));
+ DNSDistributor* distributor = g_distributors[num]; // the big dispatcher!
DNSPacket question(true);
DNSPacket cached(false);
// If we have SO_REUSEPORT then create a new port for all receiver threads
// other than the first one.
- if( number != NULL && N->canReusePort() ) {
+ if(N->canReusePort() ) {
NS = g_udpReceivers[num];
if (NS == nullptr) {
NS = N;
}
for(;;) {
- if(!(P=NS->receive(&question, buffer))) { // receive a packet inline
+ if(!NS->receive(question, buffer)) { // receive a packet inline
continue; // packet was broken, try again
}
numreceived++;
- if(P->d_remote.getSocklen()==sizeof(sockaddr_in))
+ if(question.d_remote.getSocklen()==sizeof(sockaddr_in))
numreceived4++;
else
numreceived6++;
- if(P->d_dnssecOk)
+ if(question.d_dnssecOk)
numreceiveddo++;
- if(P->d.qr)
+ if(question.d.qr)
continue;
- S.ringAccount("queries", P->qdomain, P->qtype);
- S.ringAccount("remotes",P->d_remote);
+ S.ringAccount("queries", question.qdomain, question.qtype);
+ S.ringAccount("remotes", question.d_remote);
if(logDNSQueries) {
string remote;
- if(P->hasEDNSSubnet())
- remote = P->getRemote().toString() + "<-" + P->getRealRemote().toString();
+ if(question.hasEDNSSubnet())
+ remote = question.getRemote().toString() + "<-" + question.getRealRemote().toString();
else
- remote = P->getRemote().toString();
- g_log << Logger::Notice<<"Remote "<< remote <<" wants '" << P->qdomain<<"|"<<P->qtype.getName() <<
- "', do = " <<P->d_dnssecOk <<", bufsize = "<< P->getMaxReplyLen();
- if(P->d_ednsRawPacketSizeLimit > 0 && P->getMaxReplyLen() != (unsigned int)P->d_ednsRawPacketSizeLimit)
- g_log<<" ("<<P->d_ednsRawPacketSizeLimit<<")";
+ remote = question.getRemote().toString();
+ g_log << Logger::Notice<<"Remote "<< remote <<" wants '" << question.qdomain<<"|"<<question.qtype.getName() <<
+ "', do = " <<question.d_dnssecOk <<", bufsize = "<< question.getMaxReplyLen();
+ if(question.d_ednsRawPacketSizeLimit > 0 && question.getMaxReplyLen() != (unsigned int)question.d_ednsRawPacketSizeLimit)
+ g_log<<" ("<<question.d_ednsRawPacketSizeLimit<<")";
g_log<<": ";
}
- if(PC.enabled() && (P->d.opcode != Opcode::Notify && P->d.opcode != Opcode::Update) && P->couldBeCached()) {
- bool haveSomething=PC.get(P, &cached); // does the PacketCache recognize this question?
+ if(PC.enabled() && (question.d.opcode != Opcode::Notify && question.d.opcode != Opcode::Update) && question.couldBeCached()) {
+ bool haveSomething=PC.get(question, cached); // does the PacketCache recognize this question?
if (haveSomething) {
if(logDNSQueries)
g_log<<"packetcache HIT"<<endl;
- cached.setRemote(&P->d_remote); // inlined
- cached.setSocket(P->getSocket()); // inlined
- cached.d_anyLocal = P->d_anyLocal;
- cached.setMaxReplyLen(P->getMaxReplyLen());
- cached.d.rd=P->d.rd; // copy in recursion desired bit
- cached.d.id=P->d.id;
+ cached.setRemote(&question.d_remote); // inlined
+ cached.setSocket(question.getSocket()); // inlined
+ cached.d_anyLocal = question.d_anyLocal;
+ cached.setMaxReplyLen(question.getMaxReplyLen());
+ cached.d.rd=question.d.rd; // copy in recursion desired bit
+ cached.d.id=question.d.id;
cached.commitD(); // commit d to the packet inlined
- NS->send(&cached); // answer it then inlined
- diff=P->d_dt.udiff();
+ NS->send(cached); // answer it then inlined
+ diff=question.d_dt.udiff();
avg_latency=(int)(0.999*avg_latency+0.001*diff); // 'EWMA'
continue;
}
g_log<<"packetcache MISS"<<endl;
try {
- distributor->question(P, &sendout); // otherwise, give to the distributor
+ distributor->question(question, &sendout); // otherwise, give to the distributor
}
catch(DistributorFatal& df) { // when this happens, we have leaked loads of memory. Bailing out time.
_exit(1);
}
}
- return 0;
}
catch(PDNSException& pe)
{
Utility::dropUserPrivs(newuid);
if(::arg().mustDo("resolver")){
- DP=new DNSProxy(::arg()["resolver"]);
+ DP=std::unique_ptr<DNSProxy>(new DNSProxy(::arg()["resolver"]));
DP->go();
}
// NOW SAFE TO CREATE THREADS!
dl->go();
- pthread_t qtid;
-
if(::arg().mustDo("webserver") || ::arg().mustDo("api"))
webserver.go();
TN->go(); // tcp nameserver launch
- // fork(); (this worked :-))
unsigned int max_rthreads= ::arg().asNum("receiver-threads", 1);
g_distributors.resize(max_rthreads);
- for(unsigned int n=0; n < max_rthreads; ++n)
- pthread_create(&qtid,0,qthread, reinterpret_cast<void *>(n)); // receives packets
+ for(unsigned int n=0; n < max_rthreads; ++n) {
+ std::thread t(qthread, n);
+ t.detach();
+ }
- pthread_create(&qtid,0,carbonDumpThread, 0); // runs even w/o carbon, might change @ runtime
+ std::thread carbonThread(carbonDumpThread); // runs even w/o carbon, might change @ runtime
#ifdef HAVE_SYSTEMD
/* If we are here, notify systemd that we are ay-ok! This might have some
extern StatBag S; //!< Statistics are gathered across PDNS via the StatBag class S
extern AuthPacketCache PC; //!< This is the main PacketCache, shared across all threads
extern AuthQueryCache QC;
-extern DNSProxy *DP;
-extern DynListener *dl;
+extern std::unique_ptr<DNSProxy> DP;
+extern std::unique_ptr<DynListener> dl;
extern CommunicatorClass Communicator;
extern std::shared_ptr<UDPNameserver> N;
extern vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
extern void declareStats();
extern void mainthread();
extern int isGuarded( char ** );
-void* carbonDumpThread(void*);
+void carbonDumpThread();
extern bool g_anyToTcp;
extern bool g_8bitDNS;
#ifdef HAVE_LUA_RECORDS
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/sequenced_index.hpp>
-#include <boost/scoped_ptr.hpp>
using namespace boost::multi_index;
#include <unistd.h>
bool justNotified(const DNSName &domain, const string &ip);
void addSuckRequest(const DNSName &domain, const ComboAddress& master);
void addSlaveCheckRequest(const DomainInfo& di, const ComboAddress& remote);
- void addTrySuperMasterRequest(DNSPacket *p);
+ void addTrySuperMasterRequest(const DNSPacket& p);
void notify(const DNSName &domain, const string &ip);
void mainloop();
void retrievalLoopThread();
map<pair<DNSName,string>,time_t>d_holes;
pthread_mutex_t d_holelock;
void suck(const DNSName &domain, const ComboAddress& remote);
- void ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, boost::scoped_ptr<AuthLua4>& pdl,
+ void ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, std::unique_ptr<AuthLua4>& pdl,
ZoneStatus& zs, vector<DNSRecord>* axfr);
void slaveRefresh(PacketHandler *P);
template<class Answer, class Question, class Backend> class Distributor
{
public:
- static Distributor *Create(int n=1); //!< Create a new Distributor with \param n threads
- typedef std::function<void(Answer*)> callback_t;
- virtual int question(Question *, callback_t callback) =0; //!< Submit a question to the Distributor
+ static Distributor* Create(int n=1); //!< Create a new Distributor with \param n threads
+ typedef std::function<void(std::unique_ptr<Answer>&)> callback_t;
+ virtual int question(Question&, callback_t callback) =0; //!< Submit a question to the Distributor
virtual int getQueueSize() =0; //!< Returns length of question queue
virtual bool isOverloaded() =0;
+ virtual ~Distributor() { cerr<<__func__<<endl;}
};
template<class Answer, class Question, class Backend> class SingleThreadDistributor
SingleThreadDistributor(const SingleThreadDistributor&) = delete;
void operator=(const SingleThreadDistributor&) = delete;
SingleThreadDistributor();
- typedef std::function<void(Answer*)> callback_t;
- int question(Question *, callback_t callback) override; //!< Submit a question to the Distributor
+ typedef std::function<void(std::unique_ptr<Answer>&)> callback_t;
+ int question(Question&, callback_t callback) override; //!< Submit a question to the Distributor
int getQueueSize() override {
return 0;
}
return false;
}
- ~SingleThreadDistributor() {
- if (b) delete b;
- }
private:
- Backend *b{0};
+ std::unique_ptr<Backend> b{nullptr};
};
template<class Answer, class Question, class Backend> class MultiThreadDistributor
MultiThreadDistributor(const MultiThreadDistributor&) = delete;
void operator=(const MultiThreadDistributor&) = delete;
MultiThreadDistributor(int n);
- typedef std::function<void(Answer*)> callback_t;
- int question(Question *, callback_t callback) override; //!< Submit a question to the Distributor
+ typedef std::function<void(std::unique_ptr<Answer>&)> callback_t;
+ int question(Question&, callback_t callback) override; //!< Submit a question to the Distributor
static void* makeThread(void *); //!< helper function to create our n threads
int getQueueSize() override {
return d_queued;
struct QuestionData
{
- Question *Q;
+ QuestionData(const Question& query): Q(query)
+ {
+ }
+
+ Question Q;
callback_t callback;
int id;
};
{
return d_overloadQueueLength && (d_queued > d_overloadQueueLength);
}
-
+
private:
int nextid;
time_t d_last_started;
};
//template<class Answer, class Question, class Backend>::nextid;
-template<class Answer, class Question, class Backend>Distributor<Answer,Question,Backend>* Distributor<Answer,Question,Backend>::Create(int n)
+template<class Answer, class Question, class Backend> Distributor<Answer,Question,Backend>* Distributor<Answer,Question,Backend>::Create(int n)
{
if( n == 1 )
- return new SingleThreadDistributor<Answer,Question,Backend>();
+ return new SingleThreadDistributor<Answer,Question,Backend>();
else
- return new MultiThreadDistributor<Answer,Question,Backend>( n );
+ return new MultiThreadDistributor<Answer,Question,Backend>( n );
}
template<class Answer, class Question, class Backend>SingleThreadDistributor<Answer,Question,Backend>::SingleThreadDistributor()
{
g_log<<Logger::Error<<"Only asked for 1 backend thread - operating unthreaded"<<endl;
try {
- b=new Backend;
+ b=make_unique<Backend>();
}
catch(const PDNSException &AE) {
g_log<<Logger::Error<<"Distributor caught fatal exception: "<<AE.reason<<endl;
int ournum=us->d_running++;
try {
- Backend *b=new Backend(); // this will answer our questions
+ std::unique_ptr<Backend> b= make_unique<Backend>(); // this will answer our questions
int queuetimeout=::arg().asNum("queue-limit");
for(;;) {
- QuestionData* QD;
- if(read(us->d_pipes[ournum].first, &QD, sizeof(QD)) != sizeof(QD))
+ QuestionData* tempQD = nullptr;
+ if(read(us->d_pipes[ournum].first, &tempQD, sizeof(tempQD)) != sizeof(tempQD))
unixDie("read");
--us->d_queued;
- Answer *a = nullptr;
+ std::unique_ptr<QuestionData> QD = std::unique_ptr<QuestionData>(tempQD);
+ tempQD = nullptr;
+ std::unique_ptr<Answer> a = nullptr;
- if(queuetimeout && QD->Q->d_dt.udiff()>queuetimeout*1000) {
- delete QD->Q;
- delete QD;
+ if(queuetimeout && QD->Q.d_dt.udiff()>queuetimeout*1000) {
S.inc("timedout-packets");
continue;
}
try {
if (!b) {
allowRetry=false;
- b=new Backend();
+ b=make_unique<Backend>();
}
a=b->question(QD->Q);
- delete QD->Q;
}
catch(const PDNSException &e) {
- delete b;
- b=NULL;
+ b.reset();
if (!allowRetry) {
g_log<<Logger::Error<<"Backend error: "<<e.reason<<endl;
- a=QD->Q->replyPacket();
+ a=QD->Q.replyPacket();
a->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", QD->Q->qdomain, QD->Q->qtype);
-
- delete QD->Q;
+ S.ringAccount("servfail-queries", QD->Q.qdomain, QD->Q.qtype);
} else {
g_log<<Logger::Notice<<"Backend error (retry once): "<<e.reason<<endl;
goto retry;
}
}
catch(...) {
- delete b;
- b=NULL;
+ b.reset();
if (!allowRetry) {
g_log<<Logger::Error<<"Caught unknown exception in Distributor thread "<<(long)pthread_self()<<endl;
- a=QD->Q->replyPacket();
+ a=QD->Q.replyPacket();
a->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", QD->Q->qdomain, QD->Q->qtype);
-
- delete QD->Q;
+ S.ringAccount("servfail-queries", QD->Q.qdomain, QD->Q.qtype);
} else {
g_log<<Logger::Warning<<"Caught unknown exception in Distributor thread "<<(long)pthread_self()<<" (retry once)"<<endl;
goto retry;
}
QD->callback(a);
- delete QD;
+ QD.reset();
}
- delete b;
+ b.reset();
}
catch(const PDNSException &AE) {
g_log<<Logger::Error<<"Distributor caught fatal exception: "<<AE.reason<<endl;
return 0;
}
-template<class Answer, class Question, class Backend>int SingleThreadDistributor<Answer,Question,Backend>::question(Question* q, callback_t callback)
+template<class Answer, class Question, class Backend>int SingleThreadDistributor<Answer,Question,Backend>::question(Question& q, callback_t callback)
{
- Answer *a = nullptr;
+ std::unique_ptr<Answer> a = nullptr;
bool allowRetry=true;
retry:
try {
if (!b) {
allowRetry=false;
- b=new Backend;
+ b=make_unique<Backend>();
}
a=b->question(q); // a can be NULL!
}
catch(const PDNSException &e) {
- delete b;
- b=NULL;
+ b.reset();
if (!allowRetry) {
g_log<<Logger::Error<<"Backend error: "<<e.reason<<endl;
- a=q->replyPacket();
+ a=q.replyPacket();
a->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", q->qdomain, q->qtype);
+ S.ringAccount("servfail-queries", q.qdomain, q.qtype);
} else {
g_log<<Logger::Notice<<"Backend error (retry once): "<<e.reason<<endl;
goto retry;
}
}
catch(...) {
- delete b;
- b=NULL;
+ b.reset();
if (!allowRetry) {
g_log<<Logger::Error<<"Caught unknown exception in Distributor thread "<<(unsigned long)pthread_self()<<endl;
- a=q->replyPacket();
+ a=q.replyPacket();
a->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", q->qdomain, q->qtype);
+ S.ringAccount("servfail-queries", q.qdomain, q.qtype);
} else {
g_log<<Logger::Warning<<"Caught unknown exception in Distributor thread "<<(unsigned long)pthread_self()<<" (retry once)"<<endl;
goto retry;
struct DistributorFatal{};
-template<class Answer, class Question, class Backend>int MultiThreadDistributor<Answer,Question,Backend>::question(Question* q, callback_t callback)
+template<class Answer, class Question, class Backend>int MultiThreadDistributor<Answer,Question,Backend>::question(Question& q, callback_t callback)
{
- q=new Question(*q);
-
// this is passed to other process over pipe and released there
- auto QD=new QuestionData();
- QD->Q=q;
+ auto QD=new QuestionData(q);
auto ret = QD->id = nextid++; // might be deleted after write!
QD->callback=callback;
++d_queued;
if(write(d_pipes[QD->id % d_pipes.size()].second, &QD, sizeof(QD)) != sizeof(QD)) {
--d_queued;
+ delete QD;
unixDie("write");
}
// this will leak the entire contents of all pipes, nothing will be freed. Respawn when this happens!
throw DistributorFatal();
}
-
+
return ret;
}
d_rrs.reserve(200);
}
-bool DNSPacket::couldBeCached()
+bool DNSPacket::couldBeCached() const
{
return !d_wantsnsid && qclass==QClass::IN && !d_havetsig;
}
qtype=newqtype;
}
-/** convenience function for creating a reply packet from a question packet. Do not forget to delete it after use! */
-DNSPacket *DNSPacket::replyPacket() const
+/** convenience function for creating a reply packet from a question packet. */
+std::unique_ptr<DNSPacket> DNSPacket::replyPacket() const
{
- DNSPacket *r=new DNSPacket(false);
+ auto r=make_unique<DNSPacket>(false);
r->setSocket(d_socket);
r->d_anyLocal=d_anyLocal;
r->setRemote(&d_remote);
return r;
}
-void DNSPacket::spoofQuestion(const DNSPacket *qd)
+void DNSPacket::spoofQuestion(const DNSPacket& qd)
{
d_wrapped=true; // if we do this, don't later on wrapup
string::size_type i=sizeof(d);
for(;;) {
- labellen = qd->d_rawpacket[i];
+ labellen = qd.d_rawpacket[i];
if(!labellen) break;
i++;
- d_rawpacket.replace(i, labellen, qd->d_rawpacket, i, labellen);
+ d_rawpacket.replace(i, labellen, qd.d_rawpacket, i, labellen);
i = i + labellen;
}
}
return d_haveednssubnet;
}
-bool DNSPacket::hasEDNS()
+bool DNSPacket::hasEDNS() const
{
return d_haveednssection;
}
DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer
void wrapup(); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer
- void spoofQuestion(const DNSPacket *qd); //!< paste in the exact right case of the question. Useful for PacketCache
+ void spoofQuestion(const DNSPacket& qd); //!< paste in the exact right case of the question. Useful for PacketCache
unsigned int getMinTTL(); //!< returns lowest TTL of any record in the packet
bool isEmpty(); //!< returns true if there are no rrs in the packet
vector<DNSZoneRecord*> getAnswerRecords(); //!< get a vector with DNSZoneRecords that are answers
void setCompress(bool compress);
- DNSPacket *replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
+ std::unique_ptr<DNSPacket> replyPacket() const; //!< convenience function that creates a virgin answer packet to this question
void commitD(); //!< copies 'd' into the stringbuffer
unsigned int getMaxReplyLen(); //!< retrieve the maximum length of the packet we should send in response
void setMaxReplyLen(int bytes); //!< set the max reply len (used when retrieving from the packet cache, and this changed)
- bool couldBeCached(); //!< returns 0 if this query should bypass the packet cache
+ bool couldBeCached() const; //!< returns 0 if this query should bypass the packet cache
bool hasEDNSSubnet() const;
- bool hasEDNS();
+ bool hasEDNS() const;
uint8_t getEDNSVersion() const { return d_ednsversion; };
void setEDNSRcode(uint16_t extRCode)
{
}
//! look up qname target with r->qtype, plonk it in the answer section of 'r' with name aname
-bool DNSProxy::completePacket(DNSPacket *r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask)
+bool DNSProxy::completePacket(std::unique_ptr<DNSPacket>& r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask)
{
if(r->d_tcp) {
vector<DNSZoneRecord> ips;
}
uint16_t id;
+ uint16_t qtype = r->qtype.getCode();
{
Lock l(&d_lock);
id=getID_locked();
ce.qtype = r->qtype.getCode();
ce.qname = target;
ce.anyLocal = r->d_anyLocal;
- ce.complete = r;
+ ce.complete = std::move(r);
ce.aname=aname;
ce.anameScopeMask = scopeMask;
- d_conntrack[id]=ce;
+ d_conntrack[id]=std::move(ce);
}
vector<uint8_t> packet;
- DNSPacketWriter pw(packet, target, r->qtype.getCode());
+ DNSPacketWriter pw(packet, target, qtype);
pw.getHeader()->rd=true;
pw.getHeader()->id=id ^ d_xor;
g_log<<Logger::Warning<<"Recursive query for remote "<<
i->second.remote.toStringWithPort()<<" with internal id "<<n<<
" was not answered by backend within timeout, reusing id"<<endl;
- delete i->second.complete;
+ i->second.complete.reset();
S.inc("recursion-unanswered");
}
return n;
reply=i->second.complete->getString();
iov.iov_base = (void*)reply.c_str();
iov.iov_len = reply.length();
- delete i->second.complete;
- i->second.complete=0;
+ i->second.complete.reset();
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
msgh.msg_name = (struct sockaddr*)&i->second.remote;
DNSProxy(const string &ip); //!< creates socket
~DNSProxy(); //<! dtor for DNSProxy
void go(); //!< launches the actual thread
- bool completePacket(DNSPacket *r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask);
+ bool completePacket(std::unique_ptr<DNSPacket>& r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask);
void mainloop(); //!< this is the main loop that receives reply packets and sends them out again
static void *launchhelper(void *p)
time_t created;
boost::optional<ComboAddress> anyLocal;
DNSName qname;
- DNSPacket* complete;
+ std::unique_ptr<DNSPacket> complete;
DNSName aname;
uint8_t anameScopeMask;
ComboAddress remote;
}
-Socket *s_socket;
+std::unique_ptr<Socket> s_socket = nullptr;
void receiveFromReference()
try
g_timeoutMsec=g_vm["timeout-msec"].as<uint32_t>();
PcapPacketReader pr(g_vm["pcap-source"].as<string>());
- s_socket= new Socket(AF_INET, SOCK_DGRAM);
+ s_socket= make_unique<Socket>(AF_INET, SOCK_DGRAM);
s_socket->setNonBlocking();
for(unsigned int fno=0; fno < files.size(); ++fno) {
PcapPacketReader pr(files[fno]);
- PcapPacketWriter* pw=0;
+ std::unique_ptr<PcapPacketWriter> pw=nullptr;
if(!g_vm["write-failures"].as<string>().empty())
- pw=new PcapPacketWriter(g_vm["write-failures"].as<string>(), pr);
+ pw=std::unique_ptr<PcapPacketWriter>(new PcapPacketWriter(g_vm["write-failures"].as<string>(), pr));
EDNSOpts edo;
while(pr.getUDPPacket()) {
throw PDNSException("tcp read failed");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=sock.read(creply+n, len-n);
+ numread=sock.read(creply.get()+n, len-n);
if(numread<0)
throw PDNSException("tcp read failed");
n+=numread;
}
- reply=string(creply, len);
- delete[] creply;
+ reply=string(creply.get(), len);
gettimeofday(&now, 0);
q->tcpUsec = makeUsec(now - tv);
#if !defined(HAVE_LUA)
-bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) { return false; }
+bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, const DNSPacket& packet) { return false; }
bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) { return false; }
-LuaContext* AuthLua4::getLua() { return 0; }
-DNSPacket *AuthLua4::prequery(DNSPacket *q) { return NULL; }
+LuaContext* AuthLua4::getLua() { return nullptr; }
+std::unique_ptr<DNSPacket> AuthLua4::prequery(const DNSPacket& q) { return nullptr; }
AuthLua4::~AuthLua4() { }
});
/* DNSPacket */
- d_lw->writeFunction("newDNSPacket", [](bool isQuery) { return new DNSPacket(isQuery); });
- d_lw->writeFunction("dupDNSPacket", [](const DNSPacket &orig) { return new DNSPacket(orig); });
+ d_lw->writeFunction("newDNSPacket", [](bool isQuery) { return make_unique<DNSPacket>(isQuery); });
+ d_lw->writeFunction("dupDNSPacket", [](const std::unique_ptr<DNSPacket> &orig) { return make_unique<DNSPacket>(*orig); });
d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("noparse", [](DNSPacket &p, const char *mesg, size_t len){ return p.noparse(mesg, len); });
d_lw->registerFunction<DNSPacket, int(const char *, size_t)>("parse", [](DNSPacket &p, const char *mesg, size_t len){ return p.parse(mesg, len); });
d_lw->registerFunction<DNSPacket, const std::string()>("getString", [](DNSPacket &p) { return p.getString(); });
d_lw->registerFunction<DNSPacket, void(const vector<pair<unsigned int, DNSRecord> >&)>("addRecords", [](DNSPacket &p, const vector<pair<unsigned int, DNSRecord> >& records){ for(const auto &dr: records){ DNSZoneRecord dzr; dzr.dr = std::get<1>(dr); dzr.auth = true; p.addRecord(dzr); }});
d_lw->registerFunction<DNSPacket, void(unsigned int, const DNSName&, const std::string&)>("setQuestion", [](DNSPacket &p, unsigned int opcode, const DNSName &name, const string &type){ QType qtype; qtype = type; p.setQuestion(static_cast<int>(opcode), name, static_cast<int>(qtype.getCode())); });
d_lw->registerFunction<DNSPacket, bool()>("isEmpty", [](DNSPacket &p){return p.isEmpty();});
- d_lw->registerFunction<DNSPacket, DNSPacket*()>("replyPacket",[](DNSPacket& p){ return p.replyPacket();});
+ d_lw->registerFunction<DNSPacket, std::unique_ptr<DNSPacket>()>("replyPacket",[](DNSPacket& p){ return p.replyPacket();});
d_lw->registerFunction<DNSPacket, bool()>("hasEDNSSubnet", [](DNSPacket &p){return p.hasEDNSSubnet();});
d_lw->registerFunction<DNSPacket, bool()>("hasEDNS",[](DNSPacket &p){return p.hasEDNS();});
d_lw->registerFunction<DNSPacket, unsigned int()>("getEDNSVersion",[](DNSPacket &p){return p.getEDNSVersion();});
}
-bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) {
+bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, const DNSPacket& packet) {
// default decision is all goes
- if (d_update_policy == NULL) return true;
+ if (d_update_policy == nullptr) return true;
UpdatePolicyQuery upq;
upq.qname = qname;
upq.qtype = qtype.getCode();
upq.zonename = zonename;
- upq.local = packet->getLocal();
- upq.remote = packet->getRemote();
- upq.realRemote = packet->getRealRemote();
- upq.tsigName = packet->getTSIGKeyname();
- upq.peerPrincipal = packet->d_peer_principal;
+ upq.local = packet.getLocal();
+ upq.remote = packet.getRemote();
+ upq.realRemote = packet.getRealRemote();
+ upq.tsigName = packet.getTSIGKeyname();
+ upq.peerPrincipal = packet.d_peer_principal;
return d_update_policy(upq);
}
-DNSPacket *AuthLua4::prequery(DNSPacket *q) {
- if (d_prequery == NULL) return NULL;
+std::unique_ptr<DNSPacket> AuthLua4::prequery(const DNSPacket& q) {
+ if (d_prequery == nullptr) return nullptr;
- DNSPacket *r = q->replyPacket();
- if (d_prequery(r))
+ auto r = q.replyPacket();
+ if (d_prequery(r.get()))
return r;
- delete r;
- return NULL;
+
+ return nullptr;
}
AuthLua4::~AuthLua4() { }
{
public:
AuthLua4();
- bool updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet);
+ bool updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, const DNSPacket& packet);
bool axfrfilter(const ComboAddress&, const DNSName&, const DNSResourceRecord&, std::vector<DNSResourceRecord>&);
LuaContext* getLua();
- DNSPacket *prequery(DNSPacket *p);
+ std::unique_ptr<DNSPacket> prequery(const DNSPacket& p);
~AuthLua4(); // this is so unique_ptr works with an incomplete type
protected:
g_log<<Logger::Critical<<"PDNS is deaf and mute! Not listening on any interfaces"<<endl;
}
-void UDPNameserver::send(DNSPacket *p)
+void UDPNameserver::send(DNSPacket& p)
{
- string buffer=p->getString();
- g_rs.submitResponse(*p, true);
+ string buffer=p.getString();
+ g_rs.submitResponse(p, true);
struct msghdr msgh;
struct iovec iov;
cmsgbuf_aligned cbuf;
- fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p->d_remote);
+ fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)buffer.c_str(), buffer.length(), &p.d_remote);
msgh.msg_control=NULL;
- if(p->d_anyLocal) {
- addCMsgSrcAddr(&msgh, &cbuf, p->d_anyLocal.get_ptr(), 0);
+ if(p.d_anyLocal) {
+ addCMsgSrcAddr(&msgh, &cbuf, p.d_anyLocal.get_ptr(), 0);
}
- DLOG(g_log<<Logger::Notice<<"Sending a packet to "<< p->getRemote() <<" ("<< buffer.length()<<" octets)"<<endl);
- if(buffer.length() > p->getMaxReplyLen()) {
- g_log<<Logger::Error<<"Weird, trying to send a message that needs truncation, "<< buffer.length()<<" > "<<p->getMaxReplyLen()<<". Question was for "<<p->qdomain<<"|"<<p->qtype.getName()<<endl;
+ DLOG(g_log<<Logger::Notice<<"Sending a packet to "<< p.getRemote() <<" ("<< buffer.length()<<" octets)"<<endl);
+ if(buffer.length() > p.getMaxReplyLen()) {
+ g_log<<Logger::Error<<"Weird, trying to send a message that needs truncation, "<< buffer.length()<<" > "<<p.getMaxReplyLen()<<". Question was for "<<p.qdomain<<"|"<<p.qtype.getName()<<endl;
}
- if(sendmsg(p->getSocket(), &msgh, 0) < 0)
- g_log<<Logger::Error<<"Error sending reply with sendmsg (socket="<<p->getSocket()<<", dest="<<p->d_remote.toStringWithPort()<<"): "<<stringerror()<<endl;
+ if(sendmsg(p.getSocket(), &msgh, 0) < 0)
+ g_log<<Logger::Error<<"Error sending reply with sendmsg (socket="<<p.getSocket()<<", dest="<<p.d_remote.toStringWithPort()<<"): "<<stringerror()<<endl;
}
-DNSPacket *UDPNameserver::receive(DNSPacket *prefilled, std::string& buffer)
+bool UDPNameserver::receive(DNSPacket& packet, std::string& buffer)
{
ComboAddress remote;
extern StatBag S;
if(remote.sin4.sin_port == 0) // would generate error on responding. sin4 also works for ipv6
return 0;
- DNSPacket *packet;
- if(prefilled) // they gave us a preallocated packet
- packet=prefilled;
- else
- packet=new DNSPacket(true); // don't forget to free it!
-
- packet->setSocket(sock);
- packet->setRemote(&remote);
+ packet.setSocket(sock);
+ packet.setRemote(&remote);
ComboAddress dest;
if(HarvestDestinationAddress(&msgh, &dest)) {
// cerr<<"Setting d_anyLocal to '"<<dest.toString()<<"'"<<endl;
- packet->d_anyLocal = dest;
+ packet.d_anyLocal = dest;
}
struct timeval recvtv;
if(HarvestTimestamp(&msgh, &recvtv)) {
- packet->d_dt.setTimeval(recvtv);
+ packet.d_dt.setTimeval(recvtv);
}
else
- packet->d_dt.set(); // timing
+ packet.d_dt.set(); // timing
- if(packet->parse(&buffer.at(0), (size_t) len)<0) {
+ if(packet.parse(&buffer.at(0), (size_t) len)<0) {
S.inc("corrupt-packets");
- S.ringAccount("remotes-corrupt", packet->d_remote);
+ S.ringAccount("remotes-corrupt", packet.d_remote);
- if(!prefilled)
- delete packet;
- return 0; // unable to parse
+ return false; // unable to parse
}
- return packet;
+ return true;
}
{
public:
UDPNameserver( bool additional_socket = false ); //!< Opens the socket
- DNSPacket *receive(DNSPacket *prefilled, std::string& buffer); //!< call this in a while or for(;;) loop to get packets
- void send(DNSPacket *); //!< send a DNSPacket. Will call DNSPacket::truncate() if over 512 bytes
+ bool receive(DNSPacket& packet, std::string& buffer); //!< call this in a while or for(;;) loop to get packets
+ void send(DNSPacket&); //!< send a DNSPacket. Will call DNSPacket::truncate() if over 512 bytes
inline bool canReusePort() {
#ifdef SO_REUSEPORT
return d_can_reuseport;
throw PDNSException("tcp read failed");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=sock.read(creply+n, len-n);
+ numread=sock.read(creply.get()+n, len-n);
if(numread<0)
throw PDNSException("tcp read failed");
n+=numread;
}
- string reply(creply, len);
- delete[] creply;
+ string reply(creply.get(), len);
MOADNSParser mdp(false, reply);
cout<<"Reply to question for qname='"<<mdp.d_qname<<"', qtype="<<DNSRecordContent::NumberToType(mdp.d_qtype)<<endl;
* @param sd SOAData of the zone for which CDNSKEY records sets should be added
* @return bool that shows if any records were added
**/
-bool PacketHandler::addCDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd)
+bool PacketHandler::addCDNSKEY(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd)
{
string publishCDNSKEY;
- d_dk.getFromMeta(p->qdomain, "PUBLISH-CDNSKEY", publishCDNSKEY);
+ d_dk.getFromMeta(p.qdomain, "PUBLISH-CDNSKEY", publishCDNSKEY);
if (publishCDNSKEY != "1")
return false;
DNSZoneRecord rr;
bool haveOne=false;
- DNSSECKeeper::keyset_t entryPoints = d_dk.getEntryPoints(p->qdomain);
+ DNSSECKeeper::keyset_t entryPoints = d_dk.getEntryPoints(p.qdomain);
for(const auto& value: entryPoints) {
rr.dr.d_type=QType::CDNSKEY;
rr.dr.d_ttl=sd.default_ttl;
- rr.dr.d_name=p->qdomain;
+ rr.dr.d_name=p.qdomain;
rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
r->addRecord(rr);
}
if(::arg().mustDo("direct-dnskey")) {
- B.lookup(QType(QType::CDNSKEY), p->qdomain, sd.domain_id, p);
+ B.lookup(QType(QType::CDNSKEY), p.qdomain, sd.domain_id, &p);
while(B.get(rr)) {
rr.dr.d_ttl=sd.default_ttl;
* @param sd SOAData of the zone for which DNSKEY records sets should be added
* @return bool that shows if any records were added
**/
-bool PacketHandler::addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd)
+bool PacketHandler::addDNSKEY(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd)
{
DNSZoneRecord rr;
bool haveOne=false;
- DNSSECKeeper::keyset_t keyset = d_dk.getKeys(p->qdomain);
+ DNSSECKeeper::keyset_t keyset = d_dk.getKeys(p.qdomain);
for(const auto& value: keyset) {
rr.dr.d_type=QType::DNSKEY;
rr.dr.d_ttl=sd.default_ttl;
- rr.dr.d_name=p->qdomain;
+ rr.dr.d_name=p.qdomain;
rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
r->addRecord(rr);
}
if(::arg().mustDo("direct-dnskey")) {
- B.lookup(QType(QType::DNSKEY), p->qdomain, sd.domain_id, p);
+ B.lookup(QType(QType::DNSKEY), p.qdomain, sd.domain_id, &p);
while(B.get(rr)) {
rr.dr.d_ttl=sd.default_ttl;
* used to determine record TTL.
* @return bool that shows if any records were added.
**/
-bool PacketHandler::addCDS(DNSPacket *p, DNSPacket *r, const SOAData& sd)
+bool PacketHandler::addCDS(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd)
{
string publishCDS;
- d_dk.getFromMeta(p->qdomain, "PUBLISH-CDS", publishCDS);
+ d_dk.getFromMeta(p.qdomain, "PUBLISH-CDS", publishCDS);
if (publishCDS.empty())
return false;
DNSZoneRecord rr;
rr.dr.d_type=QType::CDS;
rr.dr.d_ttl=sd.default_ttl;
- rr.dr.d_name=p->qdomain;
+ rr.dr.d_name=p.qdomain;
rr.auth=true;
bool haveOne=false;
- DNSSECKeeper::keyset_t keyset = d_dk.getEntryPoints(p->qdomain);
+ DNSSECKeeper::keyset_t keyset = d_dk.getEntryPoints(p.qdomain);
for(auto const &value : keyset) {
for(auto const &digestAlgo : digestAlgos){
- rr.dr.d_content=std::make_shared<DSRecordContent>(makeDSFromDNSKey(p->qdomain, value.first.getDNSKEY(), pdns_stou(digestAlgo)));
+ rr.dr.d_content=std::make_shared<DSRecordContent>(makeDSFromDNSKey(p.qdomain, value.first.getDNSKEY(), pdns_stou(digestAlgo)));
r->addRecord(rr);
haveOne=true;
}
}
if(::arg().mustDo("direct-dnskey")) {
- B.lookup(QType(QType::CDS), p->qdomain, sd.domain_id, p);
+ B.lookup(QType(QType::CDS), p.qdomain, sd.domain_id, &p);
while(B.get(rr)) {
rr.dr.d_ttl=sd.default_ttl;
}
/** This adds NSEC3PARAM records. Returns true if one was added */
-bool PacketHandler::addNSEC3PARAM(DNSPacket *p, DNSPacket *r, const SOAData& sd)
+bool PacketHandler::addNSEC3PARAM(const DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd)
{
DNSZoneRecord rr;
NSEC3PARAMRecordContent ns3prc;
- if(d_dk.getNSEC3PARAM(p->qdomain, &ns3prc)) {
+ if(d_dk.getNSEC3PARAM(p.qdomain, &ns3prc)) {
rr.dr.d_type=QType::NSEC3PARAM;
rr.dr.d_ttl=sd.default_ttl;
- rr.dr.d_name=p->qdomain;
+ rr.dr.d_name=p.qdomain;
ns3prc.d_flags = 0; // the NSEC3PARAM 'flag' is defined to always be zero in RFC5155.
rr.dr.d_content=std::make_shared<NSEC3PARAMRecordContent>(ns3prc);
rr.auth = true;
// 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, DNSName &target)
+int PacketHandler::doChaosRequest(const DNSPacket& p, std::unique_ptr<DNSPacket>& r, DNSName &target) const
{
DNSZoneRecord rr;
- if(p->qtype.getCode()==QType::TXT) {
+ if(p.qtype.getCode()==QType::TXT) {
static const DNSName versionbind("version.bind."), versionpdns("version.pdns."), idserver("id.server.");
if (target==versionbind || target==versionpdns) {
// modes: full, powerdns only, anonymous or custom
return 0;
}
-vector<DNSZoneRecord> PacketHandler::getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target)
+vector<DNSZoneRecord> PacketHandler::getBestReferralNS(DNSPacket& p, const SOAData& sd, const DNSName &target)
{
vector<DNSZoneRecord> ret;
DNSZoneRecord rr;
do {
if(subdomain == sd.qname) // stop at SOA
break;
- B.lookup(QType(QType::NS), subdomain, sd.domain_id, p);
+ B.lookup(QType(QType::NS), subdomain, sd.domain_id, &p);
while(B.get(rr)) {
ret.push_back(rr); // this used to exclude auth NS records for some reason
}
return ret;
}
-vector<DNSZoneRecord> PacketHandler::getBestDNAMESynth(DNSPacket *p, SOAData& sd, DNSName &target)
+vector<DNSZoneRecord> PacketHandler::getBestDNAMESynth(DNSPacket& p, const SOAData& sd, DNSName &target)
{
vector<DNSZoneRecord> ret;
DNSZoneRecord rr;
do {
DLOG(g_log<<"Attempting DNAME lookup for "<<subdomain<<", sd.qname="<<sd.qname<<endl);
- B.lookup(QType(QType::DNAME), subdomain, sd.domain_id, p);
+ B.lookup(QType(QType::DNAME), subdomain, sd.domain_id, &p);
while(B.get(rr)) {
ret.push_back(rr); // put in the original
rr.dr.d_type = QType::CNAME;
// Return best matching wildcard or next closer name
-bool PacketHandler::getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* ret)
+bool PacketHandler::getBestWildcard(DNSPacket& p, const SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* ret)
{
ret->clear();
DNSZoneRecord rr;
wildcard=subdomain;
while( subdomain.chopOff() && !haveSomething ) {
if (subdomain.empty()) {
- B.lookup(QType(QType::ANY), g_wildcarddnsname, sd.domain_id, p);
+ B.lookup(QType(QType::ANY), g_wildcarddnsname, sd.domain_id, &p);
} else {
- B.lookup(QType(QType::ANY), g_wildcarddnsname+subdomain, sd.domain_id, p);
+ B.lookup(QType(QType::ANY), g_wildcarddnsname+subdomain, sd.domain_id, &p);
}
while(B.get(rr)) {
#ifdef HAVE_LUA_RECORDS
DLOG(g_log<<"Have a wildcard LUA match, but not doing LUA record for this zone"<<endl);
continue;
}
-
+
DLOG(g_log<<"Have a wildcard LUA match"<<endl);
-
+
auto rec=getRR<LUARecordContent>(rr.dr);
if (!rec) {
continue;
}
- if(rec->d_type == QType::CNAME || rec->d_type == p->qtype.getCode() || (p->qtype.getCode() == QType::ANY && rec->d_type != QType::RRSIG)) {
+ if(rec->d_type == QType::CNAME || rec->d_type == p.qtype.getCode() || (p.qtype.getCode() == QType::ANY && rec->d_type != QType::RRSIG)) {
// noCache=true;
DLOG(g_log<<"Executing Lua: '"<<rec->getCode()<<"'"<<endl);
- auto recvec=luaSynth(rec->getCode(), target, sd.qname, sd.domain_id, *p, rec->d_type);
+ auto recvec=luaSynth(rec->getCode(), target, sd.qname, sd.domain_id, p, rec->d_type);
for(const auto& r : recvec) {
rr.dr.d_type = rec->d_type; // might be CNAME
rr.dr.d_content = r;
- rr.scopeMask = p->getRealRemote().getBits(); // this makes sure answer is a specific as your question
+ rr.scopeMask = p.getRealRemote().getBits(); // this makes sure answer is a specific as your question
ret->push_back(rr);
}
}
}
else
#endif
- if(rr.dr.d_type == p->qtype.getCode() || rr.dr.d_type == QType::CNAME || (p->qtype.getCode() == QType::ANY && rr.dr.d_type != QType::RRSIG)) {
+ if(rr.dr.d_type == p.qtype.getCode() || rr.dr.d_type == QType::CNAME || (p.qtype.getCode() == QType::ANY && rr.dr.d_type != QType::RRSIG)) {
ret->push_back(rr);
}
-
+
wildcard=g_wildcarddnsname+subdomain;
haveSomething=true;
}
if ( subdomain == sd.qname || haveSomething ) // stop at SOA or result
break;
- B.lookup(QType(QType::ANY), subdomain, sd.domain_id, p);
+ B.lookup(QType(QType::ANY), subdomain, sd.domain_id, &p);
if (B.get(rr)) {
DLOG(g_log<<"No wildcard match, ancestor exists"<<endl);
while (B.get(rr)) ;
}
/** dangling is declared true if we were unable to resolve everything */
-int PacketHandler::doAdditionalProcessingAndDropAA(DNSPacket *p, DNSPacket *r, const SOAData& soadata, bool retargeted)
+int PacketHandler::doAdditionalProcessingAndDropAA(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& soadata, bool retargeted)
{
DNSZoneRecord rr;
SOAData sd;
sd.db=0;
- if(p->qtype.getCode()!=QType::AXFR) { // this packet needs additional processing
+ if(p.qtype.getCode()!=QType::AXFR) { // this packet needs additional processing
// we now have a copy, push_back on packet might reallocate!
auto& records = r->getRRS();
vector<DNSZoneRecord> toAdd;
else
continue;
- B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), lookup, soadata.domain_id, p);
+ B.lookup(QType(d_doIPv6AdditionalProcessing ? QType::ANY : QType::A), lookup, soadata.domain_id, &p);
while(B.get(rr)) {
if(rr.dr.d_type != QType::A && rr.dr.d_type!=QType::AAAA)
}
-void PacketHandler::emitNSEC(DNSPacket *r, const SOAData& sd, const DNSName& name, const DNSName& next, int mode)
+void PacketHandler::emitNSEC(std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName& name, const DNSName& next, int mode)
{
NSECRecordContent nrc;
nrc.d_next = next;
r->addRecord(rr);
}
-void PacketHandler::emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMRecordContent& ns3prc, const DNSName& name, const string& namehash, const string& nexthash, int mode)
+void PacketHandler::emitNSEC3(std::unique_ptr<DNSPacket>& r, const SOAData& sd, const NSEC3PARAMRecordContent& ns3prc, const DNSName& name, const string& namehash, const string& nexthash, int mode)
{
NSEC3RecordContent n3rc;
n3rc.d_algorithm = ns3prc.d_algorithm;
mode 4 = Name Error Responses
mode 5 = Direct NSEC request
*/
-void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, int mode)
+void PacketHandler::addNSECX(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, int mode)
{
NSEC3PARAMRecordContent ns3rc;
bool narrow;
}
}
-bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, bool decrement, DNSName& unhashed, std::string& before, std::string& after, int mode)
+static bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, bool decrement, DNSName& unhashed, std::string& before, std::string& after, int mode=0)
{
bool ret;
if(narrow) { // nsec3-narrow
return ret;
}
-void PacketHandler::addNSEC3(DNSPacket *p, DNSPacket *r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, const NSEC3PARAMRecordContent& ns3rc, bool narrow, int mode)
+void PacketHandler::addNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, const NSEC3PARAMRecordContent& ns3rc, bool narrow, int mode)
{
DLOG(g_log<<"addNSEC3() mode="<<mode<<" auth="<<auth<<" target="<<target<<" wildcard="<<wildcard<<endl);
bool doBreak = false;
DNSZoneRecord rr;
while( closest.chopOff() && (closest != sd.qname)) { // stop at SOA
- B.lookup(QType(QType::ANY), closest, sd.domain_id, p);
+ B.lookup(QType(QType::ANY), closest, sd.domain_id, &p);
while(B.get(rr))
if (rr.auth)
doBreak = true;
}
}
-void PacketHandler::addNSEC(DNSPacket *p, DNSPacket *r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, int mode)
+void PacketHandler::addNSEC(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const DNSName& auth, int mode)
{
DLOG(g_log<<"addNSEC() mode="<<mode<<" auth="<<auth<<" target="<<target<<" wildcard="<<wildcard<<endl);
*/
-int PacketHandler::trySuperMaster(DNSPacket *p, const DNSName& tsigkeyname)
+int PacketHandler::trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname)
{
- if(p->d_tcp)
+ if(p.d_tcp)
{
// do it right now if the client is TCP
// rarely happens
}
}
-int PacketHandler::trySuperMasterSynchronous(const DNSPacket *p, const DNSName& tsigkeyname)
+int PacketHandler::trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname)
{
- ComboAddress remote = p->getRemote().setPort(53);
- if(p->hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote.toString())) {
- remote = p->getRealRemote().getNetwork();
+ ComboAddress remote = p.getRemote().setPort(53);
+ if(p.hasEDNSSubnet() && ::arg().contains("trusted-notification-proxy", remote.toString())) {
+ remote = p.getRealRemote().getNetwork();
}
Resolver::res_t nsset;
try {
Resolver resolver;
uint32_t theirserial;
- resolver.getSoaSerial(remote, p->qdomain, &theirserial);
- resolver.resolve(remote, p->qdomain, QType::NS, &nsset);
+ resolver.getSoaSerial(remote, p.qdomain, &theirserial);
+ resolver.resolve(remote, p.qdomain, QType::NS, &nsset);
}
catch(ResolverException &re) {
- g_log<<Logger::Error<<"Error resolving SOA or NS for "<<p->qdomain<<" at: "<< remote <<": "<<re.reason<<endl;
+ g_log<<Logger::Error<<"Error resolving SOA or NS for "<<p.qdomain<<" at: "<< remote <<": "<<re.reason<<endl;
return RCode::ServFail;
}
}
if(!haveNS) {
- g_log<<Logger::Error<<"While checking for supermaster, did not find NS for "<<p->qdomain<<" at: "<< remote <<endl;
+ g_log<<Logger::Error<<"While checking for supermaster, did not find NS for "<<p.qdomain<<" at: "<< remote <<endl;
return RCode::ServFail;
}
DNSBackend *db;
if (!::arg().mustDo("allow-unsigned-supermaster") && tsigkeyname.empty()) {
- g_log<<Logger::Error<<"Received unsigned NOTIFY for "<<p->qdomain<<" from potential supermaster "<<remote<<". Refusing."<<endl;
+ g_log<<Logger::Error<<"Received unsigned NOTIFY for "<<p.qdomain<<" from potential supermaster "<<remote<<". Refusing."<<endl;
return RCode::Refused;
}
- if(!B.superMasterBackend(remote.toString(), p->qdomain, nsset, &nameserver, &account, &db)) {
- g_log<<Logger::Error<<"Unable to find backend willing to host "<<p->qdomain<<" for potential supermaster "<<remote<<". Remote nameservers: "<<endl;
+ if(!B.superMasterBackend(remote.toString(), p.qdomain, nsset, &nameserver, &account, &db)) {
+ g_log<<Logger::Error<<"Unable to find backend willing to host "<<p.qdomain<<" for potential supermaster "<<remote<<". Remote nameservers: "<<endl;
for(const auto& rr: nsset) {
if(rr.qtype==QType::NS)
g_log<<Logger::Error<<rr.content<<endl;
return RCode::Refused;
}
try {
- db->createSlaveDomain(p->getRemote().toString(), p->qdomain, nameserver, account);
+ db->createSlaveDomain(p.getRemote().toString(), p.qdomain, nameserver, account);
if (tsigkeyname.empty() == false) {
vector<string> meta;
meta.push_back(tsigkeyname.toStringNoDot());
- db->setDomainMetadata(p->qdomain, "AXFR-MASTER-TSIG", meta);
+ db->setDomainMetadata(p.qdomain, "AXFR-MASTER-TSIG", meta);
}
}
catch(PDNSException& ae) {
- g_log<<Logger::Error<<"Database error trying to create "<<p->qdomain<<" for potential supermaster "<<remote<<": "<<ae.reason<<endl;
+ g_log<<Logger::Error<<"Database error trying to create "<<p.qdomain<<" for potential supermaster "<<remote<<": "<<ae.reason<<endl;
return RCode::ServFail;
}
- g_log<<Logger::Warning<<"Created new slave zone '"<<p->qdomain<<"' from supermaster "<<remote<<endl;
+ g_log<<Logger::Warning<<"Created new slave zone '"<<p.qdomain<<"' from supermaster "<<remote<<endl;
return RCode::NoError;
}
-int PacketHandler::processNotify(DNSPacket *p)
+int PacketHandler::processNotify(const DNSPacket& p)
{
/* now what?
was this notification from an approved address?
if master is higher -> do stuff
*/
- g_log<<Logger::Debug<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<endl;
+ g_log<<Logger::Debug<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<endl;
if(!::arg().mustDo("slave") && s_forwardNotify.empty()) {
- g_log<<Logger::Warning<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but slave support is disabled in the configuration"<<endl;
+ g_log<<Logger::Warning<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" but slave support is disabled in the configuration"<<endl;
return RCode::Refused;
}
// Sender verification
//
- if(!s_allowNotifyFrom.match((ComboAddress *) &p->d_remote ) || p->d_havetsig) {
- if (p->d_havetsig && p->getTSIGKeyname().empty() == false) {
- g_log<<Logger::Notice<<"Received secure NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<", with TSIG key '"<<p->getTSIGKeyname()<<"'"<<endl;
+ if(!s_allowNotifyFrom.match((ComboAddress *) &p.d_remote ) || p.d_havetsig) {
+ if (p.d_havetsig && p.getTSIGKeyname().empty() == false) {
+ g_log<<Logger::Notice<<"Received secure NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<", with TSIG key '"<<p.getTSIGKeyname()<<"'"<<endl;
} else {
- g_log<<Logger::Warning<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but the remote is not providing a TSIG key or in allow-notify-from (Refused)"<<endl;
+ g_log<<Logger::Warning<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" but the remote is not providing a TSIG key or in allow-notify-from (Refused)"<<endl;
return RCode::Refused;
}
}
- if ((!::arg().mustDo("allow-unsigned-notify") && !p->d_havetsig) || p->d_havetsig) {
- if (!p->d_havetsig) {
- g_log<<Logger::Warning<<"Received unsigned NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" while a TSIG key was required (Refused)"<<endl;
+ if ((!::arg().mustDo("allow-unsigned-notify") && !p.d_havetsig) || p.d_havetsig) {
+ if (!p.d_havetsig) {
+ g_log<<Logger::Warning<<"Received unsigned NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" while a TSIG key was required (Refused)"<<endl;
return RCode::Refused;
}
vector<string> meta;
- if (B.getDomainMetadata(p->qdomain,"AXFR-MASTER-TSIG",meta) && meta.size() > 0) {
+ if (B.getDomainMetadata(p.qdomain,"AXFR-MASTER-TSIG",meta) && meta.size() > 0) {
DNSName expected{meta[0]};
- if (p->getTSIGKeyname() != expected) {
- g_log<<Logger::Warning<<"Received secure NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<": expected TSIG key '"<<expected<<"', got '"<<p->getTSIGKeyname()<<"' (Refused)"<<endl;
+ if (p.getTSIGKeyname() != expected) {
+ g_log<<Logger::Warning<<"Received secure NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<": expected TSIG key '"<<expected<<"', got '"<<p.getTSIGKeyname()<<"' (Refused)"<<endl;
return RCode::Refused;
}
}
// Domain verification
//
DomainInfo di;
- if(!B.getDomainInfo(p->qdomain, di, false) || !di.backend) {
+ if(!B.getDomainInfo(p.qdomain, di, false) || !di.backend) {
if(::arg().mustDo("superslave")) {
- g_log<<Logger::Warning<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" for which we are not authoritative, trying supermaster"<<endl;
- return trySuperMaster(p, p->getTSIGKeyname());
+ g_log<<Logger::Warning<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" for which we are not authoritative, trying supermaster"<<endl;
+ return trySuperMaster(p, p.getTSIGKeyname());
}
- g_log<<Logger::Notice<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" for which we are not authoritative (Refused)"<<endl;
+ g_log<<Logger::Notice<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" for which we are not authoritative (Refused)"<<endl;
return RCode::Refused;
}
- if(::arg().contains("trusted-notification-proxy", p->getRemote().toString())) {
- g_log<<Logger::Error<<"Received NOTIFY for "<<p->qdomain<<" from trusted-notification-proxy "<< p->getRemote()<<endl;
+ if(::arg().contains("trusted-notification-proxy", p.getRemote().toString())) {
+ g_log<<Logger::Error<<"Received NOTIFY for "<<p.qdomain<<" from trusted-notification-proxy "<< p.getRemote()<<endl;
if(di.masters.empty()) {
- g_log<<Logger::Error<<"However, "<<p->qdomain<<" does not have any masters defined (Refused)"<<endl;
+ g_log<<Logger::Error<<"However, "<<p.qdomain<<" does not have any masters defined (Refused)"<<endl;
return RCode::Refused;
}
}
else if(::arg().mustDo("master") && di.kind == DomainInfo::Master) {
- g_log<<Logger::Warning<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" but we are master (Refused)"<<endl;
+ g_log<<Logger::Warning<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" but we are master (Refused)"<<endl;
return RCode::Refused;
}
- else if(!di.isMaster(p->getRemote())) {
- g_log<<Logger::Warning<<"Received NOTIFY for "<<p->qdomain<<" from "<<p->getRemote()<<" which is not a master (Refused)"<<endl;
+ else if(!di.isMaster(p.getRemote())) {
+ g_log<<Logger::Warning<<"Received NOTIFY for "<<p.qdomain<<" from "<<p.getRemote()<<" which is not a master (Refused)"<<endl;
return RCode::Refused;
}
if(!s_forwardNotify.empty()) {
set<string> forwardNotify(s_forwardNotify);
for(set<string>::const_iterator j=forwardNotify.begin();j!=forwardNotify.end();++j) {
- g_log<<Logger::Notice<<"Relaying notification of domain "<<p->qdomain<<" from "<<p->getRemote()<<" to "<<*j<<endl;
- Communicator.notify(p->qdomain,*j);
+ g_log<<Logger::Notice<<"Relaying notification of domain "<<p.qdomain<<" from "<<p.getRemote()<<" to "<<*j<<endl;
+ Communicator.notify(p.qdomain,*j);
}
}
if(::arg().mustDo("slave")) {
- g_log<<Logger::Debug<<"Queueing slave check for "<<p->qdomain<<endl;
- Communicator.addSlaveCheckRequest(di, p->d_remote);
+ g_log<<Logger::Debug<<"Queueing slave check for "<<p.qdomain<<endl;
+ Communicator.addSlaveCheckRequest(di, p.d_remote);
}
return 0;
}
-bool validDNSName(const DNSName &name)
+static bool validDNSName(const DNSName &name)
{
if (!g_8bitDNS) {
string::size_type pos, length;
return true;
}
-DNSPacket *PacketHandler::question(DNSPacket *p)
+std::unique_ptr<DNSPacket> PacketHandler::question(DNSPacket& p)
{
- DNSPacket *ret;
+ std::unique_ptr<DNSPacket> ret{nullptr};
if(d_pdl)
{
return ret;
}
- if(p->d.rd) {
+ if(p.d.rd) {
static AtomicCounter &rdqueries=*S.getPointer("rd-queries");
rdqueries++;
}
}
-void PacketHandler::makeNXDomain(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, const SOAData& sd)
+void PacketHandler::makeNXDomain(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const SOAData& sd)
{
DNSZoneRecord rr;
rr=makeEditedDNSZRFromSOAData(d_dk, sd, DNSResourceRecord::AUTHORITY);
r->setRcode(RCode::NXDomain);
}
-void PacketHandler::makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, const SOAData& sd, int mode)
+void PacketHandler::makeNOError(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const SOAData& sd, int mode)
{
DNSZoneRecord rr;
rr=makeEditedDNSZRFromSOAData(d_dk, sd, DNSResourceRecord::AUTHORITY);
addNSECX(p, r, target, wildcard, sd.qname, mode);
}
- S.ringAccount("noerror-queries", p->qdomain, p->qtype);
+ S.ringAccount("noerror-queries", p.qdomain, p.qtype);
}
-bool PacketHandler::addDSforNS(DNSPacket* p, DNSPacket* r, SOAData& sd, const DNSName& dsname)
+bool PacketHandler::addDSforNS(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const 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, sd.domain_id, p);
+ B.lookup(QType(QType::DS), dsname, sd.domain_id, &p);
DNSZoneRecord rr;
bool gotOne=false;
while(B.get(rr)) {
return gotOne;
}
-bool PacketHandler::tryReferral(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target, bool retargeted)
+bool PacketHandler::tryReferral(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName &target, bool retargeted)
{
vector<DNSZoneRecord> rrset = getBestReferralNS(p, sd, target);
if(rrset.empty())
return true;
}
-void PacketHandler::completeANYRecords(DNSPacket *p, DNSPacket*r, SOAData& sd, const DNSName &target)
+void PacketHandler::completeANYRecords(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName &target)
{
addNSECX(p, r, target, DNSName(), sd.qname, 5);
- if(sd.qname == p->qdomain) {
+ if(sd.qname == p.qdomain) {
addDNSKEY(p, r, sd);
addCDNSKEY(p, r, sd);
addCDS(p, r, sd);
}
}
-bool PacketHandler::tryDNAME(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target)
+bool PacketHandler::tryDNAME(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, DNSName &target)
{
if(!d_doDNAME)
return false;
}
return false;
}
-bool PacketHandler::tryWildcard(DNSPacket *p, DNSPacket*r, SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata)
+bool PacketHandler::tryWildcard(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata)
{
retargeted = nodata = false;
DNSName bestmatch;
}
//! Called by the Distributor to ask a question. Returns 0 in case of an error
-DNSPacket *PacketHandler::doQuestion(DNSPacket *p)
+std::unique_ptr<DNSPacket> PacketHandler::doQuestion(DNSPacket& p)
{
DNSZoneRecord rr;
SOAData sd;
DNSName haveAlias;
uint8_t aliasScopeMask;
- DNSPacket *r=nullptr;
+ std::unique_ptr<DNSPacket> r{nullptr};
bool noCache=false;
#ifdef HAVE_LUA_RECORDS
bool doLua=g_doLuaRecord;
#endif
- if(p->d.qr) { // QR bit from dns packet (thanks RA from N)
+ if(p.d.qr) { // QR bit from dns packet (thanks RA from N)
if(d_logDNSDetails)
- g_log<<Logger::Error<<"Received an answer (non-query) packet from "<<p->getRemote()<<", dropping"<<endl;
+ g_log<<Logger::Error<<"Received an answer (non-query) packet from "<<p.getRemote()<<", dropping"<<endl;
S.inc("corrupt-packets");
- S.ringAccount("remotes-corrupt", p->d_remote);
+ S.ringAccount("remotes-corrupt", p.d_remote);
return 0;
}
- if(p->d.tc) { // truncated query. MOADNSParser would silently parse this packet in an incomplete way.
+ if(p.d.tc) { // truncated query. MOADNSParser would silently parse this packet in an incomplete way.
if(d_logDNSDetails)
- g_log<<Logger::Error<<"Received truncated query packet from "<<p->getRemote()<<", dropping"<<endl;
+ g_log<<Logger::Error<<"Received truncated query packet from "<<p.getRemote()<<", dropping"<<endl;
S.inc("corrupt-packets");
- S.ringAccount("remotes-corrupt", p->d_remote);
+ S.ringAccount("remotes-corrupt", p.d_remote);
return 0;
}
- if (p->hasEDNS() && p->getEDNSVersion() > 0) {
- r = p->replyPacket();
+ if (p.hasEDNS() && p.getEDNSVersion() > 0) {
+ r = p.replyPacket();
// PacketWriter::addOpt will take care of setting this correctly in the packet
r->setEDNSRcode(ERCode::BADVERS);
return r;
}
- if(p->d_havetsig) {
+ if(p.d_havetsig) {
DNSName keyname;
string secret;
TSIGRecordContent trc;
- if(!p->checkForCorrectTSIG(&B, &keyname, &secret, &trc)) {
- r=p->replyPacket(); // generate an empty reply packet
+ if(!p.checkForCorrectTSIG(&B, &keyname, &secret, &trc)) {
+ r=p.replyPacket(); // generate an empty reply packet
if(d_logDNSDetails)
g_log<<Logger::Error<<"Received a TSIG signed message with a non-validating key"<<endl;
// RFC3007 describes that a non-secure message should be sending Refused for DNS Updates
- if (p->d.opcode == Opcode::Update)
+ if (p.d.opcode == Opcode::Update)
r->setRcode(RCode::Refused);
else
r->setRcode(RCode::NotAuth);
return r;
} else {
- getTSIGHashEnum(trc.d_algoName, p->d_tsig_algo);
- if (p->d_tsig_algo == TSIG_GSS) {
+ getTSIGHashEnum(trc.d_algoName, p.d_tsig_algo);
+ if (p.d_tsig_algo == TSIG_GSS) {
GssContext gssctx(keyname);
- if (!gssctx.getPeerPrincipal(p->d_peer_principal)) {
+ if (!gssctx.getPeerPrincipal(p.d_peer_principal)) {
g_log<<Logger::Warning<<"Failed to extract peer principal from GSS context with keyname '"<<keyname<<"'"<<endl;
}
}
}
- p->setTSIGDetails(trc, keyname, secret, trc.d_mac); // this will get copied by replyPacket()
+ p.setTSIGDetails(trc, keyname, secret, trc.d_mac); // this will get copied by replyPacket()
noCache=true;
}
- r=p->replyPacket(); // generate an empty reply packet, possibly with TSIG details inside
+ r=p.replyPacket(); // generate an empty reply packet, possibly with TSIG details inside
- if (p->qtype == QType::TKEY) {
+ if (p.qtype == QType::TKEY) {
this->tkeyHandler(p, r);
return r;
}
// XXX FIXME do this in DNSPacket::parse ?
- if(!validDNSName(p->qdomain)) {
+ if(!validDNSName(p.qdomain)) {
if(d_logDNSDetails)
- g_log<<Logger::Error<<"Received a malformed qdomain from "<<p->getRemote()<<", '"<<p->qdomain<<"': sending servfail"<<endl;
+ g_log<<Logger::Error<<"Received a malformed qdomain from "<<p.getRemote()<<", '"<<p.qdomain<<"': sending servfail"<<endl;
S.inc("corrupt-packets");
- S.ringAccount("remotes-corrupt", p->d_remote);
+ S.ringAccount("remotes-corrupt", p.d_remote);
S.inc("servfail-packets");
r->setRcode(RCode::ServFail);
return r;
}
- if(p->d.opcode) { // non-zero opcode (again thanks RA!)
- if(p->d.opcode==Opcode::Update) {
+ if(p.d.opcode) { // non-zero opcode (again thanks RA!)
+ if(p.d.opcode==Opcode::Update) {
S.inc("dnsupdate-queries");
int res=processUpdate(p);
if (res == RCode::Refused)
r->setOpcode(Opcode::Update);
return r;
}
- else if(p->d.opcode==Opcode::Notify) {
+ else if(p.d.opcode==Opcode::Notify) {
S.inc("incoming-notifications");
int res=processNotify(p);
if(res>=0) {
r->setOpcode(Opcode::Notify);
return r;
}
- delete r;
return 0;
}
- g_log<<Logger::Error<<"Received an unknown opcode "<<p->d.opcode<<" from "<<p->getRemote()<<" for "<<p->qdomain<<endl;
+ g_log<<Logger::Error<<"Received an unknown opcode "<<p.d.opcode<<" from "<<p.getRemote()<<" for "<<p.qdomain<<endl;
r->setRcode(RCode::NotImp);
return r;
}
- // g_log<<Logger::Warning<<"Query for '"<<p->qdomain<<"' "<<p->qtype.getName()<<" from "<<p->getRemote()<< " (tcp="<<p->d_tcp<<")"<<endl;
+ // g_log<<Logger::Warning<<"Query for '"<<p.qdomain<<"' "<<p.qtype.getName()<<" from "<<p.getRemote()<< " (tcp="<<p.d_tcp<<")"<<endl;
- if(p->qtype.getCode()==QType::IXFR) {
+ if(p.qtype.getCode()==QType::IXFR) {
r->setRcode(RCode::Refused);
return r;
}
- DNSName target=p->qdomain;
+ DNSName target=p.qdomain;
// catch chaos qclass requests
- if(p->qclass == QClass::CHAOS) {
+ if(p.qclass == QClass::CHAOS) {
if (doChaosRequest(p,r,target))
goto sendit;
else
}
// we only know about qclass IN (and ANY), send Refused for everything else.
- if(p->qclass != QClass::IN && p->qclass!=QClass::ANY) {
+ if(p.qclass != QClass::IN && p.qclass!=QClass::ANY) {
r->setRcode(RCode::Refused);
return r;
}
// send TC for udp ANY query if any-to-tcp is enabled.
- if(p->qtype.getCode() == QType::ANY && !p->d_tcp && g_anyToTcp) {
+ if(p.qtype.getCode() == QType::ANY && !p.d_tcp && g_anyToTcp) {
r->d.tc = 1;
r->commitD();
return r;
}
// for qclass ANY the response should never be authoritative unless the response covers all classes.
- if(p->qclass==QClass::ANY)
+ if(p.qclass==QClass::ANY)
r->setA(false);
retargeted:;
if(retargetcount > 10) { // XXX FIXME, retargetcount++?
- g_log<<Logger::Warning<<"Abort CNAME chain resolution after "<<--retargetcount<<" redirects, sending out servfail. Initial query: '"<<p->qdomain<<"'"<<endl;
- delete r;
- r=p->replyPacket();
+ g_log<<Logger::Warning<<"Abort CNAME chain resolution after "<<--retargetcount<<" redirects, sending out servfail. Initial query: '"<<p.qdomain<<"'"<<endl;
+ r=p.replyPacket();
r->setRcode(RCode::ServFail);
return r;
}
- if(!B.getAuth(target, p->qtype, &sd)) {
+ if(!B.getAuth(target, p.qtype, &sd)) {
DLOG(g_log<<Logger::Error<<"We have no authority over zone '"<<target<<"'"<<endl);
if(!retargetcount) {
r->setA(false); // drop AA if we never had a SOA in the first place
DLOG(g_log<<Logger::Error<<"We have authority, zone='"<<sd.qname<<"', id="<<sd.domain_id<<endl);
authSet.insert(sd.qname);
- d_dnssec=(p->d_dnssecOk && d_dk.isSecuredZone(sd.qname));
+ d_dnssec=(p.d_dnssecOk && d_dk.isSecuredZone(sd.qname));
doSigs |= d_dnssec;
if(!retargetcount) r->qdomainzone=sd.qname;
- if(sd.qname==p->qdomain) {
- if(p->qtype.getCode() == QType::DNSKEY)
+ if(sd.qname==p.qdomain) {
+ if(p.qtype.getCode() == QType::DNSKEY)
{
if(addDNSKEY(p, r, sd))
goto sendit;
}
- else if(p->qtype.getCode() == QType::CDNSKEY)
+ else if(p.qtype.getCode() == QType::CDNSKEY)
{
if(addCDNSKEY(p,r, sd))
goto sendit;
}
- else if(p->qtype.getCode() == QType::CDS)
+ else if(p.qtype.getCode() == QType::CDS)
{
if(addCDS(p,r, sd))
goto sendit;
}
- else if(d_dnssec && p->qtype.getCode() == QType::NSEC3PARAM)
+ else if(d_dnssec && p.qtype.getCode() == QType::NSEC3PARAM)
{
if(addNSEC3PARAM(p,r, sd))
goto sendit;
}
}
- if(p->qtype.getCode() == QType::SOA && sd.qname==p->qdomain) {
+ if(p.qtype.getCode() == QType::SOA && sd.qname==p.qdomain) {
rr=makeEditedDNSZRFromSOAData(d_dk, sd);
r->addRecord(rr);
goto sendit;
}
// this TRUMPS a cname!
- if(d_dnssec && p->qtype.getCode() == QType::NSEC && !d_dk.getNSEC3PARAM(sd.qname, 0)) {
+ if(d_dnssec && p.qtype.getCode() == QType::NSEC && !d_dk.getNSEC3PARAM(sd.qname, 0)) {
addNSEC(p, r, target, DNSName(), sd.qname, 5);
if (!r->isEmpty())
goto sendit;
}
// this TRUMPS a cname!
- if(p->qtype.getCode() == QType::RRSIG) {
- g_log<<Logger::Info<<"Direct RRSIG query for "<<target<<" from "<<p->getRemote()<<endl;
+ if(p.qtype.getCode() == QType::RRSIG) {
+ g_log<<Logger::Info<<"Direct RRSIG query for "<<target<<" from "<<p.getRemote()<<endl;
r->setRcode(RCode::Refused);
goto sendit;
}
DLOG(g_log<<"Checking for referrals first, unless this is a DS query"<<endl);
- if(p->qtype.getCode() != QType::DS && tryReferral(p, r, sd, target, retargetcount))
+ if(p.qtype.getCode() != QType::DS && tryReferral(p, r, sd, target, retargetcount))
goto sendit;
DLOG(g_log<<"Got no referrals, trying ANY"<<endl);
#endif
// see what we get..
- B.lookup(QType(QType::ANY), target, sd.domain_id, p);
+ B.lookup(QType(QType::ANY), target, sd.domain_id, &p);
rrset.clear();
haveAlias.trimToLabels(0);
aliasScopeMask = 0;
if (!rec) {
continue;
}
- if(rec->d_type == QType::CNAME || rec->d_type == p->qtype.getCode() || (p->qtype.getCode() == QType::ANY && rec->d_type != QType::RRSIG)) {
+ if(rec->d_type == QType::CNAME || rec->d_type == p.qtype.getCode() || (p.qtype.getCode() == QType::ANY && rec->d_type != QType::RRSIG)) {
noCache=true;
try {
- auto recvec=luaSynth(rec->getCode(), target, sd.qname, sd.domain_id, *p, rec->d_type);
+ auto recvec=luaSynth(rec->getCode(), target, sd.qname, sd.domain_id, p, rec->d_type);
if(!recvec.empty()) {
for(const auto& r : recvec) {
rr.dr.d_type = rec->d_type; // might be CNAME
rr.dr.d_content = r;
- rr.scopeMask = p->getRealRemote().getBits(); // this makes sure answer is a specific as your question
+ rr.scopeMask = p.getRealRemote().getBits(); // this makes sure answer is a specific as your question
rrset.push_back(rr);
}
- if(rec->d_type == QType::CNAME && p->qtype.getCode() != QType::CNAME)
+ if(rec->d_type == QType::CNAME && p.qtype.getCode() != QType::CNAME)
weRedirected = 1;
else
weDone = 1;
}
}
catch(std::exception &e) {
- r=p->replyPacket();
+ r=p.replyPacket();
r->setRcode(RCode::ServFail);
return r;
}
#endif
//cerr<<"got content: ["<<rr.content<<"]"<<endl;
- if (!d_dnssec && p->qtype.getCode() == QType::ANY && (rr.dr.d_type == QType:: DNSKEY || rr.dr.d_type == QType::NSEC3PARAM))
+ if (!d_dnssec && p.qtype.getCode() == QType::ANY && (rr.dr.d_type == QType:: DNSKEY || rr.dr.d_type == QType::NSEC3PARAM))
continue; // Don't send dnssec info.
if (rr.dr.d_type == QType::RRSIG) // RRSIGS are added later any way.
continue; // TODO: this actually means addRRSig should check if the RRSig is already there
- // cerr<<"Auth: "<<rr.auth<<", "<<(rr.dr.d_type == p->qtype)<<", "<<rr.dr.d_type.getName()<<endl;
- if((p->qtype.getCode() == QType::ANY || rr.dr.d_type == p->qtype.getCode()) && rr.auth)
+ // cerr<<"Auth: "<<rr.auth<<", "<<(rr.dr.d_type == p.qtype)<<", "<<rr.dr.d_type.getName()<<endl;
+ if((p.qtype.getCode() == QType::ANY || rr.dr.d_type == p.qtype.getCode()) && rr.auth)
weDone=1;
// the line below fakes 'unauth NS' for delegations for non-DNSSEC backends.
- if((rr.dr.d_type == p->qtype.getCode() && !rr.auth) || (rr.dr.d_type == QType::NS && (!rr.auth || !(sd.qname==rr.dr.d_name))))
+ if((rr.dr.d_type == p.qtype.getCode() && !rr.auth) || (rr.dr.d_type == QType::NS && (!rr.auth || !(sd.qname==rr.dr.d_name))))
weHaveUnauth=1;
- if(rr.dr.d_type == QType::CNAME && p->qtype.getCode() != QType::CNAME)
+ if(rr.dr.d_type == QType::CNAME && p.qtype.getCode() != QType::CNAME)
weRedirected=1;
- if(DP && rr.dr.d_type == QType::ALIAS && (p->qtype.getCode() == QType::A || p->qtype.getCode() == QType::AAAA || p->qtype.getCode() == QType::ANY)) {
+ if(DP && rr.dr.d_type == QType::ALIAS && (p.qtype.getCode() == QType::A || p.qtype.getCode() == QType::AAAA || p.qtype.getCode() == QType::ANY)) {
if (!d_doExpandALIAS) {
g_log<<Logger::Info<<"ALIAS record found for "<<target<<", but ALIAS expansion is disabled."<<endl;
continue;
DLOG(g_log<<"After first ANY query for '"<<target<<"', id="<<sd.domain_id<<": weDone="<<weDone<<", weHaveUnauth="<<weHaveUnauth<<", weRedirected="<<weRedirected<<", haveAlias='"<<haveAlias<<"'"<<endl);
- if(p->qtype.getCode() == QType::DS && weHaveUnauth && !weDone && !weRedirected) {
+ if(p.qtype.getCode() == QType::DS && weHaveUnauth && !weDone && !weRedirected) {
DLOG(g_log<<"Q for DS of a name for which we do have NS, but for which we don't have DS; need to provide an AUTH answer that shows we don't"<<endl);
makeNOError(p, r, target, DNSName(), sd, 1);
goto sendit;
}
- if(!haveAlias.empty() && (!weDone || p->qtype.getCode() == QType::ANY)) {
+ if(!haveAlias.empty() && (!weDone || p.qtype.getCode() == QType::ANY)) {
DLOG(g_log<<Logger::Warning<<"Found nothing that matched for '"<<target<<"', but did get alias to '"<<haveAlias<<"', referring"<<endl);
DP->completePacket(r, haveAlias, target, aliasScopeMask);
return 0;
// referral for DS query
- if(p->qtype.getCode() == QType::DS) {
+ if(p.qtype.getCode() == QType::DS) {
DLOG(g_log<<"Qtype is DS"<<endl);
bool doReferral = true;
if(d_dk.doesDNSSEC()) {
}
else
{
- if (!(((p->qtype.getCode() == QType::CNAME) || (p->qtype.getCode() == QType::ANY)) && retargetcount > 0))
+ if (!(((p.qtype.getCode() == QType::CNAME) || (p.qtype.getCode() == QType::ANY)) && retargetcount > 0))
makeNXDomain(p, r, target, wildcard, sd);
}
if(loopRR.dr.d_type == QType::LUA)
continue;
#endif
- if((p->qtype.getCode() == QType::ANY || loopRR.dr.d_type == p->qtype.getCode()) && loopRR.dr.d_type && loopRR.dr.d_type != QType::ALIAS && loopRR.auth) {
+ if((p.qtype.getCode() == QType::ANY || loopRR.dr.d_type == p.qtype.getCode()) && loopRR.dr.d_type && loopRR.dr.d_type != QType::ALIAS && loopRR.auth) {
r->addRecord(loopRR);
haveRecords = true;
}
}
if (haveRecords) {
- if(d_dnssec && p->qtype.getCode() == QType::ANY)
+ if(d_dnssec && p.qtype.getCode() == QType::ANY)
completeANYRecords(p, r, sd, target);
}
else
goto sendit;
// check whether this could be fixed easily
// if (*(rr.dr.d_name.rbegin()) == '.') {
- // g_log<<Logger::Error<<"Should not get here ("<<p->qdomain<<"|"<<p->qtype.getCode()<<"): you have a trailing dot, this could be the problem (or run pdnsutil rectify-zone " <<sd.qname<<")"<<endl;
+ // g_log<<Logger::Error<<"Should not get here ("<<p.qdomain<<"|"<<p.qtype.getCode()<<"): you have a trailing dot, this could be the problem (or run pdnsutil rectify-zone " <<sd.qname<<")"<<endl;
// } else {
- g_log<<Logger::Error<<"Should not get here ("<<p->qdomain<<"|"<<p->qtype.getCode()<<"): please run pdnsutil rectify-zone "<<sd.qname<<endl;
+ g_log<<Logger::Error<<"Should not get here ("<<p.qdomain<<"|"<<p.qtype.getCode()<<"): please run pdnsutil rectify-zone "<<sd.qname<<endl;
// }
}
else {
sendit:;
if(doAdditionalProcessingAndDropAA(p, r, sd, retargetcount)<0) {
- delete r;
return 0;
}
if(doSigs)
addRRSigs(d_dk, B, authSet, r->getRRS());
- if(PC.enabled() && !noCache && p->couldBeCached())
- PC.insert(p, r, r->getMinTTL()); // in the packet cache
+ if(PC.enabled() && !noCache && p.couldBeCached())
+ PC.insert(p, *r, r->getMinTTL()); // in the packet cache
}
- catch(DBException &e) {
+ catch(const DBException &e) {
g_log<<Logger::Error<<"Backend reported condition which prevented lookup ("+e.reason+") sending out servfail"<<endl;
- delete r;
- r=p->replyPacket(); // generate an empty reply packet
+ r=p.replyPacket(); // generate an empty reply packet
r->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", p->qdomain, p->qtype);
+ S.ringAccount("servfail-queries", p.qdomain, p.qtype);
}
- catch(PDNSException &e) {
+ catch(const PDNSException &e) {
g_log<<Logger::Error<<"Backend reported permanent error which prevented lookup ("+e.reason+"), aborting"<<endl;
- delete r;
throw; // we WANT to die at this point
}
- catch(std::exception &e) {
- g_log<<Logger::Error<<"Exception building answer packet for "<<p->qdomain<<"/"<<p->qtype.getName()<<" ("<<e.what()<<") sending out servfail"<<endl;
- delete r;
- r=p->replyPacket(); // generate an empty reply packet
+ catch(const std::exception &e) {
+ g_log<<Logger::Error<<"Exception building answer packet for "<<p.qdomain<<"/"<<p.qtype.getName()<<" ("<<e.what()<<") sending out servfail"<<endl;
+ r=p.replyPacket(); // generate an empty reply packet
r->setRcode(RCode::ServFail);
S.inc("servfail-packets");
- S.ringAccount("servfail-queries", p->qdomain, p->qtype);
+ S.ringAccount("servfail-queries", p.qdomain, p.qtype);
}
return r;
class PacketHandler
{
public:
- DNSPacket *doQuestion(DNSPacket *); //!< hand us a DNS packet with a question, we give you an answer
- DNSPacket *question(DNSPacket *); //!< hand us a DNS packet with a question, we give you an answer
+ std::unique_ptr<DNSPacket> doQuestion(DNSPacket&); //!< hand us a DNS packet with a question, we give you an answer
+ std::unique_ptr<DNSPacket> question(DNSPacket&); //!< hand us a DNS packet with a question, we give you an answer
PacketHandler();
~PacketHandler(); // defined in packethandler.cc, and does --count
static int numRunning(){return s_count;}; //!< Returns the number of running PacketHandlers. Called by Distributor
UeberBackend *getBackend();
- int trySuperMasterSynchronous(const DNSPacket *p, const DNSName& tsigkeyname);
+ int trySuperMasterSynchronous(const DNSPacket& p, const DNSName& tsigkeyname);
static NetmaskGroup s_allowNotifyFrom;
static set<string> s_forwardNotify;
private:
- int trySuperMaster(DNSPacket *p, const DNSName& tsigkeyname);
- int processNotify(DNSPacket *);
- void addRootReferral(DNSPacket *r);
- int doChaosRequest(DNSPacket *p, DNSPacket *r, DNSName &target);
- bool addDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd);
- bool addCDNSKEY(DNSPacket *p, DNSPacket *r, const SOAData& sd);
- bool addCDS(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 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(DNSPacket *r, const SOAData& sd, const DNSName& name, const DNSName& next, int mode);
- void emitNSEC3(DNSPacket *r, const SOAData& sd, const NSEC3PARAMRecordContent &ns3rc, const DNSName& unhashed, const string& begin, const string& end, int mode);
- int processUpdate(DNSPacket *p);
- int forwardPacket(const string &msgPrefix, DNSPacket *p, DomainInfo *di);
+ int trySuperMaster(const DNSPacket& p, const DNSName& tsigkeyname);
+ int processNotify(const DNSPacket& );
+ void addRootReferral(DNSPacket& r);
+ int doChaosRequest(const DNSPacket& p, std::unique_ptr<DNSPacket>& r, DNSName &target) const;
+ bool addDNSKEY(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
+ bool addCDNSKEY(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
+ bool addCDS(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
+ bool addNSEC3PARAM(const DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd);
+ int doAdditionalProcessingAndDropAA(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, bool retargeted);
+ void addNSECX(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName &auth, int mode);
+ void addNSEC(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, int mode);
+ void addNSEC3(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName &target, const DNSName &wildcard, const DNSName& auth, const NSEC3PARAMRecordContent& nsec3param, bool narrow, int mode);
+ void emitNSEC(std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName& name, const DNSName& next, int mode);
+ void emitNSEC3(std::unique_ptr<DNSPacket>& r, const SOAData& sd, const NSEC3PARAMRecordContent &ns3rc, const DNSName& unhashed, const string& begin, const string& end, int mode);
+ int processUpdate(DNSPacket& p);
+ int forwardPacket(const string &msgPrefix, const DNSPacket& p, const DomainInfo& di);
uint performUpdate(const string &msgPrefix, const DNSRecord *rr, DomainInfo *di, bool isPresigned, bool* narrow, bool* haveNSEC3, NSEC3PARAMRecordContent *ns3pr, bool *updatedSerial);
int checkUpdatePrescan(const DNSRecord *rr);
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 DNSName& target, const DNSName& wildcard, const SOAData& sd);
- void makeNOError(DNSPacket* p, DNSPacket* r, const DNSName& target, const DNSName& wildcard, const SOAData& sd, int mode);
- vector<DNSZoneRecord> getBestReferralNS(DNSPacket *p, SOAData& sd, const DNSName &target);
- vector<DNSZoneRecord> 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);
+ void makeNXDomain(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const SOAData& sd);
+ void makeNOError(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const DNSName& target, const DNSName& wildcard, const SOAData& sd, int mode);
+ vector<DNSZoneRecord> getBestReferralNS(DNSPacket& p, const SOAData& sd, const DNSName &target);
+ vector<DNSZoneRecord> getBestDNAMESynth(DNSPacket& p, const SOAData& sd, DNSName &target);
+ bool tryDNAME(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, DNSName &target);
+ bool tryReferral(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName &target, bool retargeted);
- bool getBestWildcard(DNSPacket *p, SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* 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);
+ bool getBestWildcard(DNSPacket& p, const SOAData& sd, const DNSName &target, DNSName &wildcard, vector<DNSZoneRecord>* ret);
+ bool tryWildcard(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, DNSName &target, DNSName &wildcard, bool& retargeted, bool& nodata);
+ bool addDSforNS(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName& dsname);
+ void completeANYRecords(DNSPacket& p, std::unique_ptr<DNSPacket>& r, const SOAData& sd, const DNSName &target);
- void tkeyHandler(DNSPacket *p, DNSPacket *r); //<! process TKEY record, and adds TKEY record to (r)eply, or error code.
+ void tkeyHandler(const DNSPacket& p, std::unique_ptr<DNSPacket>& r); //<! process TKEY record, and adds TKEY record to (r)eply, or error code.
static AtomicCounter s_count;
static pthread_mutex_t s_rfc2136lock;
UeberBackend B; // every thread an own instance
DNSSECKeeper d_dk; // B is shared with DNSSECKeeper
};
-bool getNSEC3Hashes(bool narrow, DNSBackend* db, int id, const std::string& hashed, bool decrement, DNSName& unhashed, string& before, string& after, int mode=0);
+
std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& sd);
#endif /* PACKETHANDLER */
CK_ULONG ckLong;
std::string ckString;
CkaValueType ckType;
- unsigned char *buffer;
+ std::unique_ptr<unsigned char[]> buffer;
CK_ULONG buflen;
protected:
void Init() {
- buffer = NULL;
buflen = 0;
};
public:
// this bit is used for getting attribute from object
// we provide a pointer for GetAttributeValue to write to
CK_BYTE_PTR allocate(CK_ULONG amount) {
- buffer = new unsigned char[amount];
+ buffer = std::unique_ptr<unsigned char[]>(new unsigned char[amount]);
buflen = amount;
- return buffer;
+ return buffer.get();
}
// and here we copy the results back and delete buffer
void commit(CK_ULONG amount) {
if (buffer) {
- this->ckString.assign((char*)buffer, amount);
- delete [] buffer;
+ this->ckString.assign((char*)buffer.get(), amount);
}
- buffer = NULL;
+ buffer.reset();
buflen = 0;
}
break;
}
case Attribute_String: {
- attr->pValue = buffer;
+ attr->pValue = buffer.get();
attr->ulValueLen = buflen;
}
};
public:
Pkcs11Slot(CK_FUNCTION_LIST* functions, const CK_SLOT_ID& slot) :
- d_slot(slot),
- d_functions(functions),
- d_err(0),
- d_logged_in(false)
+ d_logged_in(false),
+ d_functions(functions),
+ d_slot(slot),
+ d_err(0)
{
CK_TOKEN_INFO tokenInfo;
pthread_mutex_init(&(this->d_m), NULL);
bool Login(const std::string& pin) {
if (d_logged_in) return true;
- unsigned char *uPin = new unsigned char[pin.size()];
- memcpy(uPin, pin.c_str(), pin.size());
- d_err = d_functions->C_Login(this->d_session, CKU_USER, uPin, pin.size());
- memset(uPin, 0, pin.size());
- delete [] uPin;
+ std::unique_ptr<unsigned char[]> uPin(new unsigned char[pin.size()]);
+ memcpy(uPin.get(), pin.c_str(), pin.size());
+ d_err = d_functions->C_Login(this->d_session, CKU_USER, uPin.get(), pin.size());
+ memset(uPin.get(), 0, pin.size());
logError("C_Login");
if (d_err == 0) {
// if we can use some library to parse the EC parameters, better use it.
// otherwise fall back to using hardcoded primev256 and secp384r1
#ifdef HAVE_LIBCRYPTO_ECDSA
- EC_KEY *key = NULL;
- BIGNUM *order;
unsigned int bits = 0;
const unsigned char *in = reinterpret_cast<const unsigned char*>(obj.c_str());
- order = BN_new();
- if ((key = d2i_ECParameters(NULL, &in, obj.size())) != NULL &&
- EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) == 1) {
- bits = BN_num_bits(order);
+ auto order = std::unique_ptr<BIGNUM, void(*)(BIGNUM*)>(BN_new(), BN_clear_free);
+ auto tempKey = d2i_ECParameters(nullptr, &in, obj.size());
+ if (tempKey != nullptr) {
+ auto key = std::unique_ptr<EC_KEY, void(*)(EC_KEY*)>(tempKey, EC_KEY_free);
+ tempKey = nullptr;
+ if (EC_GROUP_get_order(EC_KEY_get0_group(key.get()), order.get(), nullptr) == 1) {
+ bits = BN_num_bits(order.get());
+ }
}
- BN_free(order);
- if (key != NULL)
- EC_KEY_free(key);
-
if (bits == 0)
throw PDNSException("Unsupported EC key");
Lock l(d_slot->m());
size_t k;
- CK_ATTRIBUTE_PTR pubAttr, privAttr;
- pubAttr = new CK_ATTRIBUTE[pubAttributes.size()];
- privAttr = new CK_ATTRIBUTE[privAttributes.size()];
+ std::unique_ptr<CK_ATTRIBUTE[]> pubAttr(new CK_ATTRIBUTE[pubAttributes.size()]);
+ std::unique_ptr<CK_ATTRIBUTE[]> privAttr(new CK_ATTRIBUTE[privAttributes.size()]);
k = 0;
for(P11KitAttribute& attribute : pubAttributes) {
- attribute.rattr(pubAttr+k);
+ attribute.rattr(pubAttr.get()+k);
k++;
}
k = 0;
for(P11KitAttribute& attribute : privAttributes) {
- attribute.rattr(privAttr+k);
+ attribute.rattr(privAttr.get()+k);
k++;
}
- d_err = this->d_slot->f()->C_GenerateKeyPair(d_slot->Session(), mechanism, pubAttr, pubAttributes.size(), privAttr, privAttributes.size(), pubKey, privKey);
+ d_err = this->d_slot->f()->C_GenerateKeyPair(d_slot->Session(), mechanism, pubAttr.get(), pubAttributes.size(), privAttr.get(), privAttributes.size(), pubKey, privKey);
logError("C_GenerateKeyPair");
- delete [] pubAttr;
- delete [] privAttr;
}
if (d_err == 0) LoadAttributes();
size_t k;
unsigned long count;
- CK_ATTRIBUTE_PTR attr;
- CK_OBJECT_HANDLE_PTR handles = new CK_OBJECT_HANDLE[maxobjects];
- attr = new CK_ATTRIBUTE[attributes.size()];
+ std::unique_ptr<CK_OBJECT_HANDLE[]> handles(new CK_OBJECT_HANDLE[maxobjects]);
+ std::unique_ptr<CK_ATTRIBUTE[]> attr(new CK_ATTRIBUTE[attributes.size()]);
k = 0;
for(const P11KitAttribute& attribute : attributes) {
- attribute.rattr(attr+k);
+ attribute.rattr(attr.get()+k);
k++;
}
// perform search
- d_err = this->d_slot->f()->C_FindObjectsInit(d_slot->Session(), attr, k);
+ d_err = this->d_slot->f()->C_FindObjectsInit(d_slot->Session(), attr.get(), k);
if (d_err) {
- delete [] attr;
- delete [] handles;
logError("C_FindObjectsInit");
return d_err;
}
count = maxobjects;
- rv = d_err = this->d_slot->f()->C_FindObjects(d_slot->Session(), handles, maxobjects, &count);
+ rv = d_err = this->d_slot->f()->C_FindObjects(d_slot->Session(), handles.get(), maxobjects, &count);
objects.clear();
if (!rv) {
for(k=0;k<count;k++) {
- objects.push_back(handles[k]);
+ objects.push_back((handles.get())[k]);
}
}
logError("C_FindObjects");
- delete [] attr;
- delete [] handles;
-
d_err = this->d_slot->f()->C_FindObjectsFinal(d_slot->Session());
logError("C_FindObjectsFinal");
int GetAttributeValue2(const CK_OBJECT_HANDLE& object, std::vector<P11KitAttribute>& attributes)
{
size_t k;
- CK_ATTRIBUTE_PTR attr;
- attr = new CK_ATTRIBUTE[attributes.size()];
+ std::unique_ptr<CK_ATTRIBUTE[]> attr(new CK_ATTRIBUTE[attributes.size()]);
k = 0;
for(P11KitAttribute &attribute : attributes) {
- attribute.wattr(attr+k);
+ attribute.wattr(attr.get()+k);
k++;
}
// round 1 - get attribute sizes
- d_err = d_slot->f()->C_GetAttributeValue(d_slot->Session(), object, attr, attributes.size());
+ d_err = d_slot->f()->C_GetAttributeValue(d_slot->Session(), object, attr.get(), attributes.size());
logError("C_GetAttributeValue");
if (d_err) {
- delete [] attr;
return d_err;
}
// then allocate memory
for(size_t idx=0; idx < attributes.size(); idx++) {
if (attributes[idx].valueType() == Attribute_String) {
- attr[idx].pValue = attributes[idx].allocate(attr[idx].ulValueLen);
+ (attr.get())[idx].pValue = attributes[idx].allocate((attr.get())[idx].ulValueLen);
}
}
// round 2 - get actual values
- d_err = d_slot->f()->C_GetAttributeValue(d_slot->Session(), object, attr, attributes.size());
+ d_err = d_slot->f()->C_GetAttributeValue(d_slot->Session(), object, attr.get(), attributes.size());
logError("C_GetAttributeValue");
// copy values to map and release allocated memory
for(size_t idx=0; idx < attributes.size(); idx++) {
if (attributes[idx].valueType() == Attribute_String) {
- attributes[idx].commit(attr[idx].ulValueLen);
+ attributes[idx].commit((attr.get())[idx].ulValueLen);
}
}
- delete [] attr;
-
return d_err;
};
}
Pkcs11Token::Pkcs11Token(const std::shared_ptr<Pkcs11Slot>& slot, const std::string& label, const std::string& pub_label) :
- d_bits(0),
d_slot(slot),
+ d_bits(0),
d_label(label),
d_pub_label(pub_label),
- d_err(0),
- d_loaded(false)
+ d_loaded(false),
+ d_err(0)
{
// open a session
if (this->d_slot->LoggedIn()) LoadAttributes();
if(isGuarded(argv)) {
g_log<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
- dl=new DynListener; // listens on stdin
+ dl=make_unique<DynListener>(); // listens on stdin
}
else {
g_log<<Logger::Warning<<"This is a standalone pdns"<<endl;
if(::arg().mustDo("control-console"))
- dl=new DynListener();
+ dl=make_unique<DynListener>();
else
- dl=new DynListener(s_programname);
+ dl=std::unique_ptr<DynListener>(new DynListener(s_programname));
writePid();
}
return changedRecords;
}
-int PacketHandler::forwardPacket(const string &msgPrefix, DNSPacket *p, DomainInfo *di) {
+int PacketHandler::forwardPacket(const string &msgPrefix, const DNSPacket& p, const DomainInfo& di) {
vector<string> forward;
- B.getDomainMetadata(p->qdomain, "FORWARD-DNSUPDATE", forward);
+ B.getDomainMetadata(p.qdomain, "FORWARD-DNSUPDATE", forward);
if (forward.size() == 0 && ! ::arg().mustDo("forward-dnsupdate")) {
g_log<<Logger::Notice<<msgPrefix<<"Not configured to forward to master, returning Refused."<<endl;
return RCode::Refused;
}
- for(const auto& remote : di->masters) {
+ for(const auto& remote : di.masters) {
g_log<<Logger::Notice<<msgPrefix<<"Forwarding packet to master "<<remote<<endl;
ComboAddress local;
continue;
}
- DNSPacket forwardPacket(*p);
+ DNSPacket forwardPacket(p);
forwardPacket.setID(dns_random_uint16());
forwardPacket.setRemote(&remote);
uint16_t len=htons(forwardPacket.getString().length());
}
-int PacketHandler::processUpdate(DNSPacket *p) {
+int PacketHandler::processUpdate(DNSPacket& p) {
if (! ::arg().mustDo("dnsupdate"))
return RCode::Refused;
- string msgPrefix="UPDATE (" + itoa(p->d.id) + ") from " + p->getRemote().toString() + " for " + p->qdomain.toLogString() + ": ";
+ string msgPrefix="UPDATE (" + itoa(p.d.id) + ") from " + p.getRemote().toString() + " for " + p.qdomain.toLogString() + ": ";
g_log<<Logger::Info<<msgPrefix<<"Processing started."<<endl;
// if there is policy, we delegate all checks to it
// Check permissions - IP based
vector<string> allowedRanges;
- B.getDomainMetadata(p->qdomain, "ALLOW-DNSUPDATE-FROM", allowedRanges);
+ B.getDomainMetadata(p.qdomain, "ALLOW-DNSUPDATE-FROM", allowedRanges);
if (! ::arg()["allow-dnsupdate-from"].empty())
stringtok(allowedRanges, ::arg()["allow-dnsupdate-from"], ", \t" );
ng.addMask(i);
}
- if ( ! ng.match(&p->d_remote)) {
+ if ( ! ng.match(&p.d_remote)) {
g_log<<Logger::Error<<msgPrefix<<"Remote not listed in allow-dnsupdate-from or domainmetadata. Sending REFUSED"<<endl;
return RCode::Refused;
}
// Check permissions - TSIG based.
vector<string> tsigKeys;
- B.getDomainMetadata(p->qdomain, "TSIG-ALLOW-DNSUPDATE", tsigKeys);
+ B.getDomainMetadata(p.qdomain, "TSIG-ALLOW-DNSUPDATE", tsigKeys);
if (tsigKeys.size() > 0) {
bool validKey = false;
TSIGRecordContent trc;
DNSName inputkey;
string message;
- if (! p->getTSIGDetails(&trc, &inputkey)) {
+ if (! p.getTSIGDetails(&trc, &inputkey)) {
g_log<<Logger::Error<<msgPrefix<<"TSIG key required, but packet does not contain key. Sending REFUSED"<<endl;
return RCode::Refused;
}
- if (p->d_tsig_algo == TSIG_GSS) {
- GssName inputname(p->d_peer_principal); // match against principal since GSS
+ if (p.d_tsig_algo == TSIG_GSS) {
+ GssName inputname(p.d_peer_principal); // match against principal since GSS
for(const auto& key: tsigKeys) {
if (inputname.match(key)) {
validKey = true;
}
}
- if (tsigKeys.size() == 0 && p->d_havetsig)
+ if (tsigKeys.size() == 0 && p.d_havetsig)
g_log<<Logger::Warning<<msgPrefix<<"TSIG is provided, but domain is not secured with TSIG. Processing continues"<<endl;
}
// RFC2136 uses the same DNS Header and Message as defined in RFC1035.
// This means we can use the MOADNSParser to parse the incoming packet. The result is that we have some different
// variable names during the use of our MOADNSParser.
- MOADNSParser mdp(false, p->getString());
+ MOADNSParser mdp(false, p.getString());
if (mdp.d_header.qdcount != 1) {
g_log<<Logger::Warning<<msgPrefix<<"Zone Count is not 1, sending FormErr"<<endl;
return RCode::FormErr;
}
- if (p->qtype.getCode() != QType::SOA) { // RFC2136 2.3 - ZTYPE must be SOA
+ if (p.qtype.getCode() != QType::SOA) { // RFC2136 2.3 - ZTYPE must be SOA
g_log<<Logger::Warning<<msgPrefix<<"Query ZTYPE is not SOA, sending FormErr"<<endl;
return RCode::FormErr;
}
- if (p->qclass != QClass::IN) {
+ if (p.qclass != QClass::IN) {
g_log<<Logger::Warning<<msgPrefix<<"Class is not IN, sending NotAuth"<<endl;
return RCode::NotAuth;
}
DomainInfo di;
di.backend=0;
- if(!B.getDomainInfo(p->qdomain, di) || !di.backend) {
- g_log<<Logger::Error<<msgPrefix<<"Can't determine backend for domain '"<<p->qdomain<<"' (or backend does not support DNS update operation)"<<endl;
+ if(!B.getDomainInfo(p.qdomain, di) || !di.backend) {
+ g_log<<Logger::Error<<msgPrefix<<"Can't determine backend for domain '"<<p.qdomain<<"' (or backend does not support DNS update operation)"<<endl;
return RCode::NotAuth;
}
if (di.kind == DomainInfo::Slave)
- return forwardPacket(msgPrefix, p, &di);
+ return forwardPacket(msgPrefix, p, di);
// Check if all the records provided are within the zone
for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i != mdp.d_answers.end(); ++i) {
Lock l(&s_rfc2136lock); //TODO: i think this lock can be per zone, not for everything
g_log<<Logger::Info<<msgPrefix<<"starting transaction."<<endl;
- if (!di.backend->startTransaction(p->qdomain, -1)) { // Not giving the domain_id means that we do not delete the existing records.
- g_log<<Logger::Error<<msgPrefix<<"Backend for domain "<<p->qdomain<<" does not support transaction. Can't do Update packet."<<endl;
+ if (!di.backend->startTransaction(p.qdomain, -1)) { // Not giving the domain_id means that we do not delete the existing records.
+ g_log<<Logger::Error<<msgPrefix<<"Backend for domain "<<p.qdomain<<" does not support transaction. Can't do Update packet."<<endl;
return RCode::NotImp;
}
// Notify slaves
if (di.kind == DomainInfo::Master) {
vector<string> notify;
- B.getDomainMetadata(p->qdomain, "NOTIFY-DNSUPDATE", notify);
+ B.getDomainMetadata(p.qdomain, "NOTIFY-DNSUPDATE", notify);
if (!notify.empty() && notify.front() == "1") {
Communicator.notifyDomain(di.zone, &B);
}
throw PDNSException("tcp read failed");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=sock.read(creply+n, len-n);
+ numread=sock.read(creply.get()+n, len-n);
if(numread<0)
throw PDNSException("tcp read failed");
n+=numread;
}
- MOADNSParser mdp(false, string(creply, len));
+ MOADNSParser mdp(false, string(creply.get(), len));
if (mdp.d_header.rcode != 0) {
throw PDNSException(string("Remote server refused: ") + std::to_string(mdp.d_header.rcode));
}
throw PDNSException("tcp read failed");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=sock.read(creply+n, len-n);
+ numread=sock.read(creply.get()+n, len-n);
if(numread<0)
throw PDNSException("tcp read failed");
n+=numread;
}
- MOADNSParser mdp(false, string(creply, len));
+ MOADNSParser mdp(false, string(creply.get(), len));
if (mdp.d_header.rcode != 0) {
throw PDNSException(string("Remote server refused: ") + std::to_string(mdp.d_header.rcode));
}
}while(shorter.chopOff());
}
-
- delete[] creply;
}
if (isNSEC3 && unhash)
throw PDNSException("tcp read failed");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=sock.read(creply+n, len-n);
+ numread=sock.read(creply.get()+n, len-n);
if(numread<0)
throw PDNSException("tcp read failed");
n+=numread;
}
- reply=string(creply, len);
- delete[] creply;
+ reply=string(creply.get(), len);
}
else //udp
{
: d_signed(0), d_queued(0), d_outstanding(0), d_numworkers(workers), d_submitted(0), d_signer(signerName),
d_maxchunkrecords(100), d_threads(d_numworkers), d_mustSign(mustSign), d_final(false)
{
- d_rrsetToSign = new rrset_t;
+ d_rrsetToSign = make_unique<rrset_t>();
d_chunks.push_back(vector<DNSZoneRecord>()); // load an empty chunk
if(!d_mustSign)
ChunkedSigningPipe::~ChunkedSigningPipe()
{
- delete d_rrsetToSign;
-
if(!d_mustSign)
return;
return vects;
}
-void ChunkedSigningPipe::addSignedToChunks(chunk_t* signedChunk)
+void ChunkedSigningPipe::addSignedToChunks(std::unique_ptr<chunk_t>& signedChunk)
{
chunk_t::const_iterator from = signedChunk->begin();
while(from != signedChunk->end()) {
chunk_t& fillChunk = d_chunks.back();
-
chunk_t::size_type room = d_maxchunkrecords - fillChunk.size();
unsigned int fit = std::min(room, (chunk_t::size_type)(signedChunk->end() - from));
d_chunks.back().insert(fillChunk.end(), from , from + fit);
from+=fit;
-
+
if(from != signedChunk->end()) // it didn't fit, so add a new chunk
d_chunks.push_back(chunk_t());
}
if(wantWrite && !rwVect.second.empty()) {
random_shuffle(rwVect.second.begin(), rwVect.second.end()); // pick random available worker
- writen2(*rwVect.second.begin(), &d_rrsetToSign, sizeof(d_rrsetToSign));
- d_rrsetToSign = new rrset_t;
+ auto ptr = d_rrsetToSign.release();
+ writen2(*rwVect.second.begin(), &ptr, sizeof(ptr));
+ d_rrsetToSign = make_unique<rrset_t>();
d_outstandings[*rwVect.second.begin()]++;
d_outstanding++;
d_queued++;
if(wantRead) {
while(d_outstanding) {
- chunk_t* chunk;
-
for(int fd : rwVect.first) {
if(d_eof.count(fd))
continue;
while(d_outstanding) {
+ chunk_t* chunk = nullptr;
int res = readn(fd, &chunk, sizeof(chunk));
if(!res) {
if (d_outstandings[fd] > 0) {
else
break;
}
-
+
+ std::unique_ptr<rrset_t> chunkPtr(chunk);
+ chunk = nullptr;
--d_outstanding;
d_outstandings[fd]--;
- addSignedToChunks(chunk);
-
- delete chunk;
+ addSignedToChunks(chunkPtr);
}
}
if(!d_outstanding || !d_final)
if(wantWrite) { // our optimization above failed, we now wait synchronously
rwVect = waitForRW(false, wantWrite, -1); // wait for something to happen
random_shuffle(rwVect.second.begin(), rwVect.second.end()); // pick random available worker
- writen2(*rwVect.second.begin(), &d_rrsetToSign, sizeof(d_rrsetToSign));
- d_rrsetToSign = new rrset_t;
+ auto ptr = d_rrsetToSign.release();
+ writen2(*rwVect.second.begin(), &ptr, sizeof(ptr));
+ d_rrsetToSign = make_unique<rrset_t>();
d_outstandings[*rwVect.second.begin()]++;
d_outstanding++;
d_queued++;
void flushToSign();
void dedupRRSet();
void sendRRSetToWorker(); // dispatch RRSET to worker
- void addSignedToChunks(chunk_t* signedChunk);
+ void addSignedToChunks(std::unique_ptr<chunk_t>& signedChunk);
pair<vector<int>, vector<int> > waitForRW(bool rd, bool wr, int seconds);
static void* helperWorker(ChunkedSigningPipe* csp, int fd);
unsigned int d_numworkers;
unsigned int d_submitted;
- rrset_t* d_rrsetToSign;
+ std::unique_ptr<rrset_t> d_rrsetToSign;
std::deque< std::vector<DNSZoneRecord> > d_chunks;
DNSName d_signer;
#include "common_startup.hh"
#include "ixfr.hh"
-using boost::scoped_ptr;
-
void CommunicatorClass::addSuckRequest(const DNSName &domain, const ComboAddress& master)
{
};
-void CommunicatorClass::ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, scoped_ptr<AuthLua4>& pdl,
+void CommunicatorClass::ixfrSuck(const DNSName &domain, const TSIGTriplet& tt, const ComboAddress& laddr, const ComboAddress& remote, unique_ptr<AuthLua4>& pdl,
ZoneStatus& zs, vector<DNSRecord>* axfr)
{
UeberBackend B; // fresh UeberBackend
5) It updates the Empty Non Terminals
*/
-static vector<DNSResourceRecord> doAxfr(const ComboAddress& raddr, const DNSName& domain, const TSIGTriplet& tt, const ComboAddress& laddr, scoped_ptr<AuthLua4>& pdl, ZoneStatus& zs)
+static vector<DNSResourceRecord> doAxfr(const ComboAddress& raddr, const DNSName& domain, const TSIGTriplet& tt, const ComboAddress& laddr, unique_ptr<AuthLua4>& pdl, ZoneStatus& zs)
{
uint16_t axfr_timeout=::arg().asNum("axfr-fetch-timeout");
vector<DNSResourceRecord> rrs;
}
- scoped_ptr<AuthLua4> pdl;
+ unique_ptr<AuthLua4> pdl{nullptr};
vector<string> scripts;
string script=::arg()["lua-axfr-script"];
if(B.getDomainMetadata(domain, "LUA-AXFR-SCRIPT", scripts) && !scripts.empty()) {
}
if(!script.empty()){
try {
- pdl.reset(new AuthLua4());
+ pdl = make_unique<AuthLua4>();
pdl->loadFile(script);
g_log<<Logger::Info<<"Loaded Lua script '"<<script<<"' to edit the incoming AXFR of '"<<domain<<"'"<<endl;
}
d_any_sem.post(); // kick the loop!
}
-void CommunicatorClass::addTrySuperMasterRequest(DNSPacket *p)
+void CommunicatorClass::addTrySuperMasterRequest(const DNSPacket& p)
{
Lock l(&d_lock);
- DNSPacket ours = *p;
+ DNSPacket ours = p;
if(d_potentialsupermasters.insert(ours).second)
d_any_sem.post(); // kick the loop!
}
TSIGRecordContent trc;
DNSName tsigkeyname;
dp.getTSIGDetails(&trc, &tsigkeyname);
- P->trySuperMasterSynchronous(&dp, tsigkeyname); // FIXME could use some error loging
+ P->trySuperMasterSynchronous(dp, tsigkeyname); // FIXME could use some error loging
}
if(rdomains.empty()) { // if we have priority domains, check them first
B->getUnfreshSlaveInfos(&rdomains);
void StatBag::declare(const string &key, const string &descrip)
{
- AtomicCounter *i=new AtomicCounter(0);
- d_stats[key]=i;
+ auto i=make_unique<AtomicCounter>(0);
+ d_stats[key]=std::move(i);
d_keyDescrips[key]=descrip;
}
AtomicCounter *StatBag::getPointer(const string &key)
{
exists(key);
- return d_stats[key];
+ return d_stats[key].get();
}
StatBag::~StatBag()
{
- for(const auto& i: d_stats) {
- delete i.second;
- }
-
}
template<typename T, typename Comp>
//! use this to gather and query statistics
class StatBag
{
- map<string, AtomicCounter *> d_stats;
+ map<string, std::unique_ptr<AtomicCounter>> d_stats;
map<string, string> d_keyDescrips;
map<string,StatRing<string, CIStringCompare> >d_rings;
map<string,StatRing<SComboAddress> >d_comborings;
*/
pthread_mutex_t TCPNameserver::s_plock = PTHREAD_MUTEX_INITIALIZER;
-Semaphore *TCPNameserver::d_connectionroom_sem;
+std::unique_ptr<Semaphore> TCPNameserver::d_connectionroom_sem{nullptr};
+std::unique_ptr<PacketHandler> TCPNameserver::s_P{nullptr};
unsigned int TCPNameserver::d_maxTCPConnections = 0;
-PacketHandler *TCPNameserver::s_P;
NetmaskGroup TCPNameserver::d_ng;
size_t TCPNameserver::d_maxTransactionsPerConn;
size_t TCPNameserver::d_maxConnectionsPerClient;
void TCPNameserver::go()
{
g_log<<Logger::Error<<"Creating backend connection for TCP"<<endl;
- s_P=0;
+ s_P.reset();
try {
- s_P=new PacketHandler;
+ s_P=make_unique<PacketHandler>();
}
catch(PDNSException &ae) {
g_log<<Logger::Error<<"TCP server is unable to launch backends - will try again when questions come in: "<<ae.reason<<endl;
;
}
-void TCPNameserver::sendPacket(shared_ptr<DNSPacket> p, int outsock)
+void TCPNameserver::sendPacket(std::unique_ptr<DNSPacket>& p, int outsock)
{
g_rs.submitResponse(*p, false);
void *TCPNameserver::doConnection(void *data)
{
setThreadName("pdns/tcpConnect");
- shared_ptr<DNSPacket> packet;
+ std::unique_ptr<DNSPacket> packet;
// Fix gcc-4.0 error (on AMD64)
int fd=(int)(long)data; // gotta love C (generates a harmless warning on opteron)
ComboAddress remote;
else
S.inc("tcp4-queries");
- packet=shared_ptr<DNSPacket>(new DNSPacket(true));
+ packet=make_unique<DNSPacket>(true);
packet->setRemote(&remote);
packet->d_tcp=true;
packet->setSocket(fd);
continue;
}
- shared_ptr<DNSPacket> reply;
- shared_ptr<DNSPacket> cached= shared_ptr<DNSPacket>(new DNSPacket(false));
+ std::unique_ptr<DNSPacket> reply;
+ auto cached = make_unique<DNSPacket>(false);
if(logDNSQueries) {
string remote_text;
if(packet->hasEDNSSubnet())
}
if(PC.enabled()) {
- if(packet->couldBeCached() && PC.get(packet.get(), cached.get())) { // short circuit - does the PacketCache recognize this question?
+ if(packet->couldBeCached() && PC.get(*packet, *cached)) { // short circuit - does the PacketCache recognize this question?
if(logDNSQueries)
g_log<<"packetcache HIT"<<endl;
cached->setRemote(&packet->d_remote);
Lock l(&s_plock);
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections, launching"<<endl;
- s_P=new PacketHandler;
+ s_P=make_unique<PacketHandler>();
}
- reply=shared_ptr<DNSPacket>(s_P->doQuestion(packet.get())); // we really need to ask the backend :-)
+ reply= s_P->doQuestion(*packet); // we really need to ask the backend :-)
}
if(!reply) // unable to write an answer?
}
catch(PDNSException &ae) {
Lock l(&s_plock);
- delete s_P;
- s_P = 0; // on next call, backend will be recycled
+ s_P.reset(); // on next call, backend will be recycled
g_log<<Logger::Error<<"TCP nameserver had error, cycling backend: "<<ae.reason<<endl;
}
catch(NetworkError &e) {
// call this method with s_plock held!
-bool TCPNameserver::canDoAXFR(shared_ptr<DNSPacket> q)
+bool TCPNameserver::canDoAXFR(std::unique_ptr<DNSPacket>& q)
{
if(::arg().mustDo("disable-axfr"))
return false;
bool d_auth;
};
- shared_ptr<DNSPacket> getFreshAXFRPacket(shared_ptr<DNSPacket> q)
+ std::unique_ptr<DNSPacket> getFreshAXFRPacket(std::unique_ptr<DNSPacket>& q)
{
- shared_ptr<DNSPacket> ret = shared_ptr<DNSPacket>(q->replyPacket());
+ std::unique_ptr<DNSPacket> ret = std::unique_ptr<DNSPacket>(q->replyPacket());
ret->setCompress(false);
ret->d_dnssecOk=false; // RFC 5936, 2.2.5
ret->d_tcp = true;
/** do the actual zone transfer. Return 0 in case of error, 1 in case of success */
-int TCPNameserver::doAXFR(const DNSName &target, shared_ptr<DNSPacket> q, int outsock)
+int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr<DNSPacket>& q, int outsock)
{
- shared_ptr<DNSPacket> outpacket= getFreshAXFRPacket(q);
+ std::unique_ptr<DNSPacket> outpacket= getFreshAXFRPacket(q);
if(q->d_dnssecOk)
outpacket->d_dnssecOk=true; // RFC 5936, 2.2.5 'SHOULD'
DLOG(g_log<<"Looking for SOA"<<endl); // find domain_id via SOA and list complete domain. No SOA, no AXFR
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections in doAXFR, launching"<<endl;
- s_P=new PacketHandler;
+ s_P=make_unique<PacketHandler>();
}
// canDoAXFR does all the ACL checks, and has the if(disable-axfr) shortcut, call it first.
return 1;
}
-int TCPNameserver::doIXFR(shared_ptr<DNSPacket> q, int outsock)
+int TCPNameserver::doIXFR(std::unique_ptr<DNSPacket>& q, int outsock)
{
- shared_ptr<DNSPacket> outpacket=getFreshAXFRPacket(q);
+ std::unique_ptr<DNSPacket> outpacket=getFreshAXFRPacket(q);
if(q->d_dnssecOk)
outpacket->d_dnssecOk=true; // RFC 5936, 2.2.5 'SHOULD'
DLOG(g_log<<"Looking for SOA"<<endl); // find domain_id via SOA and list complete domain. No SOA, no IXFR
if(!s_P) {
g_log<<Logger::Error<<"TCP server is without backend connections in doIXFR, launching"<<endl;
- s_P=new PacketHandler;
+ s_P=make_unique<PacketHandler>();
}
// canDoAXFR does all the ACL checks, and has the if(disable-axfr) shortcut, call it first.
TCPNameserver::~TCPNameserver()
{
- delete d_connectionroom_sem;
}
TCPNameserver::TCPNameserver()
d_maxConnectionsPerClient = ::arg().asNum("max-tcp-connections-per-client");
// sem_init(&d_connectionroom_sem,0,::arg().asNum("max-tcp-connections"));
- d_connectionroom_sem = new Semaphore( ::arg().asNum( "max-tcp-connections" ));
+ d_connectionroom_sem = make_unique<Semaphore>( ::arg().asNum( "max-tcp-connections" ));
d_maxTCPConnections = ::arg().asNum( "max-tcp-connections" );
d_tid=0;
vector<string>locals;
unsigned int numTCPConnections();
private:
- static void sendPacket(std::shared_ptr<DNSPacket> p, int outsock);
+ static void sendPacket(std::unique_ptr<DNSPacket>& p, int outsock);
static int readLength(int fd, ComboAddress *remote);
static void getQuestion(int fd, char *mesg, int pktlen, const ComboAddress& remote, unsigned int totalTime);
- static int doAXFR(const DNSName &target, std::shared_ptr<DNSPacket> q, int outsock);
- static int doIXFR(std::shared_ptr<DNSPacket> q, int outsock);
- static bool canDoAXFR(std::shared_ptr<DNSPacket> q);
+ static int doAXFR(const DNSName &target, std::unique_ptr<DNSPacket>& q, int outsock);
+ static int doIXFR(std::unique_ptr<DNSPacket>& q, int outsock);
+ static bool canDoAXFR(std::unique_ptr<DNSPacket>& q);
static void *doConnection(void *data);
static void *launcher(void *data);
static void decrementClientCount(const ComboAddress& remote);
static pthread_mutex_t s_plock;
static std::mutex s_clientsCountMutex;
static std::map<ComboAddress,size_t,ComboAddress::addressOnlyLessThan> s_clientsCount;
- static PacketHandler *s_P;
+ static std::unique_ptr<PacketHandler> s_P;
pthread_t d_tid;
- static Semaphore *d_connectionroom_sem;
+ static std::unique_ptr<Semaphore> d_connectionroom_sem;
static unsigned int d_maxTCPConnections;
static NetmaskGroup d_ng;
static size_t d_maxTransactionsPerConn;
DTime d_dt;
DNSName qdomain;
QType qtype;
- DNSPacket* replyPacket()
+ std::unique_ptr<DNSPacket> replyPacket()
{
- return new DNSPacket(false);
+ return make_unique<DNSPacket>(false);
}
};
struct Backend
{
- DNSPacket* question(Question*)
+ std::unique_ptr<DNSPacket> question(Question&)
{
- return new DNSPacket(true);
+ return make_unique<DNSPacket>(true);
}
};
static std::atomic<int> g_receivedAnswers;
-static void report(DNSPacket* A)
+static void report(std::unique_ptr<DNSPacket>& A)
{
- delete A;
g_receivedAnswers++;
}
int n;
for(n=0; n < 100; ++n) {
- auto q = new Question();
- q->d_dt.set();
+ Question q;
+ q.d_dt.set();
d->question(q, report);
}
sleep(1);
struct BackendSlow
{
- DNSPacket* question(Question*)
+ std::unique_ptr<DNSPacket> question(Question&)
{
sleep(1);
- return new DNSPacket(true);
+ return make_unique<DNSPacket>(true);
}
};
static std::atomic<int> g_receivedAnswers1;
-static void report1(DNSPacket* A)
+static void report1(std::unique_ptr<DNSPacket>& A)
{
- delete A;
g_receivedAnswers1++;
}
int n;
// bound should be higher than max-queue-length
for(n=0; n < 2000; ++n) {
- auto q = new Question();
- q->d_dt.set();
+ Question q;
+ q.d_dt.set();
d->question(q, report1);
}
}, DistributorFatal, [](DistributorFatal) { return true; });
~BackendDies()
{
}
- DNSPacket* question(Question* q)
+ std::unique_ptr<DNSPacket> question(Question& q)
{
// cout<<"Q: "<<q->qdomain<<endl;
if(!d_ourcount && ++d_count == 10) {
// cerr<<"Going.. down!"<<endl;
throw runtime_error("kill");
}
- return new DNSPacket(true);
+ return make_unique<DNSPacket>(true);
}
static std::atomic<int> s_count;
int d_count{0};
std::atomic<int> g_receivedAnswers2;
-static void report2(DNSPacket* A)
+static void report2(std::unique_ptr<DNSPacket>& A)
{
- delete A;
g_receivedAnswers2++;
}
try {
for(int n=0; n < 100; ++n) {
- auto q = new Question();
- q->d_dt.set();
- q->qdomain=DNSName(std::to_string(n));
- q->qtype = QType(QType::A);
+ Question q;
+ q.d_dt.set();
+ q.qdomain=DNSName(std::to_string(n));
+ q.qtype = QType(QType::A);
d->question(q, report2);
}
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
-#include <boost/scoped_ptr.hpp>
#include "base32.hh"
#include "dnsrecords.hh"
BOOST_AUTO_TEST_CASE(test_pdns_lock)
{
for(unsigned int n=0; n < 1000; ++n) {
- auto p = new pthread_rwlock_t;
- pthread_rwlock_init(p, 0);
- g_locks.emplace_back(p);
+ auto p = make_unique<pthread_rwlock_t>();
+ pthread_rwlock_init(p.get(), 0);
+ g_locks.emplace_back(std::move(p));
}
std::vector<ReadLock> rlocks;
" return false\n"
"end";
AuthLua4 lua;
- DNSPacket *p = new DNSPacket(true);
- p->qdomain = DNSName("mod.unit.test.");
+ DNSPacket p(true);
+ p.qdomain = DNSName("mod.unit.test.");
lua.loadString(script);
- DNSPacket *r = nullptr;
+ std::unique_ptr<DNSPacket> r{nullptr};
try {
r = lua.prequery(p);
+ BOOST_REQUIRE(r != nullptr);
BOOST_CHECK_EQUAL(r->qdomain.toString(), "mod.unit.test.");
} catch (const LuaContext::ExecutionErrorException& e) {
try {
g_log<<"Extra info: "<<exp.what();
}
}
- delete r;
- delete p;
}
BOOST_AUTO_TEST_CASE(test_updatePolicy) {
" return false\n"
"end";
AuthLua4 lua;
- DNSPacket *p = new DNSPacket(true);
+ DNSPacket p(true);
ComboAddress ca(std::string("192.168.1.1"));
lua.loadString(script);
- p->setRemote(&ca);
- p->d_peer_principal = "admin@DOMAIN";
+ p.setRemote(&ca);
+ p.d_peer_principal = "admin@DOMAIN";
BOOST_CHECK_EQUAL(lua.updatePolicy(DNSName("mod.example.com."), QType(QType::A), DNSName("example.com."), p), true);
- p->d_peer_principal = "";
+ p.d_peer_principal = "";
BOOST_CHECK_EQUAL(lua.updatePolicy(DNSName("mod.example.com."), QType(QType::A), DNSName("example.com."), p), true);
ca = ComboAddress(std::string("192.168.1.2"));
- p->setRemote(&ca);
+ p.setRemote(&ca);
BOOST_CHECK_EQUAL(lua.updatePolicy(DNSName("mod.example.com."), QType(QType::A), DNSName("example.com."), p), false);
- delete p;
}
BOOST_AUTO_TEST_SUITE_END()
q.setHash(g_PC->canHashPacket(q.getString()));
const unsigned int maxTTL = 3600;
- g_PC->insert(&q, &r, maxTTL);
+ g_PC->insert(q, r, maxTTL);
}
return 0;
q.parse((char*)&pak[0], pak.size());
DNSPacket r(false);
- if(!g_PC->get(&q, &r)) {
+ if(!g_PC->get(q, r)) {
g_PCmissing++;
}
}
}
/* this call is required so the correct hash is set into q->d_hash */
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), false);
- PC.insert(&q, &r, 3600);
+ PC.insert(q, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
/* different QID, still should match */
- BOOST_CHECK_EQUAL(PC.get(&differentIDQ, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(differentIDQ, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
/* with EDNS, should not match */
- BOOST_CHECK_EQUAL(PC.get(&ednsQ, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ednsQ, r2), false);
/* inserting the EDNS-enabled one too */
- PC.insert(&ednsQ, &r, 3600);
+ PC.insert(ednsQ, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 2);
/* different EDNS versions, should not match */
- BOOST_CHECK_EQUAL(PC.get(&ednsVersion42, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ednsVersion42, r2), false);
/* EDNS DO set, should not match */
- BOOST_CHECK_EQUAL(PC.get(&ednsDO, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ednsDO, r2), false);
/* EDNS Client Subnet set, should not match
since not only we don't skip the actual option, but the
total EDNS opt RR is still different. */
- BOOST_CHECK_EQUAL(PC.get(&ecs1, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ecs1, r2), false);
/* inserting the version with ECS Client Subnet set,
it should NOT replace the existing EDNS one. */
- PC.insert(&ecs1, &r, 3600);
+ PC.insert(ecs1, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 3);
/* different subnet of same size, should NOT match
since we don't skip the option */
- BOOST_CHECK_EQUAL(PC.get(&ecs2, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ecs2, r2), false);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
/* different subnet of different size, should NOT match. */
- BOOST_CHECK_EQUAL(PC.get(&ecs3, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(ecs3, r2), false);
BOOST_CHECK_EQUAL(PC.purge("www.powerdns.com"), 3);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), false);
BOOST_CHECK_EQUAL(PC.size(), 0);
- PC.insert(&q, &r, 3600);
+ PC.insert(q, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
BOOST_CHECK_EQUAL(PC.purge("com$"), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), false);
BOOST_CHECK_EQUAL(PC.size(), 0);
- PC.insert(&q, &r, 3600);
+ PC.insert(q, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
BOOST_CHECK_EQUAL(PC.purge("powerdns.com$"), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), false);
BOOST_CHECK_EQUAL(PC.size(), 0);
- PC.insert(&q, &r, 3600);
+ PC.insert(q, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
BOOST_CHECK_EQUAL(PC.purge("www.powerdns.com$"), 1);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), false);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), false);
BOOST_CHECK_EQUAL(PC.size(), 0);
- PC.insert(&q, &r, 3600);
+ PC.insert(q, r, 3600);
BOOST_CHECK_EQUAL(PC.size(), 1);
BOOST_CHECK_EQUAL(PC.purge("www.powerdns.net"), 0);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
BOOST_CHECK_EQUAL(PC.size(), 1);
BOOST_CHECK_EQUAL(PC.purge("net$"), 0);
- BOOST_CHECK_EQUAL(PC.get(&q, &r2), true);
+ BOOST_CHECK_EQUAL(PC.get(q, r2), true);
BOOST_CHECK_EQUAL(r2.qdomain, r.qdomain);
BOOST_CHECK_EQUAL(PC.size(), 1);
#include <boost/assign/list_of.hpp>
#include <boost/tuple/tuple.hpp>
-#include <boost/scoped_ptr.hpp>
#include "base64.hh"
#include "dnsseckeeper.hh"
#endif
#include "packethandler.hh"
-void PacketHandler::tkeyHandler(DNSPacket *p, DNSPacket *r) {
+void PacketHandler::tkeyHandler(const DNSPacket& p, std::unique_ptr<DNSPacket>& r) {
TKEYRecordContent tkey_in;
std::shared_ptr<TKEYRecordContent> tkey_out(new TKEYRecordContent());
DNSName name;
bool sign = false;
- if (!p->getTKEYRecord(&tkey_in, &name)) {
+ if (!p.getTKEYRecord(&tkey_in, &name)) {
g_log<<Logger::Error<<"TKEY request but no TKEY RR found"<<endl;
r->setRcode(RCode::FormErr);
return;
tkey_out->d_error = 21; // BADALGO
}
} else if (tkey_in.d_mode == 5) { // destroy context
- if (p->d_havetsig == false) { // unauthenticated
- if (p->d.opcode == Opcode::Update)
+ if (p.d_havetsig == false) { // unauthenticated
+ if (p.d.opcode == Opcode::Update)
r->setRcode(RCode::Refused);
else
r->setRcode(RCode::NotAuth);
else
tkey_out->d_error = 20; // BADNAME (because we have no support for anything here)
} else {
- if (p->d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated
- if (p->d.opcode == Opcode::Update)
+ if (p.d_havetsig == false && tkey_in.d_mode != 2) { // unauthenticated
+ if (p.d.opcode == Opcode::Update)
r->setRcode(RCode::Refused);
else
r->setRcode(RCode::NotAuth);
trc.d_time = tkey_out->d_inception;
trc.d_fudge = 300;
trc.d_mac = "";
- trc.d_origID = p->d.id;
+ trc.d_origID = p.d.id;
trc.d_eRcode = 0;
trc.d_otherData = "";
// this should cause it to lookup name context
throw PDNSException("EOF on TCP read");
len=ntohs(len);
- char *creply = new char[len];
+ std::unique_ptr<char[]> creply(new char[len]);
int n=0;
int numread;
while(n<len) {
- numread=d_rsock.read(creply+n, len-n);
+ numread=d_rsock.read(creply.get()+n, len-n);
if(numread<0) {
- delete[] creply;
throw PDNSException("tcp read failed: "+stringerror());
}
n+=numread;
}
- string reply(creply, len);
- delete[] creply;
+ string reply(creply.get(), len);
return reply;
}
DNSBackend *d_hinterBackend;
//! DNSPacket who asked this question
- DNSPacket *pkt_p;
+ DNSPacket* pkt_p;
DNSName qname;
//! Index of the current backend within the backends vector
Semaphore::Semaphore(unsigned int value)
{
- m_pSemaphore=new sem_t;
- if (sem_init(m_pSemaphore, 0, value) == -1) {
+ m_pSemaphore=make_unique<sem_t>();
+ if (sem_init(m_pSemaphore.get(), 0, value) == -1) {
g_log << Logger::Error << "Cannot create semaphore: " << stringerror() << endl;
exit(1);
}
int Semaphore::post()
{
- return sem_post(m_pSemaphore);
+ return sem_post(m_pSemaphore.get());
}
int Semaphore::wait()
{
int ret;
do
- ret = sem_wait(m_pSemaphore);
+ ret = sem_wait(m_pSemaphore.get());
while (ret == -1 && errno == EINTR);
return ret;
}
int Semaphore::tryWait()
{
- return sem_trywait(m_pSemaphore);
+ return sem_trywait(m_pSemaphore.get());
}
int Semaphore::getValue(Semaphore::sem_value_t *sval)
{
- return sem_getvalue(m_pSemaphore, sval);
+ return sem_getvalue(m_pSemaphore.get(), sval);
}
Semaphore::~Semaphore()
{
- delete m_pSemaphore;
}
#endif
sem_value_t m_count;
uint32_t m_nwaiters;
#else
- sem_t *m_pSemaphore;
+ std::unique_ptr<sem_t> m_pSemaphore;
#endif
protected:
#include "namespaces.hh"
#include "sstuff.hh"
-class WebServer;
-
class HttpRequest : public YaHTTP::Request {
public:
HttpRequest(const string& logprefix="") : YaHTTP::Request(), accept_json(false), accept_html(false), complete(false), logprefix(logprefix) { };
{
registerAllStats();
- d_ws = new AsyncWebServer(fdm, arg()["webserver-address"], arg().asNum("webserver-port"));
+ d_ws = std::unique_ptr<AsyncWebServer>(new AsyncWebServer(fdm, arg()["webserver-address"], arg().asNum("webserver-port")));
d_ws->setApiKey(arg()["api-key"]);
d_ws->setPassword(arg()["webserver-password"]);
d_ws->setLogLevel(arg()["webserver-loglevel"]);
void jsonstat(HttpRequest* req, HttpResponse *resp);
private:
- AsyncWebServer* d_ws;
+ std::unique_ptr<AsyncWebServer> d_ws{nullptr};
};
#endif /* PDNS_WSRECURSOR_HH */