[svn] commit: r1965 - in /experiments/jinmei-onmemdb/src: bin/auth/ bin/auth/tests/ lib/dns/ lib/dns/rdata/generic/ lib/dns/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri May 28 09:57:34 UTC 2010
Author: jinmei
Date: Fri May 28 09:57:34 2010
New Revision: 1965
Log:
experimental on memory DB implementation for reference
Added:
experiments/jinmei-onmemdb/src/bin/auth/compilezone.cc
experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.cc
experiments/jinmei-onmemdb/src/bin/auth/rbt_datasrc.h
experiments/jinmei-onmemdb/src/bin/auth/root_datasrc.cc
experiments/jinmei-onmemdb/src/bin/auth/root_datasrc.h
experiments/jinmei-onmemdb/src/bin/auth/rootdb
experiments/jinmei-onmemdb/src/bin/auth/tests/rbt_datasrc_unittest.cc
Modified:
experiments/jinmei-onmemdb/src/bin/auth/Makefile.am
experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc
experiments/jinmei-onmemdb/src/bin/auth/main.cc
experiments/jinmei-onmemdb/src/bin/auth/tests/Makefile.am
experiments/jinmei-onmemdb/src/lib/dns/message.cc
experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc
experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h
experiments/jinmei-onmemdb/src/lib/dns/name.cc
experiments/jinmei-onmemdb/src/lib/dns/name.h
experiments/jinmei-onmemdb/src/lib/dns/rdata/generic/soa_6.h
experiments/jinmei-onmemdb/src/lib/dns/rrset.cc
experiments/jinmei-onmemdb/src/lib/dns/rrset.h
experiments/jinmei-onmemdb/src/lib/dns/tests/name_unittest.cc
Modified: experiments/jinmei-onmemdb/src/bin/auth/Makefile.am
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/Makefile.am (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/Makefile.am Fri May 28 09:57:34 2010
@@ -27,10 +27,15 @@
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
BUILT_SOURCES = spec_config.h
-pkglibexec_PROGRAMS = b10-auth
+pkglibexec_PROGRAMS = b10-auth b10-compilezone
b10_auth_SOURCES = auth_srv.cc auth_srv.h
b10_auth_SOURCES += common.h
b10_auth_SOURCES += main.cc
+
+b10_auth_SOURCES += offsetptr.h
+b10_auth_SOURCES += rbt_datasrc.h rbt_datasrc.cc
+b10_auth_SOURCES += root_datasrc.h root_datasrc.cc
+
b10_auth_LDADD = $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
b10_auth_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
b10_auth_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
@@ -45,6 +50,11 @@
b10_auth_LDADD += $(BOOST_SYSTEM_LIB)
endif
+b10_compilezone_SOURCES = compilezone.cc
+b10_compilezone_SOURCES += rbt_datasrc.h rbt_datasrc.cc
+b10_compilezone_LDADD = $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
+b10_compilezone_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
+
# TODO: config.h.in is wrong because doesn't honor pkgdatadir
# and can't use @datadir@ because doesn't expand default ${prefix}
b10_authdir = $(DESTDIR)$(pkgdatadir)
Modified: experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/auth_srv.cc Fri May 28 09:57:34 2010
@@ -42,7 +42,10 @@
#include "common.h"
#include "auth_srv.h"
-
+#include "rbt_datasrc.h"
+#include "root_datasrc.h"
+
+#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
@@ -53,6 +56,8 @@
using namespace isc::dns::rdata;
using namespace isc::data;
using namespace isc::config;
+
+typedef boost::shared_ptr<RbtRRset> RbtRRsetPtr;
class AuthSrvImpl {
private:
@@ -61,6 +66,19 @@
AuthSrvImpl& operator=(const AuthSrvImpl& source);
public:
AuthSrvImpl();
+ RbtRRsetPtr getRbtRRset() {
+ assert(rrset_counter_ < MAXRRS_IN_MESSAGE); // XXX
+ return (rrsets_[rrset_counter_++]);
+ }
+ void clearRbtRRsets() {
+ for (int i = 0; i < rrset_counter_; ++i) {
+ rrsets_[i]->clear();
+ }
+ rrset_counter_ = 0;
+ }
+ void processRootQuery(Message& message);
+ void addAdditional(Message& message, RbtRRsetPtr rrset,
+ const RRType& rrtype);
isc::data::ElementPtr setDbFile(const isc::data::ElementPtr config);
@@ -74,11 +92,17 @@
bool verbose_mode_;
+ const RbtDataSrc* mem_datasrc_;
+ static const unsigned int MAXRRS_IN_MESSAGE = 256; // XXX
+ RbtRRsetPtr rrsets_[MAXRRS_IN_MESSAGE];
+ unsigned int rrset_counter_;
+
/// Currently non-configurable, but will be.
static const uint16_t DEFAULT_LOCAL_UDPSIZE = 4096;
};
-AuthSrvImpl::AuthSrvImpl() : cs_(NULL), verbose_mode_(false)
+AuthSrvImpl::AuthSrvImpl() : cs_(NULL), verbose_mode_(false),
+ mem_datasrc_(NULL), rrset_counter_(0)
{
// cur_datasrc_ is automatically initialized by the default constructor,
// effectively being an empty (sqlite) data source. once ccsession is up
@@ -86,6 +110,123 @@
// add static data source
data_sources_.addDataSrc(ConstDataSrcPtr(new StaticDataSrc));
+
+ if (getenv("ROOTSERVER") != NULL) {
+ cerr << "[AuthSrv] generating root zone data source" << endl;
+ mem_datasrc_ = createRootRbtDataSrc();
+ } else {
+ const char* dbfile = getenv("DBFILE");
+ const char* dborigin = getenv("DBORIGIN");
+ if (dbfile != NULL && dborigin != NULL) {
+ cerr << "[AuthSrv] generating " << dborigin << " zone data from "
+ << dbfile << endl;
+ mem_datasrc_ = new RbtDataSrc(Name(dborigin), *dbfile,
+ RbtDataSrc::SERVE);
+ }
+ }
+
+ if (mem_datasrc_ != NULL) {
+ for (int i = 0; i < MAXRRS_IN_MESSAGE; ++i) {
+ rrsets_[i] = RbtRRsetPtr(new RbtRRset);
+ }
+ }
+}
+
+void
+AuthSrvImpl::addAdditional(Message& message, RbtRRsetPtr rrset,
+ const RRType& rrtype)
+{
+ if (rrtype != RRType::NS()) {
+ return;
+ }
+
+ RbtDataSrcResult result;
+ RbtRdataHandle rdata;
+ for (result = rrset->getFirstRdata(rdata);
+ result == RbtDataSrcSuccess;
+ result = rdata.moveToNext()) {
+ RbtRdataFieldHandle field;
+ result = rdata.getFirstField(field);
+ if (result == RbtDataSrcSuccess) {
+ RbtNode node;
+ field.convertToRbtNode(&node);
+
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::A(), *rrset);
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::ADDITIONAL(), rrset);
+ }
+
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::AAAA(), *rrset);
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::ADDITIONAL(), rrset);
+ }
+ }
+ }
+}
+
+inline void
+AuthSrvImpl::processRootQuery(Message& message) {
+ QuestionPtr question = *message.beginQuestion();
+ RbtNode node;
+ RbtDataSrcResult result =
+ mem_datasrc_->findNode(question->getName(), &node);
+ RbtRRsetPtr rrset;
+
+ switch (result) {
+ case RbtDataSrcSuccess:
+ rrset = getRbtRRset();
+ result = node.findRRset(question->getType(), *rrset);
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::ANSWER(), rrset);
+
+ result = mem_datasrc_->getApexNode(&node);
+ if (result == RbtDataSrcSuccess) {
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::NS(), *rrset);
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::AUTHORITY(), rrset);
+ addAdditional(message, rrset, RRType::NS());
+ }
+ }
+ } else {
+ result = mem_datasrc_->getApexNode(&node);
+ if (result == RbtDataSrcSuccess) {
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::SOA(), *rrset);
+ }
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::AUTHORITY(), rrset);
+ }
+ }
+ break;
+ case RbtDataSrcPartialMatch:
+ // reset AA, add NS, add glues
+ message.clearHeaderFlag(MessageFlag::AA());
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::NS(), *rrset);
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::AUTHORITY(), rrset);
+ addAdditional(message, rrset, RRType::NS());
+ }
+ break;
+ case RbtDataSrcNotFound:
+ // reset AA, add SOA in auth, set NXDOMAIN
+ message.clearHeaderFlag(MessageFlag::AA());
+ message.setRcode(Rcode::NXDOMAIN());
+ result = mem_datasrc_->getApexNode(&node);
+ if (result == RbtDataSrcSuccess) {
+ rrset = getRbtRRset();
+ result = node.findRRset(RRType::SOA(), *rrset);
+ }
+ if (result == RbtDataSrcSuccess) {
+ message.addRRset(Section::AUTHORITY(), rrset);
+ }
+ break;
+ default:
+ assert(0); // XXX
+ }
}
AuthSrv::AuthSrv() : impl_(new AuthSrvImpl) {
@@ -207,7 +348,7 @@
return (true);
} // other exceptions will be handled at a higher layer.
- if (impl_->verbose_mode_) {
+ if (0 && impl_->verbose_mode_) {
cerr << "[AuthSrv] received a message:\n" << message.toText() << endl;
}
@@ -238,24 +379,38 @@
message.setDNSSECSupported(dnssec_ok);
message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
- try {
- Query query(message, dnssec_ok);
- impl_->data_sources_.doQuery(query);
- } catch (const Exception& ex) {
- if (impl_->verbose_mode_) {
- cerr << "Internal error, returning SERVFAIL: " << ex.what() << endl;
- }
- makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
- impl_->verbose_mode_);
- return (true);
+ if (impl_->mem_datasrc_ != NULL) {
+ impl_->processRootQuery(message);
+ CompressOffset* offsets = // XXX bad cast
+ reinterpret_cast<CompressOffset*>(response_renderer.getArg());
+ if (offsets != NULL) {
+ memset(offsets, 0xff, sizeof(*offsets));
+ }
+ } else {
+ try {
+ Query query(message, dnssec_ok);
+ impl_->data_sources_.doQuery(query);
+ } catch (const Exception& ex) {
+ if (impl_->verbose_mode_) {
+ cerr << "Internal error, returning SERVFAIL: " << ex.what()
+ << endl;
+ }
+ makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
+ impl_->verbose_mode_);
+ return (true);
+ }
}
response_renderer.setLengthLimit(udp_buffer ? remote_bufsize : 65535);
message.toWire(response_renderer);
- if (impl_->verbose_mode_) {
+ if (0 && impl_->verbose_mode_) {
cerr << "sending a response (" <<
boost::lexical_cast<string>(response_renderer.getLength())
<< " bytes):\n" << message.toText() << endl;
+ }
+
+ if (impl_->mem_datasrc_ != NULL) {
+ impl_->clearRbtRRsets();
}
return (true);
Modified: experiments/jinmei-onmemdb/src/bin/auth/main.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/main.cc (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/main.cc Fri May 28 09:57:34 2010
@@ -51,6 +51,7 @@
#include "spec_config.h"
#include "common.h"
#include "auth_srv.h"
+#include "rbt_datasrc.h"
using namespace std;
#ifdef USE_XFROUT
@@ -154,7 +155,7 @@
socket_(io_service),
response_buffer_(0),
responselen_buffer_(TCP_MESSAGE_LENGTHSIZE),
- response_renderer_(response_buffer_),
+ response_renderer_(response_buffer_, &offsets_),
dns_message_(Message::PARSE)
{}
@@ -245,6 +246,7 @@
enum { MAX_LENGTH = 65535 };
static const size_t TCP_MESSAGE_LENGTHSIZE = 2;
char data_[MAX_LENGTH];
+ struct CompressOffset offsets_;
};
class TCPServer {
@@ -298,7 +300,7 @@
io_service_(io_service),
socket_(io_service, af == AF_INET6 ? udp::v6() : udp::v4()),
response_buffer_(0),
- response_renderer_(response_buffer_),
+ response_renderer_(response_buffer_, &offsets_),
dns_message_(Message::PARSE)
{
// Set v6-only (we use a different instantiation for v4,
@@ -363,6 +365,7 @@
udp::endpoint sender_endpoint_;
enum { MAX_LENGTH = 4096 };
char data_[MAX_LENGTH];
+ struct CompressOffset offsets_;
};
struct ServerSet {
@@ -655,14 +658,15 @@
int ss = srv->configSession()->getSocket();
Message dns_message(Message::PARSE);
+ struct CompressOffset offsets;
OutputBuffer resonse_buffer(0);
- MessageRenderer response_renderer(resonse_buffer);
+ MessageRenderer response_renderer(resonse_buffer, &offsets);
+ ++nfds;
running = true;
while (running) {
fd_set fds = fds_base;
FD_SET(ss, &fds);
- ++nfds;
if (srv->configSession()->hasQueuedMsgs()) {
srv->configSession()->checkCommand();
@@ -670,7 +674,7 @@
int n = select(nfds, &fds, NULL, NULL, NULL);
if (n < 0) {
if (errno != EINTR) {
- isc_throw(FatalError, "select error");
+ isc_throw(FatalError, "select error: " << strerror(errno));
}
continue;
}
Modified: experiments/jinmei-onmemdb/src/bin/auth/tests/Makefile.am
==============================================================================
--- experiments/jinmei-onmemdb/src/bin/auth/tests/Makefile.am (original)
+++ experiments/jinmei-onmemdb/src/bin/auth/tests/Makefile.am Fri May 28 09:57:34 2010
@@ -12,6 +12,11 @@
run_unittests_SOURCES += ../auth_srv.h ../auth_srv.cc
run_unittests_SOURCES += auth_srv_unittest.cc
run_unittests_SOURCES += run_unittests.cc
+
+run_unittests_SOURCES += ../rbt_datasrc.h ../rbt_datasrc.cc
+run_unittests_SOURCES += ../root_datasrc.h ../root_datasrc.cc
+run_unittests_SOURCES += rbt_datasrc_unittest.cc
+
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
Modified: experiments/jinmei-onmemdb/src/lib/dns/message.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/message.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/message.cc Fri May 28 09:57:34 2010
@@ -374,10 +374,13 @@
impl_->rrsets_[sectionCodeToId(section)].push_back(rrset);
impl_->counts_[section.getCode()] += rrset->getRdataCount();
- RRsetPtr sp = rrset->getRRsig();
- if (sign && sp != NULL) {
- impl_->rrsets_[sectionCodeToId(section)].push_back(sp);
- impl_->counts_[section.getCode()] += sp->getRdataCount();
+
+ if (sign) {
+ RRsetPtr sp = rrset->getRRsig();
+ if (sp != NULL) {
+ impl_->rrsets_[sectionCodeToId(section)].push_back(sp);
+ impl_->counts_[section.getCode()] += sp->getRdataCount();
+ }
}
}
Modified: experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.cc Fri May 28 09:57:34 2010
@@ -176,7 +176,11 @@
};
MessageRenderer::MessageRenderer(OutputBuffer& buffer) :
- impl_(new MessageRendererImpl(buffer))
+ impl_(new MessageRendererImpl(buffer)), arg_(NULL)
+{}
+
+MessageRenderer::MessageRenderer(OutputBuffer& buffer, void* arg) :
+ impl_(new MessageRendererImpl(buffer)), arg_(arg)
{}
MessageRenderer::~MessageRenderer() {
Modified: experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/messagerenderer.h Fri May 28 09:57:34 2010
@@ -104,6 +104,8 @@
/// \param buffer An \c OutputBuffer object to which wire format data is
/// written.
MessageRenderer(OutputBuffer& buffer);
+ MessageRenderer(OutputBuffer& buffer, void* arg); // ad hoc extension
+ void* getArg() { return (arg_); }
/// \brief The destructor.
///
/// The destructor does nothing on the given \c buffer on construction;
@@ -261,6 +263,7 @@
private:
struct MessageRendererImpl;
MessageRendererImpl* impl_;
+ void* arg_; // for ad hoc extension
};
}
}
Modified: experiments/jinmei-onmemdb/src/lib/dns/name.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/name.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/name.cc Fri May 28 09:57:34 2010
@@ -740,10 +740,177 @@
return (*this);
}
+void
+Name::setLabelSequence(LabelSequence& sequence) const {
+ // XXX: the use of ndata_.data() is probably not a good idea.
+ // we should perhaps consider changing the type of ndata to a plain
+ // vector.
+ // XXX: use of reinterpret_cast is of course bad. we should actually
+ // change the type of ndata to unsigned char-based.
+ sequence.set(length_, reinterpret_cast<const unsigned char*>(ndata_.data()),
+ offsets_.size(), &offsets_[0]);
+}
+
+NameComparisonResult
+LabelSequence::compare(const LabelSequence& other) const {
+ // XXX code duplicate with Name::compare()
+ unsigned int nlabels = 0;
+ unsigned int l1 = offsetlen_;
+ unsigned int l2 = other.offsetlen_;
+ int ldiff = (int)l1 - (int)l2;
+ unsigned int l = (ldiff < 0) ? l1 : l2;
+
+ while (l > 0) {
+ --l;
+ --l1;
+ --l2;
+ size_t pos1 = offsets_[l1];
+ size_t pos2 = other.offsets_[l2];
+ unsigned int count1 = ndata_[pos1++];
+ unsigned int count2 = other.ndata_[pos2++];
+
+ assert(count1 <= Name::MAX_LABELLEN && count2 <= Name::MAX_LABELLEN);
+
+ int cdiff = (int)count1 - (int)count2;
+ unsigned int count = (cdiff < 0) ? count1 : count2;
+
+ while (count > 0) {
+ unsigned char label1 = ndata_[pos1];
+ unsigned char label2 = other.ndata_[pos2];
+
+ int chdiff = (int)maptolower[label1] - (int)maptolower[label2];
+ if (chdiff != 0) {
+ return (NameComparisonResult(chdiff, nlabels,
+ nlabels > 0 ?
+ NameComparisonResult::COMMONANCESTOR :
+ NameComparisonResult::NONE));
+ }
+ --count;
+ ++pos1;
+ ++pos2;
+ }
+ if (cdiff != 0) {
+ return (NameComparisonResult(cdiff, nlabels,
+ nlabels > 0 ?
+ NameComparisonResult::COMMONANCESTOR :
+ NameComparisonResult::NONE));
+ }
+ ++nlabels;
+ }
+
+ if (ldiff < 0) {
+ return (NameComparisonResult(ldiff, nlabels,
+ NameComparisonResult::SUPERDOMAIN));
+ } else if (ldiff > 0) {
+ return (NameComparisonResult(ldiff, nlabels,
+ NameComparisonResult::SUBDOMAIN));
+ }
+ return (NameComparisonResult(ldiff, nlabels, NameComparisonResult::EQUAL));
+}
+
+void
+LabelSequence::set(const unsigned char nlen, const unsigned char* ndata,
+ const unsigned char offsetlen, const unsigned char* offsets)
+{
+ // XXX: we should validate the parameters
+ nbeg_ = 0;
+ nlen_ = nlen;
+ ndata_ = ndata;
+ obeg_ = 0;
+ offsetlen_ = offsetlen;
+ offsets_ = offsets;
+}
+
+void
+LabelSequence::set(const unsigned char* const data) {
+ // set from the "native" binary format of sequence.
+ const unsigned char* cp = data;
+
+ nlen_ = *cp++;
+ ndata_ = cp;
+ cp += nlen_;
+ offsetlen_ = *cp++;
+ offsets_ = cp;
+}
+
+void
+LabelSequence::toWire(OutputBuffer& buffer) const {
+ assert(nlen_ != 0);
+ buffer.writeUint8(static_cast<uint8_t>(nlen_));
+ buffer.writeData(&ndata_[nbeg_], nlen_);
+ buffer.writeUint8(static_cast<uint8_t>(offsetlen_));
+
+ if (obeg_ > 0) { // need to adjust the offsets
+ vector<unsigned char> new_offsets(offsets_ + obeg_,
+ offsets_ + obeg_ + offsetlen_);
+ for (int i = 0; i < offsetlen_; ++i) { // XXX: use algorithm
+ new_offsets[i] -= offsets_[obeg_];
+ }
+ buffer.writeData(&new_offsets[0], offsetlen_);
+ } else {
+ buffer.writeData(&offsets_[obeg_], offsetlen_);
+ }
+}
+
+void
+LabelSequence::split(int labels) {
+ assert(nlen_ != 0 && labels != 0 &&
+ labels < (int)offsetlen_ && -labels < (int)offsetlen_);
+ if (labels > 0) {
+ obeg_ += labels;
+ nlen_ -= (&ndata_[offsets_[obeg_]] - &ndata_[nbeg_]);
+ nbeg_ = offsets_[obeg_];
+ offsetlen_ -= labels;
+ } else {
+ labels = -labels; // # of trailing labels excluded
+ offsetlen_ -= labels;
+ nlen_ = &ndata_[offsets_[obeg_ + offsetlen_]] - ndata_;
+ }
+}
+
+void
+LabelSequence::split(LabelSequence& prefix, LabelSequence& suffix,
+ const int labels) const
+{
+ assert(nlen_ != 0 && labels != 0 &&
+ labels < (int)offsetlen_ && -labels < (int)offsetlen_);
+ suffix = *this;
+ prefix = *this;
+ if (labels > 0) {
+ prefix.split(-(offsetlen_ - labels));
+ suffix.split(labels);
+ } else {
+ suffix.split(offsetlen_ + labels);
+ prefix.split(labels);
+ }
+}
+
+string
+LabelSequence::toText() const {
+ assert(nlen_ != 0);
+ vector<unsigned char> placeholder(ndata_ + nbeg_, ndata_ + nbeg_ + nlen_);
+ bool omit_final_dot = false;
+
+ if (ndata_[offsets_[obeg_ + offsetlen_ - 1]] != '\0') {
+ // ensure the data is null terminated
+ placeholder.push_back('\0');
+ omit_final_dot = true;
+ }
+
+ InputBuffer b(&placeholder[0], placeholder.size());
+ return (Name(b, false).toText(omit_final_dot));
+}
+
std::ostream&
operator<<(std::ostream& os, const Name& name) {
os << name.toText();
return (os);
}
-}
-}
+
+std::ostream&
+operator<<(std::ostream& os, const LabelSequence& sequence) {
+ os << sequence.toText();
+ return (os);
+}
+}
+}
Modified: experiments/jinmei-onmemdb/src/lib/dns/name.h
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/name.h (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/name.h Fri May 28 09:57:34 2010
@@ -129,10 +129,11 @@
/// If, on the other hand, we finally decide we really don't need that
/// notion, we'll probably reconsider the design here, too.
enum NameRelation {
- SUPERDOMAIN = 0,
- SUBDOMAIN = 1,
- EQUAL = 2,
- COMMONANCESTOR = 3
+ NONE = 0, // describe it.
+ SUPERDOMAIN = 1,
+ SUBDOMAIN = 2,
+ EQUAL = 3,
+ COMMONANCESTOR = 4
};
///
@@ -163,6 +164,32 @@
int order_;
unsigned int nlabels_;
NameRelation relation_;
+};
+
+class LabelSequence {
+public:
+ LabelSequence() : nbeg_(0), nlen_(0), ndata_(NULL),
+ obeg_(0), offsetlen_(0), offsets_(NULL) {}
+ void set(unsigned char nlen, const unsigned char* ndata,
+ unsigned char offsetlen, const unsigned char* offsets);
+ void set(const unsigned char* data);
+ NameComparisonResult compare(const LabelSequence& other) const;
+ void toWire(OutputBuffer& buffer) const;
+ unsigned int getDataLength() const { return (nlen_); }
+ const unsigned char* getData() const { return (ndata_); }
+ // the following two may not be necessary.
+ unsigned int getOffsetLength() const { return (offsetlen_); }
+ const unsigned char* getOffsets() const { return (offsets_); }
+ std::string toText() const;
+ void split(int labels);
+ void split(LabelSequence& prefix, LabelSequence& suffix, int labels) const;
+private:
+ unsigned int nbeg_;
+ unsigned int nlen_;
+ const unsigned char* ndata_;
+ unsigned int obeg_;
+ unsigned int offsetlen_;
+ const unsigned char* offsets_;
};
///
@@ -626,6 +653,9 @@
bool isWildcard() const;
//@}
+ // experimental extension
+ void setLabelSequence(LabelSequence& sequence) const;
+
///
/// \name Protocol constants
///
@@ -691,6 +721,9 @@
/// parameter \c os after the insertion operation.
std::ostream&
operator<<(std::ostream& os, const Name& name);
+
+std::ostream&
+operator<<(std::ostream& os, const LabelSequence& sequence);
}
}
#endif // __NAME_H
Modified: experiments/jinmei-onmemdb/src/lib/dns/rdata/generic/soa_6.h
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/rdata/generic/soa_6.h (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/rdata/generic/soa_6.h Fri May 28 09:57:34 2010
@@ -36,6 +36,13 @@
explicit SOA(const Name& mname, const Name& rname, uint32_t serial,
uint32_t refresh, uint32_t retry, uint32_t expire,
uint32_t minimum);
+
+ ///
+ /// Specialized methods
+ ///
+ const Name& getMName() const { return (mname_); }
+ const Name& getRName() const { return (rname_); }
+
private:
/// Note: this is a prototype version; we may reconsider
/// this representation later.
Modified: experiments/jinmei-onmemdb/src/lib/dns/rrset.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/rrset.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/rrset.cc Fri May 28 09:57:34 2010
@@ -13,6 +13,8 @@
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
+
+#include <config.h>
#include <algorithm>
#include <string>
@@ -260,5 +262,26 @@
{
return (RdataIteratorPtr(new BasicRdataIterator(impl_->rdatalist_)));
}
-}
-}
+
+void
+AbstractRRset::addRRsig(AbstractRRset& sigs UNUSED_PARAM)
+{
+}
+
+void
+AbstractRRset::addRRsig(RRsetPtr sigs UNUSED_PARAM)
+{
+}
+
+void
+AbstractRRset::removeRRsig()
+{
+}
+
+RRsetPtr
+AbstractRRset::getRRsig() { // XXX
+ return (RRsetPtr());
+}
+
+}
+}
Modified: experiments/jinmei-onmemdb/src/lib/dns/rrset.h
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/rrset.h (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/rrset.h Fri May 28 09:57:34 2010
@@ -57,14 +57,14 @@
///
/// This type is commonly used as an argument of various functions defined
/// in this library in order to handle RRsets in a polymorphic manner.
-typedef boost::shared_ptr<RRset> RRsetPtr;
+typedef boost::shared_ptr<AbstractRRset> RRsetPtr;
/// \brief A pointer-like type pointing to an (immutable) \c RRset
/// object.
///
/// This type is commonly used as an argument of various functions defined
/// in this library in order to handle RRsets in a polymorphic manner.
-typedef boost::shared_ptr<const RRset> ConstRRsetPtr;
+typedef boost::shared_ptr<const AbstractRRset> ConstRRsetPtr;
/// \brief A pointer-like type point to an \c RdataIterator object.
typedef boost::shared_ptr<RdataIterator> RdataIteratorPtr;
@@ -397,6 +397,12 @@
/// object.
virtual RdataIteratorPtr getRdataIterator() const = 0;
//@}
+
+ // experimental hack for prototype (XXX)
+ virtual void addRRsig(AbstractRRset& sigs);
+ virtual void addRRsig(RRsetPtr sigs);
+ virtual void removeRRsig();
+ virtual RRsetPtr getRRsig();
};
/// \brief The \c RdataIterator class is an abstract base class that
@@ -716,7 +722,7 @@
/// \brief Clear the RRSIGs for this RRset
void removeRRsig() { rrsig_ = RRsetPtr(); }
-
+
/// \brief Return a pointer to this RRset's RRSIG RRset
RRsetPtr getRRsig() { return (rrsig_); }
private:
Modified: experiments/jinmei-onmemdb/src/lib/dns/tests/name_unittest.cc
==============================================================================
--- experiments/jinmei-onmemdb/src/lib/dns/tests/name_unittest.cc (original)
+++ experiments/jinmei-onmemdb/src/lib/dns/tests/name_unittest.cc Fri May 28 09:57:34 2010
@@ -603,4 +603,104 @@
oss << example_name;
EXPECT_EQ(example_name.toText(), oss.str());
}
-}
+
+TEST_F(NameTest, LabelSequenceFromName) {
+ LabelSequence sequence;
+ example_name.setLabelSequence(sequence);
+ EXPECT_EQ(example_name.getLength(), sequence.getDataLength());
+ EXPECT_EQ(example_name.getLabelCount(), sequence.getOffsetLength());
+}
+
+TEST_F(NameTest, LabelSequenceSplit) {
+ LabelSequence sequence;
+ example_name.setLabelSequence(sequence);
+ sequence.split(1);
+ EXPECT_EQ("example.com.", sequence.toText());
+ example_name.setLabelSequence(sequence);
+ sequence.split(2);
+ EXPECT_EQ("com.", sequence.toText());
+ example_name.setLabelSequence(sequence);
+ sequence.split(3);
+ EXPECT_EQ(".", sequence.toText());
+ example_name.setLabelSequence(sequence);
+ sequence.split(-1);
+ EXPECT_EQ("www.example.com", sequence.toText());
+ example_name.setLabelSequence(sequence);
+ sequence.split(-2);
+ EXPECT_EQ("www.example", sequence.toText());
+ example_name.setLabelSequence(sequence);
+ sequence.split(-3);
+ EXPECT_EQ("www", sequence.toText());
+}
+
+TEST_F(NameTest, LabelSequenceSplitToTwo) {
+ LabelSequence sequence, prefix, suffix;
+ example_name.setLabelSequence(sequence);
+
+ sequence.split(prefix, suffix, 1);
+ EXPECT_EQ("www", prefix.toText());
+ EXPECT_EQ("example.com.", suffix.toText());
+
+ sequence.split(prefix, suffix, 2);
+ EXPECT_EQ("www.example", prefix.toText());
+ EXPECT_EQ("com.", suffix.toText());
+
+ sequence.split(prefix, suffix, 3);
+ EXPECT_EQ("www.example.com", prefix.toText());
+ EXPECT_EQ(".", suffix.toText());
+
+ sequence.split(prefix, suffix, -1);
+ EXPECT_EQ("www.example.com", prefix.toText());
+ EXPECT_EQ(".", suffix.toText());
+
+ sequence.split(prefix, suffix, -2);
+ EXPECT_EQ("www.example", prefix.toText());
+ EXPECT_EQ("com.", suffix.toText());
+
+ sequence.split(prefix, suffix, -3);
+ EXPECT_EQ("www", prefix.toText());
+ EXPECT_EQ("example.com.", suffix.toText());
+}
+
+TEST_F(NameTest, LabelSequenceToWire) {
+ const uint8_t wiredata1[] = {
+ 17, // data length
+ 0x03, 0x77, 0x77, 0x77, // www
+ 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, // example
+ 0x03, 0x63, 0x6f, 0x6d, 0x00, // com.
+ 4, 0, 4, 12, 16 }; // offsetlen, offsets
+
+ LabelSequence sequence;
+ example_name.setLabelSequence(sequence);
+ sequence.toWire(buffer_actual);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer_actual.getData(),
+ buffer_actual.getLength(),
+ wiredata1, sizeof(wiredata1));
+
+ buffer_actual.clear();
+ const uint8_t wiredata2[] = {
+ 13, // data length
+ 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, // example
+ 0x03, 0x63, 0x6f, 0x6d, 0x00, // com.
+ 3, 0, 8, 12 }; // offsetlen, offsets
+ example_name.setLabelSequence(sequence);
+ sequence.split(1);
+ sequence.toWire(buffer_actual);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer_actual.getData(),
+ buffer_actual.getLength(),
+ wiredata2, sizeof(wiredata2));
+
+ buffer_actual.clear();
+ const uint8_t wiredata3[] = {
+ 12, // data length
+ 0x03, 0x77, 0x77, 0x77, // www
+ 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, // example
+ 2, 0, 4 }; // offsetlen, offsets
+ example_name.setLabelSequence(sequence);
+ sequence.split(-2);
+ sequence.toWire(buffer_actual);
+ EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, buffer_actual.getData(),
+ buffer_actual.getLength(),
+ wiredata3, sizeof(wiredata3));
+}
+}
More information about the bind10-changes
mailing list