md5.hh signingpipe.cc signingpipe.hh dnslabeltext.cc
#
-pdns_server_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library
-pdns_server_LDADD= -lpolarssl
+pdns_server_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library $(BOOST_SERIALIZATION_LDFLAGS)
+pdns_server_LDADD= -lpolarssl $(BOOST_SERIALIZATION_LIBS)
if BOTAN19
pdns_server_SOURCES += botan19signers.cc botansigners.cc
dynlistener.cc dns.cc randombackend.cc dnssecsigner.cc polarrsakeyinfra.cc md5.cc \
signingpipe.cc dnslabeltext.cc
-pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library/ $(BOOST_PROGRAM_OPTIONS_LDFLAGS)
-pdnssec_LDADD= -lpolarssl $(BOOST_PROGRAM_OPTIONS_LIBS)
+pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library/ $(BOOST_PROGRAM_OPTIONS_LDFLAGS) $(BOOST_SERIALIZATION_LDFLAGS)
+pdnssec_LDADD= -lpolarssl $(BOOST_PROGRAM_OPTIONS_LIBS) $(BOOST_SERIALIZATION_LIBS)
if BOTAN19
pdnssec_SOURCES += botan19signers.cc botansigners.cc
#include <boost/tuple/tuple_comparison.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/sequenced_index.hpp>
+
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/version.hpp>
+
+
#include "utility.hh"
#include "qtype.hh"
#include <time.h>
DNSResourceRecord() : qclass(1), priority(0), last_modified(0), d_place(ANSWER) {};
~DNSResourceRecord(){};
- string serialize() const;
- int unSerialize(const string &str);
-
// data
QType qtype; //!< qtype of this record, ie A, CNAME, MX etc
string qname; //!< the name of this record, for example: www.powerdns.com
string wildcardname;
string content; //!< what this record points to. Example: 10.1.2.3
- uint16_t priority; //!< For qtype's that support a priority or preference. Currently only MX
+ uint16_t priority; //!< For qtypes that support a priority or preference (MX, SRV)
uint32_t ttl; //!< Time To Live of this record
int domain_id; //!< If a backend implements this, the domain_id of the zone this record is in
time_t last_modified; //!< For autocalculating SOA serial numbers - the backend needs to fill this in
bool auth;
+ template<class Archive>
+ void serialize(Archive & ar, const unsigned int version)
+ {
+ ar & qtype;
+ ar & qclass;
+ ar & qname;
+ ar & wildcardname;
+ ar & content;
+ ar & priority;
+ ar & ttl;
+ ar & domain_id;
+ ar & last_modified;
+ ar & d_place;
+ ar & auth;
+ }
+
bool operator<(const DNSResourceRecord &b) const
{
if(qname < b.qname)
return(content < b.content);
return false;
}
-
-private:
- string escape(const string &str) const;
};
#ifdef _MSC_VER
QType();
code=n;
}
-
-string DNSResourceRecord::serialize() const
-{
- ostringstream ostr;
- ostr<<escape(qname)<<"|"<<qtype.getName()<<"|"<<escape(content)<<"|"<<ttl<<"|"<<priority<<"|"<<domain_id
- <<"|"<<last_modified;
- return ostr.str();
-}
-
-string DNSResourceRecord::escape(const string &name) const
-{
- string a;
-
- for(string::const_iterator i=name.begin();i!=name.end();++i)
- if(*i=='|' || *i=='\\'){
- a+='\\';
- a+=*i;
- }
- else
- a+=*i;
-
- return a;
-}
-
-int DNSResourceRecord::unSerialize(const string &source)
-{
- // qname|qtype|content|ttl|priority|domain_id|last_modified;
- string chunk;
- unsigned int m=0;
- for(int n=0;n<7;++n) {
- chunk="";
- for(;m<source.size();++m) {
- if(source[m]=='\\' && m+1<source.size())
- chunk.append(1,source[++m]);
- else if(source[m]=='|') {
- ++m;
- break;
- }
- else
- chunk.append(1,source[m]);
- }
- switch(n) {
- case 0:
- qname=chunk;
- break;
- case 1:
- qtype=chunk;
- break;
- case 2:
- content=chunk;
- break;
- case 3:
- ttl=atoi(chunk.c_str());
- break;
- case 4:
- priority=atoi(chunk.c_str());
- break;
- case 5:
- domain_id=atoi(chunk.c_str());
- break;
- case 6:
- last_modified=atoi(chunk.c_str());
- break;
- }
- }
- return m;
-}
-
-
-#if 0
-int main(int argc, char **argv)
-{
- QType t;
-
- cout << endl;
- cout << "Assiging a '6'" << endl;
- t=6;
- cout << "Code is now " << t.getCode() << endl;
- cout << "Name is now " << t.getName() << endl;
-
- cout << endl;
-
- cout << "Assiging a 'CNAME'" << endl;
- t="CNAME";
- cout << "Code is now " << t.getCode() << endl;
- cout << "Name is now " << t.getName() << endl;
-
- QType u;
- u="SOA";
- cout << u.getCode() << endl;
-
-
-}
-#endif
#include <string>
#include <vector>
#include <utility>
-
#include "namespaces.hh"
/** The QType class is meant to deal easily with the different kind of resource types, like 'A', 'NS',
return code < rhs.code;
}
+ template<class Archive>
+ void serialize(Archive &ar, const unsigned int version)
+ {
+ ar & code;
+ }
+
bool operator==(const QType &) const; //!< equality operator
const string getName() const; //!< Get a string representation of this type
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/binary_oarchive.hpp>
+
#include "packetcache.hh"
#include "utility.hh"
#include <string>
#include <map>
#include <sys/types.h>
-
+#include <sstream>
#include <errno.h>
#include <iostream>
#include <sstream>
#include <functional>
#include <boost/foreach.hpp>
-
#include "dns.hh"
#include "arguments.hh"
#include "dnsbackend.hh"
d_question.zoneId=-1;
if(sd.db!=(DNSBackend *)-1) {
- int cstat=cacheHas(d_question,d_answer);
- if(cstat==0) {
+ int cstat=cacheHas(d_question,d_answers);
+ if(cstat==0) { // negative
return false;
}
- else if(cstat==1) {
- // ehm
- fillSOAData(d_answer.content,sd);
- sd.domain_id=d_answer.domain_id;
- sd.ttl=d_answer.ttl;
+ else if(cstat==1 && !d_answers.empty()) {
+ fillSOAData(d_answers[0].content,sd);
+ sd.domain_id=d_answers[0].domain_id;
+ sd.ttl=d_answers[0].ttl;
sd.db=0;
return true;
}
rr.content=serializeSOAData(sd);
rr.ttl=sd.ttl;
rr.domain_id=sd.domain_id;
- addOneCache(d_question,rr);
+ vector<DNSResourceRecord> rrs;
+ rrs.push_back(rr);
+ addCache(d_question, rrs);
return true;
}
// silly Solaris fix
#undef PC
-int UeberBackend::cacheHas(const Question &q, DNSResourceRecord &rr)
+// returns -1 for miss, 0 for negative match, 1 for hit
+int UeberBackend::cacheHas(const Question &q, vector<DNSResourceRecord> &rrs)
{
extern PacketCache PC;
static unsigned int *qcachehit=S.getPointer("query-cache-hit");
string content;
// L<<Logger::Warning<<"looking up: '"<<q.qname+"'|N|"+q.qtype.getName()+"|"+itoa(q.zoneId)<<endl;
- bool ret=PC.getEntry(q.qname, q.qtype, PacketCache::QUERYCACHE, content, q.zoneId); // think about lowercasing here
-
+ bool ret=PC.getEntry(q.qname, q.qtype, PacketCache::QUERYCACHE, content, -1); // think about lowercasing here
if(!ret) {
(*qcachemiss)++;
return -1;
(*qcachehit)++;
if(content.empty()) // negatively cached
return 0;
- rr.unSerialize(content);
+
+ std::istringstream istr(content);
+ boost::archive::binary_iarchive boa(istr);
+
+ boa >> rrs;
return 1;
}
static int negqueryttl=::arg().asNum("negquery-cache-ttl");
if(!negqueryttl)
return;
- // L<<Logger::Warning<<"negative inserting: "<<q.qname+"|N|"+q.qtype.getName()+"|"+itoa(q.zoneId)<<endl;
- PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, "", negqueryttl, q.zoneId);
+ PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, "", negqueryttl, -1);
}
-void UeberBackend::addOneCache(const Question &q, const DNSResourceRecord &rr)
+void UeberBackend::addCache(const Question &q, const vector<DNSResourceRecord> &rrs)
{
extern PacketCache PC;
static int queryttl=::arg().asNum("query-cache-ttl");
if(!queryttl)
return;
+
// L<<Logger::Warning<<"inserting: "<<q.qname+"|N|"+q.qtype.getName()+"|"+itoa(q.zoneId)<<endl;
- PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, rr.serialize(), queryttl, q.zoneId);
+ std::ostringstream ostr;
+ boost::archive::binary_oarchive boa(ostr);
+
+ boa << rrs;
+ PC.insert(q.qname, q.qtype, PacketCache::QUERYCACHE, ostr.str(), queryttl, -1);
}
void UeberBackend::alsoNotifies(const string &domain, set<string> *ips)
else {
d_question.qtype=qtype;
d_question.qname=qname;
- d_question.zoneId=zoneId;
- int cstat=cacheHas(d_question,d_answer);
+ d_question.zoneId=-1;
+ int cstat=cacheHas(d_question, d_answers);
if(cstat<0) { // nothing
d_negcached=d_cached=false;
(d_handle.d_hinterBackend=backends[d_handle.i++])->lookup(qtype, qname,pkt_p,zoneId);
else if(cstat==0) {
d_negcached=true;
d_cached=false;
+ d_answers.clear();
}
else {
d_negcached=false;
d_cached=true;
+ d_cachehandleiter = d_answers.begin();
}
}
d_handle.parent=this;
-
}
bool UeberBackend::get(DNSResourceRecord &rr)
}
if(d_cached) {
- rr=d_answer;
- d_negcached=true; // ugly, confusing
- return true;
+ if(d_cachehandleiter != d_answers.end()) {
+ rr=*d_cachehandleiter++;;
+ return true;
+ }
+ return false;
}
if(!d_handle.get(rr)) {
if(!d_ancount && !d_handle.qname.empty()) // don't cache axfr
addNegCache(d_question);
- if(d_ancount==1) {
- addOneCache(d_question, lastrr);
- }
-
+ addCache(d_question, d_answers);
+ d_answers.clear();
return false;
}
-
- if(!d_ancount++) {
- lastrr=rr;
- }
+ d_ancount++;
+ d_answers.push_back(rr);
return true;
}
string qname;
int zoneId;
}d_question;
- DNSResourceRecord d_answer;
+ vector<DNSResourceRecord> d_answers;
+ vector<DNSResourceRecord>::const_iterator d_cachehandleiter;
- int cacheHas(const Question &q, DNSResourceRecord &rr);
+ int cacheHas(const Question &q, vector<DNSResourceRecord> &rrs);
void addNegCache(const Question &q);
- void addOneCache(const Question &q, const DNSResourceRecord &rr);
+ void addCache(const Question &q, const vector<DNSResourceRecord> &rrs);
static pthread_mutex_t d_mut;
static pthread_cond_t d_cond;