[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