[svn] commit: r1111 - in /branches/each-nsec3/src: bin/auth/ lib/auth/cpp/ lib/dns/cpp/ lib/dns/cpp/rdata/generic/ lib/dns/cpp/tests/ lib/dns/cpp/tests/testdata/
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Mar 4 19:14:07 UTC 2010
Author: each
Date: Thu Mar 4 19:14:07 2010
New Revision: 1111
Log:
sync libdns, libauth, and b10-auth with recent changes in trunk
Modified:
branches/each-nsec3/src/bin/auth/auth_srv.cc
branches/each-nsec3/src/bin/auth/auth_srv.h
branches/each-nsec3/src/bin/auth/common.cc
branches/each-nsec3/src/bin/auth/common.h
branches/each-nsec3/src/bin/auth/main.cc
branches/each-nsec3/src/lib/auth/cpp/TODO
branches/each-nsec3/src/lib/auth/cpp/data_source.cc
branches/each-nsec3/src/lib/auth/cpp/data_source.h
branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.cc
branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.h
branches/each-nsec3/src/lib/auth/cpp/data_source_static.cc
branches/each-nsec3/src/lib/auth/cpp/data_source_static.h
branches/each-nsec3/src/lib/auth/cpp/datasrc_unittest.cc
branches/each-nsec3/src/lib/auth/cpp/query.cc
branches/each-nsec3/src/lib/auth/cpp/query.h
branches/each-nsec3/src/lib/auth/cpp/unittest_ds.cc
branches/each-nsec3/src/lib/auth/cpp/unittest_ds.h
branches/each-nsec3/src/lib/auth/cpp/unittest_util.h
branches/each-nsec3/src/lib/dns/cpp/Makefile.am
branches/each-nsec3/src/lib/dns/cpp/buffer.h
branches/each-nsec3/src/lib/dns/cpp/dnstime.cc
branches/each-nsec3/src/lib/dns/cpp/message.cc
branches/each-nsec3/src/lib/dns/cpp/message.h
branches/each-nsec3/src/lib/dns/cpp/messagerenderer.h
branches/each-nsec3/src/lib/dns/cpp/rdata.cc
branches/each-nsec3/src/lib/dns/cpp/rdata/generic/dnskey_48.cc
branches/each-nsec3/src/lib/dns/cpp/rdata/generic/ds_43.cc
branches/each-nsec3/src/lib/dns/cpp/rdata/generic/nsec_47.cc
branches/each-nsec3/src/lib/dns/cpp/rdata/generic/rrsig_46.cc
branches/each-nsec3/src/lib/dns/cpp/tests/Makefile.am
branches/each-nsec3/src/lib/dns/cpp/tests/buffer_unittest.cc
branches/each-nsec3/src/lib/dns/cpp/tests/message_unittest.cc
branches/each-nsec3/src/lib/dns/cpp/tests/rdata_nsec_unittest.cc
branches/each-nsec3/src/lib/dns/cpp/tests/rdata_rrsig_unittest.cc
branches/each-nsec3/src/lib/dns/cpp/tests/testdata/gen-wiredata.py.in
Modified: branches/each-nsec3/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/each-nsec3/src/bin/auth/auth_srv.cc (original)
+++ branches/each-nsec3/src/bin/auth/auth_srv.cc Thu Mar 4 19:14:07 2010
@@ -12,7 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// $Id$
+// $Id: auth_srv.cc 1110 2010-03-04 17:57:39Z jinmei $
#include <sys/types.h>
#include <sys/socket.h>
@@ -21,8 +21,6 @@
#include <netdb.h>
#include <stdlib.h>
-#include <algorithm>
-#include <set>
#include <iostream>
#include <dns/buffer.h>
@@ -34,13 +32,14 @@
#include <dns/message.h>
#include <config/ccsession.h>
+#include <auth/query.h>
+
#include <cc/data.h>
#include "common.h"
#include "auth_srv.h"
#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
using namespace std;
@@ -50,10 +49,13 @@
using namespace isc::data;
using namespace isc::config;
-AuthSrv::AuthSrv(int port) {
+AuthSrv::AuthSrv(int port) :
+ data_src(NULL), sock(-1)
+{
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (s < 0)
+ if (s < 0) {
throw FatalError("failed to open socket");
+ }
struct sockaddr_in sin;
sin.sin_family = AF_INET;
@@ -65,22 +67,39 @@
sin.sin_len = sa_len;
#endif
- if (bind(s, (struct sockaddr *)&sin, sa_len) < 0)
+ if (bind(s, (struct sockaddr *)&sin, sa_len) < 0) {
+ close(s);
throw FatalError("could not bind socket");
+ }
sock = s;
+ // XXX: the following code is not exception-safe. Will address in the
+ // next phase.
+
+ data_src = new(MetaDataSrc);
+
// add static data source
- data_src.addDataSrc(new StaticDataSrc);
+ data_src->addDataSrc(new StaticDataSrc);
// add SQL data source
Sqlite3DataSrc* sd = new Sqlite3DataSrc;
sd->init();
- data_src.addDataSrc(sd);
+ data_src->addDataSrc(sd);
+}
+
+AuthSrv::~AuthSrv()
+{
+ if (sock >= 0) {
+ close(sock);
+ }
+
+ delete data_src;
}
void
-AuthSrv::processMessage() {
+AuthSrv::processMessage()
+{
struct sockaddr_storage ss;
socklen_t sa_len = sizeof(ss);
struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
@@ -89,7 +108,7 @@
int cc;
if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) {
- Message msg;
+ Message msg(Message::PARSE);
InputBuffer buffer(recvbuf, cc);
try {
@@ -105,17 +124,19 @@
return;
}
- QuestionPtr query = *msg.beginQuestion();
+ bool dnssec_ok = msg.isDNSSECSupported();
+ uint16_t remote_bufsize = msg.getUDPSize();
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
+ msg.setDNSSECSupported(dnssec_ok);
+ msg.setUDPSize(sizeof(recvbuf));
- // do the DataSource call here
- Query q = Query(msg, false);
- data_src.doQuery(q);
+ Query query(msg, dnssec_ok);
+ data_src->doQuery(query);
- OutputBuffer obuffer(4096);
+ OutputBuffer obuffer(remote_bufsize);
MessageRenderer renderer(obuffer);
msg.toWire(renderer);
cout << "sending a response (" <<
@@ -133,7 +154,8 @@
}
ElementPtr
-AuthSrv::updateConfig(isc::data::ElementPtr new_config) {
+AuthSrv::updateConfig(isc::data::ElementPtr new_config)
+{
if (new_config) {
// the ModuleCCSession has already checked if we have
// the correct ElementPtr type as specified in our .spec file
Modified: branches/each-nsec3/src/bin/auth/auth_srv.h
==============================================================================
--- branches/each-nsec3/src/bin/auth/auth_srv.h (original)
+++ branches/each-nsec3/src/bin/auth/auth_srv.h Thu Mar 4 19:14:07 2010
@@ -12,10 +12,12 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// $Id$
+// $Id: auth_srv.h 1110 2010-03-04 17:57:39Z jinmei $
#ifndef __AUTH_SRV_H
#define __AUTH_SRV_H 1
+
+#include <string>
#include <cc/data.h>
#include <auth/data_source_static.h>
@@ -24,6 +26,7 @@
class AuthSrv {
public:
explicit AuthSrv(int port);
+ ~AuthSrv();
int getSocket() { return (sock); }
void processMessage();
void serve(std::string zone_name);
@@ -31,10 +34,13 @@
isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);
private:
std::string _db_file;
-
- isc::auth::MetaDataSrc data_src;
+
+ isc::auth::MetaDataSrc* data_src;
int sock;
};
#endif // __AUTH_SRV_H
+// Local Variables:
+// mode: c++
+// End:
Modified: branches/each-nsec3/src/bin/auth/common.cc
==============================================================================
--- branches/each-nsec3/src/bin/auth/common.cc (original)
+++ branches/each-nsec3/src/bin/auth/common.cc Thu Mar 4 19:14:07 2010
@@ -12,7 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// $Id$
+// $Id: common.cc 1072 2010-03-02 18:42:39Z jinmei $
#include "common.h"
#include <iostream>
Modified: branches/each-nsec3/src/bin/auth/common.h
==============================================================================
--- branches/each-nsec3/src/bin/auth/common.h (original)
+++ branches/each-nsec3/src/bin/auth/common.h Thu Mar 4 19:14:07 2010
@@ -12,7 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// $Id$
+// $Id: common.h 1072 2010-03-02 18:42:39Z jinmei $
#ifndef __COMMON_H
#define __COMMON_H 1
Modified: branches/each-nsec3/src/bin/auth/main.cc
==============================================================================
--- branches/each-nsec3/src/bin/auth/main.cc (original)
+++ branches/each-nsec3/src/bin/auth/main.cc Thu Mar 4 19:14:07 2010
@@ -12,7 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-// $Id$
+// $Id: main.cc 1072 2010-03-02 18:42:39Z jinmei $
#include <sys/types.h>
#include <sys/socket.h>
Modified: branches/each-nsec3/src/lib/auth/cpp/TODO
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/TODO (original)
+++ branches/each-nsec3/src/lib/auth/cpp/TODO Thu Mar 4 19:14:07 2010
@@ -1,3 +1,20 @@
- change filenames so we don't have everything starting with "data_source_"?
- clean up SQL data source code
- store rdata in the database as binary blobs instead of text
+
+NSEC3:
+- new nsec3 table in SQL schema:
+ id zone_id name (rname?) owner rowner rdata
+
+| add findCoveringNSEC3() API
+- add findCoveringNSEC3() routine, implementing:
+
+ select * from nsec3
+ where rowner <= name.reverse()
+ order by rowner desc
+ limit 1;
+
+- need to determine whether zone is signed nsec or nsec3 -- where?
+
+- add base32
+- add sha-1
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source.cc Thu Mar 4 19:14:07 2010
@@ -17,6 +17,8 @@
#include <iostream>
#include <vector>
+#include <boost/foreach.hpp>
+
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
@@ -27,6 +29,7 @@
#include <cc/data.h>
#include "data_source.h"
+#include "query.h"
using namespace std;
using namespace isc::dns;
@@ -71,9 +74,9 @@
// Synthesize a CNAME answer, for the benefit of clients that don't
// understand DNAME
static void
-synthesizeCname(Query& q, QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
- RdataIteratorPtr it;
- it = rrset->getRdataIterator();
+synthesizeCname(Query& q, QueryTaskPtr task, RRsetPtr rrset, RRsetList& target)
+{
+ RdataIteratorPtr it = rrset->getRdataIterator();
// More than one DNAME RR in the RRset is illegal, so we only have
// to process the first one.
@@ -102,9 +105,9 @@
// Add a task to the query task queue to look up the data pointed
// to by a CNAME record
static void
-chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
- RdataIteratorPtr it;
- it = rrset->getRdataIterator();
+chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
+{
+ RdataIteratorPtr it = rrset->getRdataIterator();
// More than one CNAME RR in the RRset is illegal, so we only have
// to process the first one.
@@ -113,20 +116,19 @@
return;
}
- const Rdata& rd(it->getCurrent());
- const generic::CNAME& cname = dynamic_cast<const generic::CNAME&>(rd);
- const Name& target(cname.getCname());
-
- QueryTaskPtr newtask = QueryTaskPtr(new QueryTask(target, task->qclass,
- task->qtype,
- Section::ANSWER(),
- QueryTask::FOLLOWCNAME));
- q.tasks().push(newtask);
+ q.tasks().push(QueryTaskPtr(
+ new QueryTask(dynamic_cast<const generic::CNAME&>
+ (it->getCurrent()).getCname(),
+ task->qclass,
+ task->qtype,
+ Section::ANSWER(),
+ QueryTask::FOLLOWCNAME)));
}
// Perform the query specified in a QueryTask object
DataSrc::Result
-doQueryTask(const DataSrc* ds, Query& q, QueryTask& task, RRsetList& target) {
+doQueryTask(const DataSrc* ds, Query& q, QueryTask& task, RRsetList& target)
+{
switch (task.op) {
case QueryTask::AUTH_QUERY:
return (ds->findRRset(q, task.qname, task.qclass, task.qtype,
@@ -152,13 +154,13 @@
// Copy referral information into the authority section of a message
static inline void
-copyAuth(Query& q, RRsetList& auth) {
- Message& m = q.message();
+copyAuth(Query& q, RRsetList& auth)
+{
BOOST_FOREACH(RRsetPtr rrset, auth) {
if (rrset->getType() == RRType::DNAME()) {
continue;
}
- m.addRRset(Section::AUTHORITY(), rrset, q.wantDnssec());
+ q.message().addRRset(Section::AUTHORITY(), rrset, q.wantDnssec());
getAdditional(q, rrset);
}
}
@@ -166,7 +168,8 @@
// Query for referrals (i.e., NS/DS or DNAME) at a given name
static inline bool
refQuery(const Name& name, Query& q, QueryTaskPtr task,
- const DataSrc* ds, RRsetList& target) {
+ const DataSrc* ds, RRsetList& target)
+{
QueryTask newtask(name, q.qclass(), QueryTask::REF_QUERY);
newtask.zone = task->zone;
@@ -188,14 +191,14 @@
// Match downward, from the zone apex to the query name, looking for
// referrals.
static inline bool
-hasDelegation(const DataSrc* ds, Query& q, QueryTaskPtr task) {
- Message& m = q.message();
+hasDelegation(const DataSrc* ds, Query& q, QueryTaskPtr task)
+{
int nlen = task->qname.getLabelCount();
int diff = nlen - task->zone->getLabelCount();
if (diff > 1) {
bool found = false;
RRsetList ref;
- for(int i = diff; i > 1; i--) {
+ for(int i = diff; i > 1; --i) {
Name sub(task->qname.split(i - 1, nlen - i));
if (refQuery(sub, q, task, ds, ref)) {
found = true;
@@ -214,13 +217,13 @@
if (found) {
if (RRsetPtr r = ref[RRType::DNAME()]) {
RRsetList syn;
- m.addRRset(Section::ANSWER(), r, q.wantDnssec());
- m.setHeaderFlag(MessageFlag::AA());
+ q.message().addRRset(Section::ANSWER(), r, q.wantDnssec());
+ q.message().setHeaderFlag(MessageFlag::AA());
synthesizeCname(q, task, r, syn);
if (syn.size() == 1) {
- m.addRRset(Section::ANSWER(),
- syn[RRType::CNAME()],
- q.wantDnssec());
+ q.message().addRRset(Section::ANSWER(),
+ syn[RRType::CNAME()],
+ q.wantDnssec());
chaseCname(q, task, syn[RRType::CNAME()]);
return (true);
}
@@ -236,7 +239,7 @@
// at the actual qname node.)
if (task->op == QueryTask::AUTH_QUERY &&
task->state == QueryTask::GETANSWER) {
- m.setHeaderFlag(MessageFlag::AA());
+ q.message().setHeaderFlag(MessageFlag::AA());
}
return (false);
@@ -244,7 +247,8 @@
// Attempt a wildcard lookup
static inline DataSrc::Result
-tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds, bool& found) {
+tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds, bool& found)
+{
Message& m = q.message();
DataSrc::Result result;
found = false;
@@ -265,7 +269,7 @@
Name star("*");
uint32_t rflags = 0;
- for(int i = 1; i <= diff; i++) {
+ for (int i = 1; i <= diff; ++i) {
const Name& wname(star.concatenate(task->qname.split(i, nlen - i)));
QueryTask newtask(wname, task->qclass, task->qtype,
QueryTask::SIMPLE_QUERY);
@@ -307,8 +311,8 @@
} else if (q.wantDnssec()) {
// No wildcard found; add an NSEC to prove it
RRsetList nsec;
- QueryTask newtask = QueryTask(*task->zone, task->qclass, RRType::NSEC(),
- QueryTask::SIMPLE_QUERY);
+ QueryTask newtask(*task->zone, task->qclass, RRType::NSEC(),
+ QueryTask::SIMPLE_QUERY);
newtask.zone = task->zone;
result = doQueryTask(ds, q, newtask, nsec);
if (result != DataSrc::SUCCESS) {
@@ -327,19 +331,13 @@
// doQuery: Processes a query.
//
void
-DataSrc::doQuery(Query q) {
- Result result;
+DataSrc::doQuery(Query& q)
+{
Message& m = q.message();
vector<RRsetPtr> additional;
- // XXX: this is for testing purposes; it should be done when
- // parsing the message for EDNS0 options
- q.setWantDnssec(true);
-
m.clearHeaderFlag(MessageFlag::AA());
while (!q.tasks().empty()) {
- RRsetList data;
-
QueryTaskPtr task = q.tasks().front();
q.tasks().pop();
@@ -353,19 +351,17 @@
// Find the closest enclosing zone for which we are authoritative,
// and the concrete data source which is authoritative for it.
// (Note that RRtype DS queries need to go to the parent.)
- Name search(".");
- if (task->qtype == RRType::DS()) {
- search = task->qname.split(1, task->qname.getLabelCount() - 1);
- } else {
- search = task->qname;
- }
-
- NameMatch match(search);
+ NameMatch match(task->qtype == RRType::DS() ?
+ task->qname.split(1, task->qname.getLabelCount() - 1) :
+ task->qname);
findClosestEnclosure(match);
- const DataSrc* ds = match.bestDataSrc();
+ const DataSrc* datasource = match.bestDataSrc();
const Name* zone = match.closestName();
- if (ds) {
+ RRsetList data;
+ Result result = SUCCESS;
+
+ if (datasource) {
task->zone = new Name(*zone);
// For these query task types, if there is more than
@@ -373,11 +369,11 @@
// check the intermediate nodes for referrals.
if ((task->op == QueryTask::AUTH_QUERY ||
task->op == QueryTask::NOGLUE_QUERY) &&
- hasDelegation(ds, q, task)) {
+ hasDelegation(datasource, q, task)) {
continue;
}
- result = doQueryTask(ds, q, *task, data);
+ result = doQueryTask(datasource, q, *task, data);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
@@ -386,7 +382,7 @@
// Query found a referral; let's find out if that was expected--
// i.e., if an NS was at the zone apex, or if we were querying
// specifically for the NS, DS or DNAME record.
- if ((task->flags & REFERRAL) &&
+ if ((task->flags & REFERRAL) != 0 &&
(zone->getLabelCount() == task->qname.getLabelCount() ||
task->qtype == RRType::NS() ||
task->qtype == RRType::DS() ||
@@ -418,7 +414,7 @@
// Add the NS records for the enclosing zone to
// the authority section.
RRsetList auth;
- if (! refQuery(Name(*zone), q, task, ds, auth)) {
+ if (! refQuery(Name(*zone), q, task, datasource, auth)) {
m.setRcode(Rcode::SERVFAIL());
return;
}
@@ -447,7 +443,7 @@
} else if (result == ERROR || result == NOT_IMPLEMENTED) {
m.setRcode(Rcode::SERVFAIL());
return;
- } else if (task->flags & CNAME_FOUND) {
+ } else if ((task->flags & CNAME_FOUND) != 0) {
// The qname node contains a CNAME. Add a new task to the
// queue to look up its target.
if (RRsetPtr rrset = data[RRType::CNAME()]) {
@@ -455,12 +451,12 @@
chaseCname(q, task, rrset);
}
continue;
- } else if (task->flags & REFERRAL) {
+ } else if ((task->flags & REFERRAL) != 0) {
// The qname node contains an out-of-zone referral.
if (task->state == QueryTask::GETANSWER) {
RRsetList auth;
m.clearHeaderFlag(MessageFlag::AA());
- if (! refQuery(task->qname, q, task, ds, auth)) {
+ if (! refQuery(task->qname, q, task, datasource, auth)) {
m.setRcode(Rcode::SERVFAIL());
return;
}
@@ -478,7 +474,7 @@
}
}
continue;
- } else if (task->flags & NO_SUCH_ZONE) {
+ } else if ((task->flags & NO_SUCH_ZONE) != 0) {
// No such zone. If we're chasing cnames or adding additional
// data, that's okay, but if doing an original query, return
// REFUSED.
@@ -487,13 +483,13 @@
return;
}
continue;
- } else if (task->flags & (NAME_NOT_FOUND|TYPE_NOT_FOUND)) {
+ } else if ((task->flags & (NAME_NOT_FOUND|TYPE_NOT_FOUND)) != 0) {
// No data found at this qname/qtype.
// If we were looking for answer data, not additional,
// and the name was not found, we need to find out whether
// there are any relevant wildcards.
bool wildcard_found = false;
- result = tryWildcard(q, task, ds, wildcard_found);
+ result = tryWildcard(q, task, datasource, wildcard_found);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
@@ -511,8 +507,9 @@
// section. For TYPE_NOT_FOUND, do not set an error rcode,
// and send the current NSEC in the authority section.
Name nsecname(task->qname);
- if (task->flags & NAME_NOT_FOUND) {
- ds->findPreviousName(q, task->qname, nsecname, task->zone);
+ if ((task->flags & NAME_NOT_FOUND) != 0) {
+ datasource->findPreviousName(q, task->qname, nsecname,
+ task->zone);
}
if (task->state == QueryTask::GETANSWER) {
@@ -524,7 +521,7 @@
QueryTask newtask(Name(*zone), task->qclass, RRType::SOA(),
QueryTask::SIMPLE_QUERY);
newtask.zone = task->zone;
- result = doQueryTask(ds, q, newtask, soa);
+ result = doQueryTask(datasource, q, newtask, soa);
if (result != SUCCESS || newtask.flags != 0) {
m.setRcode(Rcode::SERVFAIL());
return;
@@ -536,11 +533,10 @@
if (q.wantDnssec()) {
RRsetList nsec;
- QueryTask newtask = QueryTask(nsecname, task->qclass,
- RRType::NSEC(),
- QueryTask::SIMPLE_QUERY);
+ QueryTask newtask(nsecname, task->qclass,
+ RRType::NSEC(), QueryTask::SIMPLE_QUERY);
newtask.zone = task->zone;
- result = doQueryTask(ds, q, newtask, nsec);
+ result = doQueryTask(datasource, q, newtask, nsec);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
@@ -577,5 +573,118 @@
}
}
-}
-}
+DataSrc::Result
+DataSrc::findAddrs(const Query& q, const Name& qname, const RRClass& qclass,
+ RRsetList& target, uint32_t& flags, Name* zone) const
+{
+ Result r;
+ bool a = false, aaaa = false;
+
+ flags = 0;
+ r = findExactRRset(q, qname, qclass, RRType::A(), target, flags, zone);
+ if (r == SUCCESS && flags == 0) {
+ a = true;
+ }
+
+ flags = 0;
+ r = findExactRRset(q, qname, qclass, RRType::AAAA(), target, flags, zone);
+ if (r == SUCCESS && flags == 0) {
+ aaaa = true;
+ }
+
+ if (!a && !aaaa) {
+ flags = TYPE_NOT_FOUND;
+ } else {
+ flags = 0;
+ }
+
+ return (SUCCESS);
+}
+
+DataSrc::Result
+DataSrc::findReferral(const Query& q, const Name& qname, const RRClass& qclass,
+ RRsetList& target, uint32_t& flags, Name* zone) const
+{
+ Result r;
+ bool ns = false, ds = false, dname = false;
+
+ flags = 0;
+ r = findExactRRset(q, qname, qclass, RRType::NS(), target, flags, zone);
+ if (r == SUCCESS && flags == 0) {
+ ns = true;
+ } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
+ return (SUCCESS);
+ }
+
+ flags = 0;
+ r = findExactRRset(q, qname, qclass, RRType::DS(), target, flags, zone);
+ if (r == SUCCESS && flags == 0) {
+ ds = true;
+ } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
+ return (SUCCESS);
+ }
+
+ flags = 0;
+ r = findExactRRset(q, qname, qclass, RRType::DNAME(), target, flags, zone);
+ if (r == SUCCESS && flags == 0) {
+ dname = true;
+ } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
+ return (SUCCESS);
+ }
+
+ if (!ns && !dname && !ds) {
+ flags = TYPE_NOT_FOUND;
+ } else {
+ flags = 0;
+ }
+
+ return (SUCCESS);
+}
+
+void
+MetaDataSrc::addDataSrc(DataSrc* ds)
+{
+ if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) {
+ dns_throw(Unexpected, "class mismatch");
+ }
+
+ data_sources.push_back(ds);
+}
+
+void
+MetaDataSrc::findClosestEnclosure(NameMatch& match) const
+{
+ BOOST_FOREACH (DataSrc* ds, data_sources) {
+ if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) {
+ continue;
+ }
+
+ ds->findClosestEnclosure(match);
+ }
+}
+
+NameMatch::~NameMatch()
+{
+ delete closest_name_;
+}
+
+void
+NameMatch::update(const DataSrc& new_source, const Name& container)
+{
+ if (closest_name_ == NULL) {
+ closest_name_ = new Name(container);
+ best_source_ = &new_source;
+ return;
+ }
+
+ if (container.compare(*closest_name_).getRelation() ==
+ NameComparisonResult::SUBDOMAIN) {
+ Name* newname = new Name(container);
+ delete closest_name_;
+ closest_name_ = newname;
+ best_source_ = &new_source;
+ }
+}
+
+}
+}
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source.h Thu Mar 4 19:14:07 2010
@@ -17,23 +17,45 @@
#ifndef __DATA_SOURCE_H
#define __DATA_SOURCE_H
-#include <boost/foreach.hpp>
+#include <vector>
+
#include <dns/name.h>
-#include <dns/rrset.h>
-#include <dns/rrsetlist.h>
-#include <auth/query.h>
-#include <iostream>
-
-using namespace isc::dns;
+#include <dns/rrclass.h>
namespace isc {
+
+namespace dns {
+class Name;
+class RRType;
+class RRset;
+class RRsetList;
+}
+
namespace auth {
-class DataSrc;
class NameMatch;
+class Query;
class AbstractDataSrc {
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private to make it explicit that this is a pure base class.
+private:
+ AbstractDataSrc(const AbstractDataSrc& source);
+ AbstractDataSrc& operator=(const AbstractDataSrc& source);
+protected:
+ /// \brief The default constructor.
+ ///
+ /// This is intentionally defined as \c protected as this base class should
+ /// never be instantiated (except as part of a derived class).
+ AbstractDataSrc() {}
public:
+ /// \brief The destructor.
+ virtual ~AbstractDataSrc() {};
+ //@}
+
enum Result {
SUCCESS,
ERROR,
@@ -55,11 +77,9 @@
NO_SUCH_ZONE = 0x10
};
- virtual ~AbstractDataSrc() {};
-
// 'High-level' methods. These will be implemented by the
// general DataSrc class, and SHOULD NOT be overwritten by subclasses.
- virtual void doQuery(Query query) = 0;
+ virtual void doQuery(Query& query) = 0;
// XXX: High-level methods to be implemented later:
// virtual void doUpdate(Update update) = 0;
@@ -77,185 +97,131 @@
// Mandatory 'low-level' methods: These will NOT be implemented by
// the general DataSrc class; subclasses MUST implement them.
virtual Result findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
virtual Result findExactRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
// These will have dumb implementations in the general DataSrc
// class, and SHOULD be overwritten by subclasses.
virtual Result findAddrs(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
virtual Result findReferral(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
// This MUST be implemented by concrete data sources which support
// DNSSEC, but is optional for others (e.g., the static data source).
virtual Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const = 0;
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const = 0;
};
// Base class for a DNS Data Source
class DataSrc : public AbstractDataSrc {
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+private:
+ DataSrc(const DataSrc& source);
+ DataSrc& operator=(const DataSrc& source);
public:
- DataSrc() : rrclass(RRClass::IN()) {}
- DataSrc(const RRClass& c) : rrclass(c) {}
+ DataSrc() : rrclass(isc::dns::RRClass::IN()) {}
+ DataSrc(const isc::dns::RRClass& c) : rrclass(c) {}
+ /// \brief The destructor.
virtual ~DataSrc() {};
-
- void doQuery(Query q);
+ //@}
+
+ virtual void doQuery(Query& q);
virtual void findClosestEnclosure(NameMatch& match) const = 0;
- const RRClass& getClass() const { return rrclass; }
- void setClass(RRClass& c) { rrclass = c; }
- void setClass(const RRClass& c) { rrclass = c; }
+ const isc::dns::RRClass& getClass() const { return rrclass; }
+ void setClass(isc::dns::RRClass& c) { rrclass = c; }
+ void setClass(const isc::dns::RRClass& c) { rrclass = c; }
Result init() { return NOT_IMPLEMENTED; }
Result close() { return NOT_IMPLEMENTED; }
virtual Result findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
virtual Result findExactRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const = 0;
+ isc::dns::Name* zone = NULL) const = 0;
virtual Result findAddrs(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const {
- Result r;
- bool a = false, aaaa = false;
-
- flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::A(), target, flags, zone);
- if (r == SUCCESS && flags == 0) {
- a = true;
- }
-
- flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::AAAA(), target,
- flags, zone);
- if (r == SUCCESS && flags == 0) {
- aaaa = true;
- }
-
- if (!a && !aaaa) {
- flags = TYPE_NOT_FOUND;
- } else {
- flags = 0;
- }
-
- return (SUCCESS);
- }
+ isc::dns::Name* zone = NULL) const;
virtual Result findReferral(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const {
- Result r;
- bool ns = false, ds = false, dname = false;
-
- flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::NS(), target, flags, zone);
- if (r == SUCCESS && flags == 0) {
- ns = true;
- } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
- return (SUCCESS);
- }
-
- flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::DS(), target, flags, zone);
- if (r == SUCCESS && flags == 0) {
- ds = true;
- } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
- return (SUCCESS);
- }
-
- flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::DNAME(), target,
- flags, zone);
- if (r == SUCCESS && flags == 0) {
- dname = true;
- } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
- return (SUCCESS);
- }
-
- if (!ns && !dname && !ds) {
- flags = TYPE_NOT_FOUND;
- } else {
- flags = 0;
- }
-
- return (SUCCESS);
- }
+ isc::dns::Name* zone = NULL) const;
virtual Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const = 0;
-private:
- RRClass rrclass;
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const = 0;
+private:
+ isc::dns::RRClass rrclass;
};
class MetaDataSrc : public DataSrc {
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ //@{
+private:
+ MetaDataSrc(const MetaDataSrc& source);
+ MetaDataSrc& operator=(const MetaDataSrc& source);
public:
- MetaDataSrc() : DataSrc(RRClass::ANY()) {}
- MetaDataSrc(const RRClass& c) : DataSrc(c) {}
+ MetaDataSrc() : DataSrc(isc::dns::RRClass::ANY()) {}
+ MetaDataSrc(const isc::dns::RRClass& c) : DataSrc(c) {}
+ /// \brief The destructor.
virtual ~MetaDataSrc() {}
-
- void addDataSrc(DataSrc* ds) {
- if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) {
- dns_throw(Unexpected, "class mismatch");
- }
-
- data_sources.push_back(ds);
- }
-
- void findClosestEnclosure(NameMatch& match) const {
- BOOST_FOREACH (DataSrc* ds, data_sources) {
- if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) {
- continue;
- }
-
- ds->findClosestEnclosure(match);
- }
- }
+ //@}
+
+ void addDataSrc(DataSrc* ds);
+ void findClosestEnclosure(NameMatch& match) const;
// Actual queries for data should not be sent to a MetaDataSrc object,
// so we return NOT_IMPLEMENTED if we receive any.
@@ -264,38 +230,45 @@
// to get a pointer to the best concrete data source for the specified
// zone, then send all queries directly to that data source.
- Result findRRset(const Query& q, const Name& qname,
- const RRClass& qclass, const RRType& qtype,
- RRsetList& target, uint32_t& flags,
- Name* zone = NULL) const {
- return (NOT_IMPLEMENTED);
- }
-
- Result findExactRRset(const Query& q, const Name& qname,
- const RRClass& qclass, const RRType& qtype,
- RRsetList& target, uint32_t& flags,
- Name* zone = NULL) const {
- return (NOT_IMPLEMENTED);
- }
-
- Result findAddrs(const Query& q,
- const Name& qname, const RRClass& qclass,
- RRsetList& target, uint32_t& flags,
- Name* zone = NULL) const {
- return (NOT_IMPLEMENTED);
- }
-
- Result findReferral(const Query& q,
- const Name& qname, const RRClass& qclass,
- RRsetList& target, uint32_t& flags,
- Name* zone = NULL) const {
+ Result findRRset(const Query& q, const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target, uint32_t& flags,
+ isc::dns::Name* zone = NULL) const
+ {
+ return (NOT_IMPLEMENTED);
+ }
+
+ Result findExactRRset(const Query& q, const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target, uint32_t& flags,
+ isc::dns::Name* zone = NULL) const
+ {
+ return (NOT_IMPLEMENTED);
+ }
+
+ Result findAddrs(const Query& q, const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target, uint32_t& flags,
+ isc::dns::Name* zone = NULL) const
+ {
+ return (NOT_IMPLEMENTED);
+ }
+
+ Result findReferral(const Query& q, const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target, uint32_t& flags,
+ isc::dns::Name* zone = NULL) const
+ {
return (NOT_IMPLEMENTED);
}
virtual Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const {
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const
+ {
return (NOT_IMPLEMENTED);
}
@@ -305,39 +278,20 @@
class NameMatch {
public:
- NameMatch(const Name& qname) :
+ NameMatch(const isc::dns::Name& qname) :
closest_name_(NULL), best_source_(NULL), qname_(qname) {}
-
- ~NameMatch() {
- delete closest_name_;
- }
-
- void update(const DataSrc& new_source, const Name& container) {
- if (closest_name_ == NULL) {
- closest_name_ = new Name(container);
- best_source_ = &new_source;
- return;
- }
-
- NameComparisonResult::NameRelation cmp =
- container.compare(*closest_name_).getRelation();
-
- if (cmp == NameComparisonResult::SUBDOMAIN) {
- Name* newname = new Name(container);
- delete closest_name_;
- closest_name_ = newname;
- best_source_ = &new_source;
- }
- }
-
- const Name& qname() { return (qname_); }
- const Name* closestName() { return (closest_name_); }
+ ~NameMatch();
+
+ void update(const DataSrc& new_source, const isc::dns::Name& container);
+
+ const isc::dns::Name& qname() { return (qname_); }
+ const isc::dns::Name* closestName() { return (closest_name_); }
const DataSrc* bestDataSrc() { return (best_source_); }
private:
- const Name* closest_name_;
+ const isc::dns::Name* closest_name_;
const DataSrc* best_source_;
- const Name& qname_;
+ const isc::dns::Name qname_;
};
}
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.cc Thu Mar 4 19:14:07 2010
@@ -34,7 +34,8 @@
// Prepare a statement. Can call release() or sqlite3_finalize()
// directly.
//
-sqlite3_stmt* Sqlite3DataSrc::prepare(const char *statement) {
+sqlite3_stmt* Sqlite3DataSrc::prepare(const char *statement)
+{
int rc;
sqlite3_stmt *prepared = NULL;
@@ -55,7 +56,8 @@
//
// Get the database schema version.
//
-int Sqlite3DataSrc::getVersion(void) {
+int Sqlite3DataSrc::getVersion(void)
+{
if (database_version == -1) {
loadVersion();
}
@@ -66,7 +68,8 @@
// Find the exact zone match. Return -1 if not found, or the zone's
// ID if found. This will always be >= 0 if found.
//
-int Sqlite3DataSrc::hasExactZone(const char *name) const {
+int Sqlite3DataSrc::hasExactZone(const char* name) const
+{
int rc, i;
sqlite3_reset(q_zone);
rc = sqlite3_bind_text(q_zone, 1, name, -1, SQLITE_STATIC);
@@ -263,7 +266,8 @@
// >= 0 if found. If position is not NULL, it will be filled in with the
// longest match found.
//
-int Sqlite3DataSrc::findClosest(const char *name, const char **position) const {
+int Sqlite3DataSrc::findClosest(const char *name, const char **position) const
+{
int rc;
const char *current = name;
@@ -286,7 +290,9 @@
return (-1);
}
-void Sqlite3DataSrc::loadVersion(void) {
+void
+Sqlite3DataSrc::loadVersion(void)
+{
int rc;
const char *q = "SELECT version FROM schema_version";
@@ -299,49 +305,51 @@
release(prepared);
}
-void Sqlite3DataSrc::setupPreparedStatements(void) {
-
- const char *q_zone_str = "SELECT id FROM zones WHERE name=?1";
+void
+Sqlite3DataSrc::setupPreparedStatements(void)
+{
+
+ const char* q_zone_str = "SELECT id FROM zones WHERE name=?1";
try {
q_zone = prepare(q_zone_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_zone_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
}
- const char *q_record_str = "SELECT rdtype, ttl, sigtype, rdata "
+ const char* q_record_str = "SELECT rdtype, ttl, sigtype, rdata "
"FROM records WHERE zone_id=?1 AND name=?2 AND "
"((rdtype=?3 OR sigtype=?3) OR "
"(rdtype='CNAME' OR sigtype='CNAME') OR "
"(rdtype='NS' OR sigtype='NS'))";
try {
q_record = prepare(q_record_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_record_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
}
- const char *q_addrs_str = "SELECT rdtype, ttl, sigtype, rdata "
+ const char* q_addrs_str = "SELECT rdtype, ttl, sigtype, rdata "
"FROM records WHERE zone_id=?1 AND name=?2 AND "
"(rdtype='A' OR sigtype='A' OR "
"rdtype='AAAA' OR sigtype='AAAA')";
try {
q_addrs = prepare(q_addrs_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_addrs_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
}
- const char *q_referral_str = "SELECT rdtype, ttl, sigtype, rdata FROM "
+ const char* q_referral_str = "SELECT rdtype, ttl, sigtype, rdata FROM "
"records WHERE zone_id=?1 AND name=?2 AND"
"(rdtype='NS' OR sigtype='NS' OR "
"rdtype='DS' OR sigtype='DS' OR "
"rdtype='DNAME' OR sigtype='DNAME')";
try {
q_referral = prepare(q_referral_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_referral_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
@@ -350,29 +358,29 @@
"FROM records WHERE zone_id=?1 AND name=?2";
try {
q_any = prepare(q_any_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_any_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
}
- const char *q_count_str = "SELECT COUNT(*) FROM records "
+ const char* q_count_str = "SELECT COUNT(*) FROM records "
"WHERE zone_id=?1 AND (name=?2 OR "
"name LIKE '%.' || ?2);";
try {
q_count = prepare(q_count_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_count_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
}
- const char *q_previous_str = "SELECT name FROM records "
+ const char* q_previous_str = "SELECT name FROM records "
"WHERE zone_id=?1 AND rdtype = 'NSEC' AND "
"rname < $2 ORDER BY rname DESC LIMIT 1";
try {
q_previous = prepare(q_previous_str);
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl << q_previous_str << endl;
cout << sqlite3_errmsg(db) << endl;
throw(e);
@@ -380,7 +388,9 @@
}
-void Sqlite3DataSrc::execSetupQuery(const char *query) {
+void
+Sqlite3DataSrc::execSetupQuery(const char *query)
+{
int rc;
rc = sqlite3_exec(db, query, NULL, NULL, NULL);
@@ -389,7 +399,9 @@
}
}
-void Sqlite3DataSrc::checkAndSetupSchema(void) {
+void
+Sqlite3DataSrc::checkAndSetupSchema(void)
+{
try {
loadVersion();
setupPreparedStatements();
@@ -446,7 +458,7 @@
open("/tmp/zone.sqlite3");
cout << "Schema version: " << getVersion() << endl;
- } catch (const char *e) {
+ } catch (const char* e) {
cout << e << endl;
}
@@ -454,7 +466,8 @@
}
void
-Sqlite3DataSrc::findClosestEnclosure(NameMatch& match) const {
+Sqlite3DataSrc::findClosestEnclosure(NameMatch& match) const
+{
const Name& qname = match.qname();
const string target_string = qname.toText();
const char *position = NULL;
@@ -473,14 +486,14 @@
Name& target,
Name* zone) const
{
- const char *c_rname = qname.reverse().toText().c_str();
+ const char* c_rname = qname.reverse().toText().c_str();
int zone_id;
if (zone == NULL) {
- const char *c_name = qname.toText().c_str();
+ const char* c_name = qname.toText().c_str();
zone_id = findClosest(c_name, NULL);
} else {
- const char *c_zone = zone->toText().c_str();
+ const char* c_zone = zone->toText().c_str();
zone_id = findClosest(c_zone, NULL);
}
@@ -554,18 +567,20 @@
const RRClass& qclass,
RRsetList& target,
uint32_t& flags,
- Name* zone) const {
+ Name* zone) const
+{
findRecords(qname, RRType::ANY(), target, zone, ADDRESS, flags);
return (SUCCESS);
}
DataSrc::Result
Sqlite3DataSrc::findReferral(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
- uint32_t& flags,
- Name* zone) const {
+ const Name& qname,
+ const RRClass& qclass,
+ RRsetList& target,
+ uint32_t& flags,
+ Name* zone) const
+{
findRecords(qname, RRType::ANY(), target, zone, DELEGATION, flags);
return (SUCCESS);
}
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source_sqlite3.h Thu Mar 4 19:14:07 2010
@@ -14,59 +14,79 @@
// $Id$
-#ifndef __SQLITE3_DATA_SOURCE_H
-#define __SQLITE3_DATA_SOURCE_H
+#ifndef __DATA_SOURCE_SQLITE3_H
+#define __DATA_SOURCE_SQLITE3_H
+
+#include <string>
#include <sqlite3.h>
#include "data_source.h"
-using namespace isc::dns;
+namespace isc {
-namespace isc {
+namespace dns {
+class Name;
+class RRClass;
+class RRType;
+class RRsetList;
+}
+
namespace auth {
+class Query;
+
class Sqlite3DataSrc : public DataSrc {
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ //@{
+private:
+ Sqlite3DataSrc(const Sqlite3DataSrc& source);
+ Sqlite3DataSrc& operator=(const Sqlite3DataSrc& source);
public:
Sqlite3DataSrc();
virtual ~Sqlite3DataSrc();
+ //@}
virtual void findClosestEnclosure(NameMatch& match) const;
virtual Result findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
virtual Result findExactRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
virtual Result findAddrs(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
virtual Result findReferral(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
virtual DataSrc::Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const;
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const;
virtual Result init();
virtual Result close();
@@ -83,8 +103,8 @@
void release(sqlite3_stmt* prepared);
int getVersion(void);
int hasExactZone(const char *name) const;
- int findRecords(const Name& name, const RRType& rdtype,
- RRsetList& target, Name* zone,
+ int findRecords(const isc::dns::Name& name, const isc::dns::RRType& rdtype,
+ isc::dns::RRsetList& target, isc::dns::Name* zone,
const Mode mode, uint32_t& flags) const;
int findClosest(const char *name, const char **position) const;
void loadVersion(void);
@@ -111,7 +131,7 @@
}
}
-#endif // __SQLITE3_DATA_SOURCE_H
+#endif // __DATA_SOURCE_SQLITE3_H
// Local Variables:
// mode: c++
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source_static.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source_static.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source_static.cc Thu Mar 4 19:14:07 2010
@@ -14,17 +14,16 @@
// $Id$
-#include "data_source_static.h"
-
#include <dns/name.h>
-#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
+#include <dns/rrsetlist.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
-#include <iostream>
+#include "data_source.h"
+#include "data_source_static.h"
using namespace std;
using namespace isc::dns;
@@ -33,36 +32,62 @@
namespace isc {
namespace auth {
-StaticDataSrc::StaticDataSrc() : authors_name("authors.bind"),
- version_name("version.bind")
+// There's no mutable internal state in StaticDataSrcImpl, so define it
+// as a struct.
+
+namespace {
+
+// All data in this class is literally static and can be generated at
+// initialization time (and won't be changed). Names can be statically
+// initialized. For RRsets, a helper class (StaticDataInitializer) and its
+// only instance will be used for initialization.
+const Name authors_name("authors.bind");
+const Name version_name("version.bind");
+// XXX: unfortunately these can't be RRsetPtr because they'll be passed to
+// RRsetList::addRRset(), which expect non const RRsetPtr. We should revisit
+// this design later.
+RRsetPtr authors;
+RRsetPtr authors_ns;
+RRsetPtr version;
+RRsetPtr version_ns;
+
+class StaticDataInitializer {
+public:
+ StaticDataInitializer()
+ {
+ authors = RRsetPtr(new RRset(authors_name, RRClass::CH(),
+ RRType::TXT(), RRTTL(0)));
+ authors->addRdata(generic::TXT("Evan Hunt"));
+ authors->addRdata(generic::TXT("Han Feng"));
+ authors->addRdata(generic::TXT("Jelte Jansen"));
+ authors->addRdata(generic::TXT("Jeremy C. Reed"));
+ authors->addRdata(generic::TXT("Jin Jian"));
+ authors->addRdata(generic::TXT("JINMEI Tatuya"));
+ authors->addRdata(generic::TXT("Kazunori Fujiwara"));
+ authors->addRdata(generic::TXT("Michael Graff"));
+ authors->addRdata(generic::TXT("Naoki Kambe"));
+ authors->addRdata(generic::TXT("Shane Kerr"));
+ authors->addRdata(generic::TXT("Zhang Likun"));
+
+ authors_ns = RRsetPtr(new RRset(authors_name, RRClass::CH(),
+ RRType::NS(), RRTTL(0)));
+ authors_ns->addRdata(generic::NS(authors_name));
+
+ version = RRsetPtr(new RRset(version_name, RRClass::CH(),
+ RRType::TXT(), RRTTL(0)));
+ version->addRdata(generic::TXT("BIND10 0.0.0 (pre-alpha)"));
+
+ version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
+ RRType::NS(), RRTTL(0)));
+ version_ns->addRdata(generic::NS(version_name));
+ }
+};
+const StaticDataInitializer initialier_object;
+}
+
+StaticDataSrc::StaticDataSrc()
{
setClass(RRClass::CH());
-
- authors = RRsetPtr(new RRset(authors_name, RRClass::CH(),
- RRType::TXT(), RRTTL(0)));
- authors->addRdata(generic::TXT("Evan Hunt"));
- authors->addRdata(generic::TXT("Han Feng"));
- authors->addRdata(generic::TXT("Jelte Jansen"));
- authors->addRdata(generic::TXT("Jeremy C. Reed"));
- authors->addRdata(generic::TXT("Jin Jian"));
- authors->addRdata(generic::TXT("JINMEI Tatuya"));
- authors->addRdata(generic::TXT("Kazunori Fujiwara"));
- authors->addRdata(generic::TXT("Michael Graff"));
- authors->addRdata(generic::TXT("Naoki Kambe"));
- authors->addRdata(generic::TXT("Shane Kerr"));
- authors->addRdata(generic::TXT("Zhang Likun"));
-
- authors_ns = RRsetPtr(new RRset(authors_name, RRClass::CH(),
- RRType::NS(), RRTTL(0)));
- authors_ns->addRdata(generic::NS(authors_name));
-
- version = RRsetPtr(new RRset(version_name, RRClass::CH(),
- RRType::TXT(), RRTTL(0)));
- version->addRdata(generic::TXT("BIND10 0.0.0 (pre-alpha)"));
-
- version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
- RRType::NS(), RRTTL(0)));
- version_ns->addRdata(generic::NS(version_name));
}
void
@@ -86,13 +111,9 @@
}
DataSrc::Result
-StaticDataSrc::findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
- uint32_t& flags,
- Name* zone) const
+StaticDataSrc::findRRset(const Query& q, const Name& qname,
+ const RRClass& qclass, const RRType& qtype,
+ RRsetList& target, uint32_t& flags, Name* zone) const
{
flags = 0;
if (qclass != getClass()) {
@@ -126,5 +147,33 @@
return (SUCCESS);
}
+DataSrc::Result
+StaticDataSrc::findExactRRset(const Query& q, const Name& qname,
+ const RRClass& qclass, const RRType& qtype,
+ RRsetList& target, uint32_t& flags,
+ Name* zone) const
+{
+ return (findRRset(q, qname, qclass, qtype, target, flags, zone));
+}
+
+DataSrc::Result
+StaticDataSrc::findPreviousName(const Query& q, const Name& qname,
+ Name& target, Name* zone) const
+{
+ return (NOT_IMPLEMENTED);
+}
+
+DataSrc::Result
+StaticDataSrc::init()
+{
+ return (SUCCESS);
+}
+
+DataSrc::Result
+StaticDataSrc::close()
+{
+ return (SUCCESS);
+}
+
}
}
Modified: branches/each-nsec3/src/lib/auth/cpp/data_source_static.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/data_source_static.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/data_source_static.h Thu Mar 4 19:14:07 2010
@@ -27,54 +27,61 @@
#include "data_source.h"
-using namespace isc::dns;
+namespace isc {
-namespace isc {
+namespace dns {
+class Name;
+class RRClass;
+class RRType;
+class RRType;
+class RRsetList;
+}
+
namespace auth {
+class Query;
+class NameMatch;
+
class StaticDataSrc : public DataSrc {
+private:
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ //@{
+ StaticDataSrc(const StaticDataSrc& source);
+ StaticDataSrc& operator=(const StaticDataSrc& source);
public:
StaticDataSrc();
~StaticDataSrc() {}
+ //@}
void findClosestEnclosure(NameMatch& match) const;
Result findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
Result findExactRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
- uint32_t& flags,
- Name* zone = NULL) const
- {
- return (findRRset(q, qname, qclass, qtype, target, flags, zone));
- }
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
+ uint32_t& flags,
+ isc::dns::Name* zone = NULL) const;
Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const {
- return (NOT_IMPLEMENTED);
- }
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const;
- Result init() { return (SUCCESS); }
- Result close() { return (SUCCESS); }
-
-private:
- const Name authors_name;
- const Name version_name;
- RRsetPtr authors;
- RRsetPtr authors_ns;
- RRsetPtr version;
- RRsetPtr version_ns;
+ Result init();
+ Result close();
};
}
Modified: branches/each-nsec3/src/lib/auth/cpp/datasrc_unittest.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/datasrc_unittest.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/datasrc_unittest.cc Thu Mar 4 19:14:07 2010
@@ -31,6 +31,7 @@
#include <dns/rrttl.h>
#include <dns/rrtype.h>
+#include "query.h"
#include "unittest_util.h"
#include "unittest_ds.h"
@@ -42,7 +43,8 @@
namespace {
class DataSrcTest : public ::testing::Test {
protected:
- DataSrcTest() : obuffer(0), renderer(obuffer) {}
+ DataSrcTest() : obuffer(0), renderer(obuffer), msg(Message::PARSE)
+ {}
TestDataSrc ds;
OutputBuffer obuffer;
MessageRenderer renderer;
@@ -65,7 +67,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -126,7 +128,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -161,7 +163,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -185,7 +187,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -211,7 +213,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -227,7 +229,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -286,7 +288,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -345,7 +347,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -406,7 +408,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -437,7 +439,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -476,7 +478,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -513,7 +515,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
@@ -556,7 +558,7 @@
msg.makeResponse();
msg.setHeaderFlag(MessageFlag::AA());
msg.setRcode(Rcode::NOERROR());
- Query q = Query(msg, false);
+ Query q(msg, true);
ds.doQuery(q);
Message* m = &(q.message());
Modified: branches/each-nsec3/src/lib/auth/cpp/query.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/query.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/query.cc Thu Mar 4 19:14:07 2010
@@ -23,12 +23,94 @@
#include "query.h"
+using namespace isc::dns;
+
namespace isc {
namespace auth {
// Destructors defined here to avoid confusing the linker
+Query::~Query() {}
QueryTask::~QueryTask() {}
-Query::~Query() {}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect) :
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(sect), op(AUTH_QUERY), state(GETANSWER), flags(0)
+{}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const Op o) :
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(sect), op(o), state(GETANSWER), flags(0)
+{}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const State st) :
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(sect), op(AUTH_QUERY), state(st), flags(0)
+{}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const Op o, const State st) :
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(sect), op(o), state(st), flags(0)
+{}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const Op o) :
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(Section::ANSWER()),
+ op(o), state(GETANSWER), flags(0)
+{
+ if (op != SIMPLE_QUERY) {
+ dns_throw(Unexpected, "invalid constructor for this task operation");
+ }
+}
+
+// A referral query doesn't need to specify section, state, or type.
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const Op o) :
+ qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
+ section(Section::ANSWER()), op(o), state(GETANSWER),
+ flags(0)
+{
+ if (op != REF_QUERY) {
+ dns_throw(Unexpected, "invalid constructor for this task operation");
+ }
+}
+
+QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::Section& sect, const Op o,
+ const State st) :
+ qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
+ section(sect), op(o), state(st), flags(0)
+{
+ if (op != GLUE_QUERY && op != NOGLUE_QUERY) {
+ dns_throw(Unexpected, "invalid constructor for this task operation");
+ }
+}
+
+Query::Query(Message& m, bool dnssec) :
+ status_(PENDING), qname_(NULL), qclass_(NULL), qtype_(NULL),
+ message_(&m), want_additional_(true), want_dnssec_(dnssec)
+{
+ // Check message formatting
+ if (message_->getRRCount(Section::QUESTION()) != 1) {
+ dns_throw(Unexpected, "malformed message: too many questions");
+ }
+
+ // Populate the query task queue with the initial question
+ QuestionPtr question = *message_->beginQuestion();
+ qname_ = &question->getName();
+ qclass_ = &question->getClass();
+ qtype_ = &question->getType();
+
+ querytasks_.push(QueryTaskPtr(new QueryTask(*qname_, *qclass_, *qtype_,
+ Section::ANSWER())));
+}
}
}
Modified: branches/each-nsec3/src/lib/auth/cpp/query.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/query.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/query.h Thu Mar 4 19:14:07 2010
@@ -19,40 +19,45 @@
#include <queue>
-#include <exceptions/exceptions.h>
-#include <dns/name.h>
-#include <dns/message.h>
-#include <dns/rrset.h>
-#include <dns/rrclass.h>
-#include <dns/rrtype.h>
-
-using namespace isc::dns;
-
namespace isc {
+
+namespace dns {
+class Name;
+class Message;
+class Section;
+class RRClass;
+class RRType;
+}
+
namespace auth {
// An individual task to be carried out by the query logic
class QueryTask {
+private:
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ QueryTask(const QueryTask& source);
+ QueryTask& operator=(const QueryTask& source);
public:
// XXX: Members are currently public, but should probably be
// moved to private and wrapped in get() functions later.
// The standard query tuple: qname/qclass/qtype.
// Note that qtype is ignored in the GLUE_QUERY/NOGLUE_QUERY case.
- const Name& qname;
- const RRClass& qclass;
- const RRType& qtype;
+ const isc::dns::Name& qname;
+ const isc::dns::RRClass& qclass;
+ const isc::dns::RRType& qtype;
// Optional: name for the containing zone, if known.
// This is particularly needed when looking up data in a
// zone other than the closest enclosure (such as getting
// DS queries from a parent zone on a server which serves
// both parent and child).
- Name* zone;
+ isc::dns::Name* zone;
// The section of the reply into which the data should be
// written after it has been fetched from the data source.
- const Section& section;
+ const isc::dns::Section& section;
// The op field indicates the operation to be carried out by
// this query task:
@@ -121,54 +126,31 @@
uint32_t flags;
// Constructors
- QueryTask(const Name& n, const RRClass& c,
- const RRType& t, const Section& sect) :
- qname(n), qclass(c), qtype(t), zone(NULL),
- section(sect), op(AUTH_QUERY), state(GETANSWER), flags(0) {}
- QueryTask(const Name& n, const RRClass& c,
- const RRType& t, const Section& sect, const Op o) :
- qname(n), qclass(c), qtype(t), zone(NULL),
- section(sect), op(o), state(GETANSWER), flags(0) {}
- QueryTask(const Name& n, const RRClass& c,
- const RRType& t, const Section& sect, const State st) :
- qname(n), qclass(c), qtype(t), zone(NULL),
- section(sect), op(AUTH_QUERY), state(st), flags(0) {}
- QueryTask(const Name& n, const RRClass& c,
- const RRType& t, const Section& sect,
- const Op o, const State st) :
- qname(n), qclass(c), qtype(t), zone(NULL),
- section(sect), op(o), state(st), flags(0) {}
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect);
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ Op o);
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ const State st);
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, const isc::dns::Section& sect,
+ Op o, State st);
// These are special constructors for particular query task types,
// to simplify the code.
//
// A simple query doesn't need to specify section or state.
- QueryTask(const Name& n, const RRClass& c, const RRType& t, const Op o) :
- qname(n), qclass(c), qtype(t), zone(NULL),
- section(Section::ANSWER()), op(o), state(GETANSWER), flags(0) {
- if (op != SIMPLE_QUERY) {
- throw "invalid constructor for this task operation";
- }
- }
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::RRType& t, Op o);
// A referral query doesn't need to specify section, state, or type.
- QueryTask(const Name& n, const RRClass& c, const Op o) :
- qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
- section(Section::ANSWER()), op(o), state(GETANSWER), flags(0) {
- if (op != REF_QUERY) {
- throw "invalid constructor for this task operation";
- }
- }
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c, Op o);
// A glue (or noglue) query doesn't need to specify type.
- QueryTask(const Name& n, const RRClass& c,
- const Section& sect, const Op o, const State st) :
- qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
- section(sect), op(o), state(st), flags(0) {
- if (op != GLUE_QUERY && op != NOGLUE_QUERY) {
- throw "invalid constructor for this task operation";
- }
- }
-
- virtual ~QueryTask();
+ QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
+ const isc::dns::Section& sect, Op o, State st);
+
+ ~QueryTask();
};
typedef boost::shared_ptr<QueryTask> QueryTaskPtr;
@@ -186,64 +168,61 @@
ANSWERED
};
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ //@{
+private:
+ Query(const Query& source);
+ Query& operator=(const Query& source);
+public:
// Query constructor
- Query(Message& m, bool dnssec) {
- message_ = &m;
- want_additional = true;
- want_dnssec = dnssec;
- status_ = PENDING;
-
- // Check message formatting
- if (message_->getRRCount(Section::QUESTION()) != 1) {
- dns_throw(Unexpected, "malformed message: too many questions");
- }
-
- // Populate the query task queue with the initial question
- QuestionPtr query = *message_->beginQuestion();
- qname_ = &query->getName();
- qclass_ = &query->getClass();
- qtype_ = &query->getType();
-
- QueryTaskPtr initial_task(new QueryTask(*qname_, *qclass_, *qtype_,
- Section::ANSWER()));
- querytasks.push(initial_task);
- };
-
+ Query(isc::dns::Message& m, bool dnssec);
+ /// \brief The destructor.
virtual ~Query();
+ //@}
// wantAdditional() == true indicates that additional-section data
// should be looked up while processing this query. false indicates
// that we're only interested in answer-section data
- bool wantAdditional() { return want_additional; }
- void setWantAdditional(bool d) { want_additional = d; }
+ bool wantAdditional() { return want_additional_; }
+ void setWantAdditional(bool d) { want_additional_ = d; }
// wantDnssec() == true indicates that DNSSEC data should be retrieved
// from the data source when this query is being processed
- bool wantDnssec() { return want_dnssec; }
- void setWantDnssec(bool d) { want_dnssec = d; }
-
- const Name& qname() { return *qname_; }
- const RRClass& qclass() { return *qclass_; }
- const RRType& qtype() { return *qtype_; }
-
- Message& message() { return *message_; }
- QueryTaskQueue& tasks() { return querytasks; }
-
- Status status() { return status_; }
+ bool wantDnssec() const { return want_dnssec_; }
+ void setWantDnssec(bool d) { want_dnssec_ = d; }
+
+ const isc::dns::Name& qname() const { return *qname_; }
+ const isc::dns::RRClass& qclass() const { return *qclass_; }
+ const isc::dns::RRType& qtype() const { return *qtype_; }
+
+ // Note: these can't be constant member functions because they expose
+ // writable 'handles' of internal member variables. It's questionable
+ // whether we need these accessors in the first place because the
+ // corresponding members are public (which itself is not a good practice
+ // but it's a different topic), but at the moment we keep them.
+ // We should definitely revisit the design later.
+ isc::dns::Message& message() { return *message_; }
+ QueryTaskQueue& tasks() { return querytasks_; }
+
+ Status status() const { return status_; }
void setStatus(Status s) { status_ = s; }
private:
Status status_;
- const Name* qname_;
- const RRClass* qclass_;
- const RRType* qtype_;
-
- Message* message_;
- QueryTaskQueue querytasks;
-
- bool want_additional;
- bool want_dnssec;
+ const isc::dns::Name* qname_;
+ const isc::dns::RRClass* qclass_;
+ const isc::dns::RRType* qtype_;
+
+ isc::dns::Message* message_;
+ QueryTaskQueue querytasks_;
+
+ bool want_additional_;
+ bool want_dnssec_;
};
}
Modified: branches/each-nsec3/src/lib/auth/cpp/unittest_ds.cc
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/unittest_ds.cc (original)
+++ branches/each-nsec3/src/lib/auth/cpp/unittest_ds.cc Thu Mar 4 19:14:07 2010
@@ -25,6 +25,7 @@
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrset.h>
+#include <dns/rrsetlist.h>
#include <dns/rrtype.h>
#include <dns/rrttl.h>
Modified: branches/each-nsec3/src/lib/auth/cpp/unittest_ds.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/unittest_ds.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/unittest_ds.h Thu Mar 4 19:14:07 2010
@@ -17,57 +17,75 @@
#ifndef __TEST_DATA_SOURCE_H
#define __TEST_DATA_SOURCE_H
+#include <dns/name.h>
+#include <dns/rrset.h>
+
#include <gtest/gtest.h>
-#include "unittest_util.h"
-
-using isc::UnitTestUtil;
-using namespace isc::dns;
#include "data_source.h"
namespace isc {
+
+namespace dns {
+class RRClass;
+class RRType;
+class RRsetList;
+}
+
namespace auth {
+class Query;
+
class TestDataSrc : public DataSrc {
+ ///
+ /// \name Constructors, Assignment Operator and Destructor.
+ ///
+ /// Note: The copy constructor and the assignment operator are intentionally
+ /// defined as private.
+ //@{
+private:
+ TestDataSrc(const TestDataSrc& source);
+ TestDataSrc operator=(const TestDataSrc& source);
public:
TestDataSrc();
~TestDataSrc() {}
+ //@}
void findClosestEnclosure(NameMatch& match) const;
Result findRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
Result findExactRRset(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- const RRType& qtype,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ const isc::dns::RRType& qtype,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
Result findAddrs(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
Result findReferral(const Query& q,
- const Name& qname,
- const RRClass& qclass,
- RRsetList& target,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
uint32_t& flags,
- Name* zone = NULL) const;
+ isc::dns::Name* zone = NULL) const;
Result findPreviousName(const Query& q,
- const Name& qname,
- Name& target,
- Name* zone) const;
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ isc::dns::Name* zone) const;
Result init() { return (SUCCESS); }
Result close() { return (SUCCESS); }
@@ -79,56 +97,56 @@
DELEGATION
};
- void findRecords(const Name& name, const RRType& rdtype,
- RRsetList& target, Name* zone, const Mode mode,
- uint32_t& flags) const;
+ void findRecords(const isc::dns::Name& name, const isc::dns::RRType& rdtype,
+ isc::dns::RRsetList& target, isc::dns::Name* zone,
+ const Mode mode, uint32_t& flags) const;
- const Name example;
- const Name sql1;
- const Name www_sql1;
- const Name www;
- const Name foo;
- const Name dns01;
- const Name dns02;
- const Name dns03;
- const Name cnameint;
- const Name cnameext;
- const Name dname;
- const Name wild;
- const Name subzone;
- RRsetPtr example_ns;
- RRsetPtr example_soa;
- RRsetPtr example_nsec;
- RRsetPtr www_a;
- RRsetPtr www_nsec;
- RRsetPtr foo_cname;
- RRsetPtr foo_nsec;
- RRsetPtr cnameint_cname;
- RRsetPtr cnameint_nsec;
- RRsetPtr cnameext_cname;
- RRsetPtr cnameext_nsec;
- RRsetPtr dns01_a;
- RRsetPtr dns01_nsec;
- RRsetPtr dns02_a;
- RRsetPtr dns02_nsec;
- RRsetPtr dns03_a;
- RRsetPtr dns03_nsec;
- RRsetPtr wild_a;
- RRsetPtr wild_nsec;
- RRsetPtr dname_dname;
- RRsetPtr dname_nsec;
- RRsetPtr sql1_ns;
- RRsetPtr sql1_soa;
- RRsetPtr sql1_nsec;
- RRsetPtr sql1_ds;
- RRsetPtr sql1_ds_nsec;
- RRsetPtr www_sql1_a;
- RRsetPtr www_sql1_nsec;
- RRsetPtr subzone_ns;
- RRsetPtr subzone_nsec;
- RRsetPtr subzone_glue1;
- RRsetPtr subzone_glue2;
- RRsetPtr subzone_ds;
+ const isc::dns::Name example;
+ const isc::dns::Name sql1;
+ const isc::dns::Name www_sql1;
+ const isc::dns::Name www;
+ const isc::dns::Name foo;
+ const isc::dns::Name dns01;
+ const isc::dns::Name dns02;
+ const isc::dns::Name dns03;
+ const isc::dns::Name cnameint;
+ const isc::dns::Name cnameext;
+ const isc::dns::Name dname;
+ const isc::dns::Name wild;
+ const isc::dns::Name subzone;
+ isc::dns::RRsetPtr example_ns;
+ isc::dns::RRsetPtr example_soa;
+ isc::dns::RRsetPtr example_nsec;
+ isc::dns::RRsetPtr www_a;
+ isc::dns::RRsetPtr www_nsec;
+ isc::dns::RRsetPtr foo_cname;
+ isc::dns::RRsetPtr foo_nsec;
+ isc::dns::RRsetPtr cnameint_cname;
+ isc::dns::RRsetPtr cnameint_nsec;
+ isc::dns::RRsetPtr cnameext_cname;
+ isc::dns::RRsetPtr cnameext_nsec;
+ isc::dns::RRsetPtr dns01_a;
+ isc::dns::RRsetPtr dns01_nsec;
+ isc::dns::RRsetPtr dns02_a;
+ isc::dns::RRsetPtr dns02_nsec;
+ isc::dns::RRsetPtr dns03_a;
+ isc::dns::RRsetPtr dns03_nsec;
+ isc::dns::RRsetPtr wild_a;
+ isc::dns::RRsetPtr wild_nsec;
+ isc::dns::RRsetPtr dname_dname;
+ isc::dns::RRsetPtr dname_nsec;
+ isc::dns::RRsetPtr sql1_ns;
+ isc::dns::RRsetPtr sql1_soa;
+ isc::dns::RRsetPtr sql1_nsec;
+ isc::dns::RRsetPtr sql1_ds;
+ isc::dns::RRsetPtr sql1_ds_nsec;
+ isc::dns::RRsetPtr www_sql1_a;
+ isc::dns::RRsetPtr www_sql1_nsec;
+ isc::dns::RRsetPtr subzone_ns;
+ isc::dns::RRsetPtr subzone_nsec;
+ isc::dns::RRsetPtr subzone_glue1;
+ isc::dns::RRsetPtr subzone_glue2;
+ isc::dns::RRsetPtr subzone_ds;
};
}
Modified: branches/each-nsec3/src/lib/auth/cpp/unittest_util.h
==============================================================================
--- branches/each-nsec3/src/lib/auth/cpp/unittest_util.h (original)
+++ branches/each-nsec3/src/lib/auth/cpp/unittest_util.h Thu Mar 4 19:14:07 2010
@@ -23,9 +23,6 @@
#include <dns/name.h>
#include <gtest/gtest.h>
-
-using namespace std;
-using namespace isc::dns;
namespace isc {
@@ -77,7 +74,7 @@
///
static ::testing::AssertionResult
matchName(const char* nameexp1, const char* nameexp2,
- const Name& name1, const Name& name2);
+ const isc::dns::Name& name1, const isc::dns::Name& name2);
};
}
#endif // __UNITTEST_UTIL_H
Modified: branches/each-nsec3/src/lib/dns/cpp/Makefile.am
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/Makefile.am (original)
+++ branches/each-nsec3/src/lib/dns/cpp/Makefile.am Thu Mar 4 19:14:07 2010
@@ -18,8 +18,8 @@
libdns_la_SOURCES += rrsetlist.h rrsetlist.cc
libdns_la_SOURCES += question.h question.cc
libdns_la_SOURCES += message.h message.cc
+libdns_la_SOURCES += base32.h base32.cc
libdns_la_SOURCES += base64.h base64.cc
-libdns_la_SOURCES += base32.h base32.cc
libdns_la_SOURCES += sha1.h sha1.cc
libdns_la_SOURCES += tsig.h tsig.cc
libdns_la_SOURCES += dnstime.h dnstime.cc
Modified: branches/each-nsec3/src/lib/dns/cpp/buffer.h
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/buffer.h (original)
+++ branches/each-nsec3/src/lib/dns/cpp/buffer.h Thu Mar 4 19:14:07 2010
@@ -358,7 +358,7 @@
/// \param pos The beginning position in the buffer to write the data.
void writeUint16At(uint16_t data, size_t pos)
{
- if (pos + sizeof(data) >= data_.size()) {
+ if (pos + sizeof(data) > data_.size()) {
dns_throw(InvalidBufferPosition, "write at invalid position");
}
Modified: branches/each-nsec3/src/lib/dns/cpp/dnstime.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/dnstime.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/dnstime.cc Thu Mar 4 19:14:07 2010
@@ -99,21 +99,20 @@
day, "day");
checkRange(0, 23, hour, "hour");
checkRange(0, 59, minute, "minute");
- checkRange(0, 60, second, "second");
+ checkRange(0, 60, second, "second"); // 60 == leap second.
timeval = second + (60 * minute) + (3600 * hour) + ((day - 1) * 86400);
- for (int m = 0; m < (month - 1); m++)
+ for (int m = 0; m < (month - 1); m++) {
timeval += days[m] * 86400;
- if (isLeap(year) && month > 2)
+ }
+ if (isLeap(year) && month > 2) {
timeval += 86400;
- for (int y = 1970; y < year; y++) {
+ }
+ for (int y = 1970; y < year; ++y) {
timeval += ((isLeap(y) ? 366 : 365 ) * 86400);
}
return (timeval);
}
-
-
-
}
}
Modified: branches/each-nsec3/src/lib/dns/cpp/message.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/message.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/message.cc Thu Mar 4 19:14:07 2010
@@ -31,6 +31,7 @@
#include "messagerenderer.h"
#include "name.h"
#include "question.h"
+#include "rdataclass.h"
#include "rrclass.h"
#include "rrtype.h"
#include "rrttl.h"
@@ -59,7 +60,7 @@
static const flags_t FLAG_CD = 0x0010;
//
-// EDNS0 related constants
+// EDNS related constants
//
static const flags_t EXTFLAG_MASK = 0xffff;
static const flags_t EXTFLAG_DO = 0x8000;
@@ -189,9 +190,10 @@
class MessageImpl {
public:
- MessageImpl();
+ MessageImpl(Message::Mode mode);
// Open issues: should we rather have a header in wire-format
// for efficiency?
+ Message::Mode mode_;
qid_t qid_;
Rcode rcode_;
const Opcode* opcode_;
@@ -202,7 +204,9 @@
int counts_[SECTION_MAX]; // TODO: revisit this definition
vector<QuestionPtr> questions_;
vector<RRsetPtr> rrsets_[SECTION_MAX];
- RRsetPtr edns_;
+ RRsetPtr remote_edns_;
+ uint16_t remote_udpsize_;
+ RRsetPtr local_edns_;
uint16_t udpsize_;
#ifdef notyet
@@ -211,13 +215,13 @@
#endif
void init();
- void parseQuestion(Message& message, InputBuffer& buffer);
- void parseSection(Message& messge, const Section& section,
- InputBuffer& buffer);
+ int parseQuestion(Message& message, InputBuffer& buffer);
+ int parseSection(Message& messge, const Section& section,
+ InputBuffer& buffer);
};
-MessageImpl::MessageImpl() :
- rcode_(Rcode::NOERROR())
+MessageImpl::MessageImpl(Message::Mode mode) :
+ mode_(mode), rcode_(Rcode::NOERROR())
{
init();
}
@@ -230,7 +234,9 @@
rcode_ = Rcode::NOERROR(); // XXX
opcode_ = NULL;
dnssec_ok_ = false;
- edns_ = RRsetPtr();
+ remote_edns_ = RRsetPtr();
+ remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
+ local_edns_ = RRsetPtr();
udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
for (int i = 0; i < SECTION_MAX; i++) {
@@ -243,8 +249,8 @@
rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
}
-Message::Message() :
- impl_(new MessageImpl())
+Message::Message(Mode mode) :
+ impl_(new MessageImpl(mode))
{
}
@@ -277,10 +283,34 @@
return (impl_->dnssec_ok_);
}
+void
+Message::setDNSSECSupported(bool on)
+{
+ if (impl_->mode_ != Message::RENDER) {
+ dns_throw(InvalidMessageOperation,
+ "setDNSSECSupported performed in non-render mode");
+ }
+ impl_->dnssec_ok_ = on;
+}
+
uint16_t
Message::getUDPSize() const
{
return (impl_->udpsize_);
+}
+
+void
+Message::setUDPSize(uint16_t size)
+{
+ if (impl_->mode_ != Message::RENDER) {
+ dns_throw(InvalidMessageOperation,
+ "setUDPSize performed in non-render mode");
+ }
+ if (size < DEFAULT_MAX_UDPSIZE) {
+ dns_throw(InvalidMessageUDPSize,
+ "Specified UDP message size is too small");
+ }
+ impl_->udpsize_ = size;
}
qid_t
@@ -370,6 +400,44 @@
};
}
+namespace {
+bool
+addEDNS(MessageImpl* mimpl, MessageRenderer& renderer)
+{
+ bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0);
+
+ // If this is a reply and the request didn't have EDNS, we shouldn't add it.
+ if (mimpl->remote_edns_ == NULL && !is_query) {
+ return (false);
+ }
+
+ // For queries, we add EDNS only when necessary:
+ // Local UDP size is not the default value, or
+ // DNSSEC DO bit is to be set, or
+ // Extended Rcode is to be specified.
+ if (is_query && mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
+ !mimpl->dnssec_ok_ &&
+ mimpl->rcode_.getCode() < 0x10) {
+ return (false);
+ }
+
+ // Render EDNS OPT RR
+ uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
+ if (mimpl->dnssec_ok_) {
+ extrcode_flags |= 0x8000; // set DO bit
+ }
+ mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
+ RRClass(mimpl->udpsize_),
+ RRType::OPT(),
+ RRTTL(extrcode_flags)));
+ // We don't support any options in this simple implementation
+ mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
+ mimpl->local_edns_->toWire(renderer);
+
+ return (true);
+}
+}
+
void
Message::toWire(MessageRenderer& renderer)
{
@@ -378,7 +446,7 @@
// reserve room for the header
renderer.skip(HEADERLEN);
- uint16_t qrcount =
+ uint16_t qdcount =
for_each(impl_->questions_.begin(), impl_->questions_.end(),
RenderSection<QuestionPtr>(renderer)).getTotalCount();
@@ -396,6 +464,12 @@
impl_->rrsets_[sectionCodeToId(Section::ADDITIONAL())].end(),
RenderSection<RRsetPtr>(renderer)).getTotalCount();
+ // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
+ // logic, see the parser case)
+ if (addEDNS(this->impl_, renderer)) {
+ ++arcount;
+ }
+
// TBD: EDNS, TSIG, etc.
// fill in the header
@@ -408,7 +482,7 @@
renderer.writeUint16At(codes_and_flags, header_pos);
header_pos += sizeof(uint16_t);
// XXX: should avoid repeated pattern (TODO)
- renderer.writeUint16At(qrcount, header_pos);
+ renderer.writeUint16At(qdcount, header_pos);
header_pos += sizeof(uint16_t);
renderer.writeUint16At(ancount, header_pos);
header_pos += sizeof(uint16_t);
@@ -435,15 +509,21 @@
impl_->counts_[Section::AUTHORITY().getCode()] = buffer.readUint16();
impl_->counts_[Section::ADDITIONAL().getCode()] = buffer.readUint16();
- impl_->parseQuestion(*this, buffer);
- impl_->parseSection(*this, Section::ANSWER(), buffer);
- impl_->parseSection(*this, Section::AUTHORITY(), buffer);
- impl_->parseSection(*this, Section::ADDITIONAL(), buffer);
-}
-
-void
+ impl_->counts_[Section::QUESTION().getCode()] =
+ impl_->parseQuestion(*this, buffer);
+ impl_->counts_[Section::ANSWER().getCode()] =
+ impl_->parseSection(*this, Section::ANSWER(), buffer);
+ impl_->counts_[Section::AUTHORITY().getCode()] =
+ impl_->parseSection(*this, Section::AUTHORITY(), buffer);
+ impl_->counts_[Section::ADDITIONAL().getCode()] =
+ impl_->parseSection(*this, Section::ADDITIONAL(), buffer);
+}
+
+int
MessageImpl::parseQuestion(Message& message, InputBuffer& buffer)
{
+ unsigned int added = 0;
+
for (unsigned int count = 0;
count < counts_[Section::QUESTION().getCode()];
count++) {
@@ -460,8 +540,11 @@
// algorithm that requires the question section contain exactly one
// RR.
- questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
- }
+ questions_.push_back(QuestionPtr(new Question(name, rrclass, rrtype)));
+ ++added;
+ }
+
+ return (added);
}
namespace {
@@ -480,10 +563,12 @@
};
}
-void
+int
MessageImpl::parseSection(Message& message, const Section& section,
InputBuffer& buffer)
{
+ unsigned int added = 0;
+
for (unsigned int count = 0; count < counts_[section.getCode()]; count++) {
Name name(buffer);
@@ -507,17 +592,17 @@
dns_throw(DNSMessageFORMERR,
"EDNS OPT RR found in an invalid section");
}
- if (edns_ != NULL) {
+ if (remote_edns_ != NULL) {
dns_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
}
if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
+ Message::EDNS_SUPPORTED_VERSION) {
// XXX: we should probably not reject the message yet, because
// it's better to let the requestor know the responder-side
// highest version as indicated in Section 4.6 of RFC2671.
// This is probably because why BIND 9 does the version check
// in the client code.
// This is a TODO item. Right now we simply reject it.
- Message::EDNS0_SUPPORTED_VERSION) {
dns_throw(DNSMessageBADVERS, "unsupported EDNS version");
}
if (name != Name::ROOT_NAME()) {
@@ -525,8 +610,8 @@
"invalid owner name for EDNS OPT RR");
}
- edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- edns_->addRdata(rdata);
+ remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
+ remote_edns_->addRdata(rdata);
dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
@@ -549,7 +634,10 @@
rrset->addRdata(rdata);
rrsets_[sectionCodeToId(section)].push_back(rrset);
}
- }
+ ++added;
+ }
+
+ return (added);
}
namespace {
@@ -609,9 +697,36 @@
lexical_cast<string>(impl_->counts_[Section::ANSWER().getCode()]);
s += ", AUTHORITY: " +
lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
- s += ", ADDITIONAL: " +
- lexical_cast<string>(impl_->counts_[Section::ADDITIONAL().getCode()])
- + "\n";
+
+ unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
+ RRsetPtr edns_rrset;
+ if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
+ edns_rrset = impl_->remote_edns_;
+ ++arcount;
+ } else if (getHeaderFlag(MessageFlag::QR()) && impl_->local_edns_ != NULL) {
+ edns_rrset = impl_->local_edns_;
+ ++arcount;
+ }
+ s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
+
+ if (edns_rrset != NULL) {
+ s += "\n;; OPT PSEUDOSECTION:\n";
+ s += "; EDNS: version: ";
+ s += lexical_cast<string>(
+ (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
+ s += ", flags:";
+ if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
+ s += " do";
+ }
+ uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
+ if (mbz != 0) {
+ s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
+ } else {
+ s += "; udp: " +
+ lexical_cast<string>(edns_rrset->getClass().getCode());
+ }
+ s += "\n";
+ }
if (!impl_->questions_.empty()) {
s += "\n;; " +
@@ -654,8 +769,20 @@
void
Message::makeResponse()
{
+ if (impl_->mode_ != Message::PARSE) {
+ dns_throw(InvalidMessageOperation,
+ "makeResponse() is performed in non-parse mode");
+ }
+
+ impl_->dnssec_ok_ = false;
+ impl_->remote_udpsize_ = impl_->udpsize_;
+ impl_->local_edns_ = RRsetPtr();
+ impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
+
impl_->flags_ &= MESSAGE_REPLYPRESERVE;
setHeaderFlag(MessageFlag::QR());
+
+ impl_->mode_ = Message::RENDER;
impl_->rrsets_[sectionCodeToId(Section::ANSWER())].clear();
impl_->counts_[Section::ANSWER().getCode()] = 0;
Modified: branches/each-nsec3/src/lib/dns/cpp/message.h
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/message.h (original)
+++ branches/each-nsec3/src/lib/dns/cpp/message.h Thu Mar 4 19:14:07 2010
@@ -60,6 +60,18 @@
class InvalidMessageSection : public Exception {
public:
InvalidMessageSection(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+class InvalidMessageOperation : public Exception {
+public:
+ InvalidMessageOperation(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
+class InvalidMessageUDPSize : public Exception {
+public:
+ InvalidMessageUDPSize(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
@@ -503,7 +515,12 @@
class Message {
public:
- Message();
+ enum Mode {
+ PARSE = 0,
+ RENDER = 1
+ };
+public:
+ Message(Mode mode);
~Message();
private:
Message(const Message& source);
@@ -513,8 +530,9 @@
void setHeaderFlag(const MessageFlag& flag);
void clearHeaderFlag(const MessageFlag& flag);
bool isDNSSECSupported() const;
- void setDNSSECSupported(bool on); // not yet
+ void setDNSSECSupported(bool on);
uint16_t getUDPSize() const;
+ void setUDPSize(uint16_t size);
qid_t getQid() const;
void setQid(qid_t qid);
const Rcode& getRcode() const;
@@ -566,11 +584,11 @@
/// \brief The default maximum size of UDP DNS messages that don't cause
/// truncation.
///
- /// With EDNS0 the maximum size can be increases per message.
+ /// With EDNS the maximum size can be increases per message.
static const uint16_t DEFAULT_MAX_UDPSIZE = 512;
- /// \brief The highest EDNS0 version this implementation supports.
- static const uint8_t EDNS0_SUPPORTED_VERSION = 0;
+ /// \brief The highest EDNS version this implementation supports.
+ static const uint8_t EDNS_SUPPORTED_VERSION = 0;
//@}
private:
Modified: branches/each-nsec3/src/lib/dns/cpp/messagerenderer.h
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/messagerenderer.h (original)
+++ branches/each-nsec3/src/lib/dns/cpp/messagerenderer.h Thu Mar 4 19:14:07 2010
@@ -77,7 +77,7 @@
/// \param buffer An \c OutputBuffer object to which wire format data is
/// written.
MessageRenderer(OutputBuffer& buffer);
- /// \brief The default destructor.
+ /// \brief The destructor.
///
/// The destructor does nothing on the given \c buffer on construction;
/// in fact, it is expected that the user will use the resulting buffer
Modified: branches/each-nsec3/src/lib/dns/cpp/rdata.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/rdata.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/rdata.cc Thu Mar 4 19:14:07 2010
@@ -115,7 +115,6 @@
vector<uint8_t> data(rdata_len);
buffer.readData(&data[0], rdata_len);
- data.resize(rdata_len);
impl_ = new GenericImpl(data);
}
Modified: branches/each-nsec3/src/lib/dns/cpp/rdata/generic/dnskey_48.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/rdata/generic/dnskey_48.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/rdata/generic/dnskey_48.cc Thu Mar 4 19:14:07 2010
@@ -58,7 +58,7 @@
stringbuf keydatabuf;
iss >> flags >> protocol >> algorithm >> &keydatabuf;
- if (iss.bad() || iss.fail() || !iss.eof()) {
+ if (iss.bad() || iss.fail()) {
dns_throw(InvalidRdataText, "Invalid DNSKEY text");
}
if (flags > 0xffff) {
@@ -90,12 +90,10 @@
uint16_t flags = buffer.readUint16();
uint16_t protocol = buffer.readUint8();
uint16_t algorithm = buffer.readUint8();
- vector<uint8_t> keydata;
rdata_len -= 4;
- for (int i = 0; i < rdata_len; i++) {
- keydata.push_back(buffer.readUint8());
- }
+ vector<uint8_t> keydata(rdata_len);
+ buffer.readData(&keydata[0], rdata_len);
impl_ = new DNSKEYImpl(flags, protocol, algorithm, keydata);
}
Modified: branches/each-nsec3/src/lib/dns/cpp/rdata/generic/ds_43.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/rdata/generic/ds_43.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/rdata/generic/ds_43.cc Thu Mar 4 19:14:07 2010
@@ -57,7 +57,7 @@
stringbuf digestbuf;
iss >> tag >> algorithm >> digest_type >> &digestbuf;
- if (iss.bad() || iss.fail() || !iss.eof()) {
+ if (iss.bad() || iss.fail()) {
dns_throw(InvalidRdataText, "Invalid DS text");
}
if (tag > 0xffff) {
@@ -71,8 +71,7 @@
}
vector<uint8_t> digest;
- string digest_string = digestbuf.str();
- decodeHex(digest_string, digest);
+ decodeHex(digestbuf.str(), digest);
impl_ = new DSImpl(tag, algorithm, digest_type, digest);
}
@@ -86,12 +85,10 @@
uint16_t tag = buffer.readUint16();
uint16_t algorithm = buffer.readUint8();
uint16_t digest_type = buffer.readUint8();
- vector<uint8_t> digest;
rdata_len -= 4;
- for (int i = 0; i < rdata_len; i++) {
- digest.push_back(buffer.readUint8());
- }
+ vector<uint8_t> digest(rdata_len);
+ buffer.readData(&digest[0], rdata_len);
impl_ = new DSImpl(tag, algorithm, digest_type, digest);
}
Modified: branches/each-nsec3/src/lib/dns/cpp/rdata/generic/nsec_47.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/rdata/generic/nsec_47.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/rdata/generic/nsec_47.cc Thu Mar 4 19:14:07 2010
@@ -68,7 +68,7 @@
bitmap[code / 8] |= (0x80 >> (code % 8));
} while(!iss.eof());
- for(int window = 0; window < 256; window++) {
+ for (int window = 0; window < 256; window++) {
int octet;
for (octet = 31; octet >= 0; octet--) {
if (bitmap[window * 32 + octet] != 0) {
@@ -91,16 +91,17 @@
{
size_t pos = buffer.getPosition();
Name nextname(buffer);
+
+ // rdata_len must be sufficiently large to hold non empty bitmap.
+ if (rdata_len <= buffer.getPosition() - pos) {
+ dns_throw(InvalidRdataLength, "NSEC too short");
+ }
rdata_len -= (buffer.getPosition() - pos);
- if (rdata_len == 0) {
- dns_throw(InvalidRdataLength, "NSEC too short");
- }
-
- vector<uint8_t> typebits;
- for (int i = 0; i < rdata_len; i++) {
- typebits.push_back(buffer.readUint8());
- }
+ // FIXIT: we cannot naively copy the data because the bitmaps have
+ // semantics and other part of this class assumes they are valid.
+ vector<uint8_t> typebits(rdata_len);
+ buffer.readData(&typebits[0], rdata_len);
impl_ = new NSECImpl(nextname, typebits);
}
Modified: branches/each-nsec3/src/lib/dns/cpp/rdata/generic/rrsig_46.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/rdata/generic/rrsig_46.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/rdata/generic/rrsig_46.cc Thu Mar 4 19:14:07 2010
@@ -39,6 +39,15 @@
// BEGIN_ISC_NAMESPACE
// BEGIN_RDATA_NAMESPACE
+namespace {
+// This is the minimum necessary length of all wire-format RRSIG RDATA:
+// - two 8-bit fields (algorithm and labels)
+// - two 16-bit fields (covered and tag)
+// - three 32-bit fields (original TTL, expire and inception)
+const size_t RRSIG_MINIMUM_LEN = 2 * sizeof(uint8_t) + 2 * sizeof(uint16_t) +
+ 3 * sizeof(uint32_t);
+}
+
struct RRSIGImpl {
// straightforward representation of RRSIG RDATA fields
RRSIGImpl(const RRType& covered, uint8_t algorithm, uint8_t labels,
@@ -75,7 +84,7 @@
iss >> covered_txt >> algorithm >> labels >> originalttl
>> expire_txt >> inception_txt >> tag >> signer_txt
>> &signaturebuf;
- if (iss.bad() || iss.fail() || !iss.eof()) {
+ if (iss.bad() || iss.fail()) {
dns_throw(InvalidRdataText, "Invalid RRSIG text");
}
if (algorithm > 0xff) {
@@ -100,12 +109,11 @@
{
size_t pos = buffer.getPosition();
- if (rdata_len < 18) {
+ if (rdata_len < RRSIG_MINIMUM_LEN) {
dns_throw(InvalidRdataLength, "RRSIG too short");
}
- uint16_t typecode = buffer.readUint16();
- RRType covered(typecode);
+ RRType covered(buffer);
uint8_t algorithm = buffer.readUint8();
uint8_t labels = buffer.readUint8();
uint32_t originalttl = buffer.readUint32();
@@ -114,15 +122,14 @@
uint16_t tag = buffer.readUint16();
Name signer(buffer);
+ // rdata_len must be sufficiently large to hold non empty signature data.
+ if (rdata_len <= buffer.getPosition() - pos) {
+ dns_throw(InvalidRdataLength, "RRSIG too short");
+ }
rdata_len -= (buffer.getPosition() - pos);
- if (rdata_len == 0) {
- dns_throw(InvalidRdataLength, "DS too short");
- }
-
- vector<uint8_t> signature;
- for (int i = 0; i < rdata_len; i++) {
- signature.push_back(buffer.readUint8());
- }
+
+ vector<uint8_t> signature(rdata_len);
+ buffer.readData(&signature[0], rdata_len);
impl_ = new RRSIGImpl(covered, algorithm, labels,
originalttl, timeexpire, timeinception, tag,
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/Makefile.am
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/Makefile.am (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/Makefile.am Thu Mar 4 19:14:07 2010
@@ -11,17 +11,18 @@
run_unittests_SOURCES += messagerenderer_unittest.cc
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
run_unittests_SOURCES += rrttl_unittest.cc
-#run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
-#run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
-#run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
-#run_unittests_SOURCES += rdata_txt_unittest.cc rdata_mx_unittest.cc
-#run_unittests_SOURCES += rdata_cname_unittest.cc
-#run_unittests_SOURCES += rdata_dname_unittest.cc
-#run_unittests_SOURCES += rdata_opt_unittest.cc
-#run_unittests_SOURCES += rdata_dnskey_unittest.cc
-#run_unittests_SOURCES += rdata_ds_unittest.cc
-#run_unittests_SOURCES += rdata_nsec_unittest.cc
-#run_unittests_SOURCES += rdata_rrsig_unittest.cc
+run_unittests_SOURCES += dnstime_unittest.cc
+run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
+run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
+run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
+run_unittests_SOURCES += rdata_txt_unittest.cc rdata_mx_unittest.cc
+run_unittests_SOURCES += rdata_cname_unittest.cc
+run_unittests_SOURCES += rdata_dname_unittest.cc
+run_unittests_SOURCES += rdata_opt_unittest.cc
+run_unittests_SOURCES += rdata_dnskey_unittest.cc
+run_unittests_SOURCES += rdata_ds_unittest.cc
+run_unittests_SOURCES += rdata_nsec_unittest.cc
+run_unittests_SOURCES += rdata_rrsig_unittest.cc
run_unittests_SOURCES += rrset_unittest.cc rrsetlist_unittest.cc
run_unittests_SOURCES += question_unittest.cc
run_unittests_SOURCES += rrparamregistry_unittest.cc
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/buffer_unittest.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/buffer_unittest.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/buffer_unittest.cc Thu Mar 4 19:14:07 2010
@@ -126,12 +126,20 @@
{
obuffer.writeUint32(data32);
expected_size += sizeof(data32);
+
+ // overwrite 2nd and 3rd bytes
obuffer.writeUint16At(data16, 1);
EXPECT_EQ(expected_size, obuffer.getLength()); // length shouldn't change
-
const uint8_t* cp = static_cast<const uint8_t*>(obuffer.getData());
EXPECT_EQ(2, *(cp + 1));
EXPECT_EQ(3, *(cp + 2));
+
+ // overwrite 3rd and 4th bytes
+ obuffer.writeUint16At(data16, 2);
+ EXPECT_EQ(expected_size, obuffer.getLength());
+ cp = static_cast<const uint8_t*>(obuffer.getData());
+ EXPECT_EQ(2, *(cp + 2));
+ EXPECT_EQ(3, *(cp + 3));
EXPECT_THROW(obuffer.writeUint16At(data16, 3),
isc::dns::InvalidBufferPosition);
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/message_unittest.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/message_unittest.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/message_unittest.cc Thu Mar 4 19:14:07 2010
@@ -39,11 +39,16 @@
namespace {
class MessageTest : public ::testing::Test {
protected:
- MessageTest() : obuffer(0), renderer(obuffer) {}
+ MessageTest() : obuffer(0), renderer(obuffer),
+ message_parse(Message::PARSE),
+ message_render(Message::RENDER)
+ {}
+
static Question factoryFromFile(const char* datafile);
OutputBuffer obuffer;
MessageRenderer renderer;
- Message message;
+ Message message_parse;
+ Message message_render;
static void factoryFromFile(Message& message, const char* datafile);
};
@@ -80,24 +85,24 @@
TEST_F(MessageTest, fromWire)
{
- factoryFromFile(message, "testdata/message_fromWire1");
- EXPECT_EQ(0x1035, message.getQid());
- EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
- EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::QR()));
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::RD()));
- EXPECT_TRUE(message.getHeaderFlag(MessageFlag::AA()));
-
- QuestionPtr q = *message.beginQuestion();
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_EQ(0x1035, message_parse.getQid());
+ EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode());
+ EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode());
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::QR()));
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::RD()));
+ EXPECT_TRUE(message_parse.getHeaderFlag(MessageFlag::AA()));
+
+ QuestionPtr q = *message_parse.beginQuestion();
EXPECT_EQ(test_name, q->getName());
EXPECT_EQ(RRType::A(), q->getType());
EXPECT_EQ(RRClass::IN(), q->getClass());
- EXPECT_EQ(1, message.getRRCount(Section::QUESTION()));
- EXPECT_EQ(2, message.getRRCount(Section::ANSWER()));
- EXPECT_EQ(0, message.getRRCount(Section::AUTHORITY()));
- EXPECT_EQ(0, message.getRRCount(Section::ADDITIONAL()));
-
- RRsetPtr rrset = *message.beginSection(Section::ANSWER());
+ EXPECT_EQ(1, message_parse.getRRCount(Section::QUESTION()));
+ EXPECT_EQ(2, message_parse.getRRCount(Section::ANSWER()));
+ EXPECT_EQ(0, message_parse.getRRCount(Section::AUTHORITY()));
+ EXPECT_EQ(0, message_parse.getRRCount(Section::ADDITIONAL()));
+
+ RRsetPtr rrset = *message_parse.beginSection(Section::ANSWER());
EXPECT_EQ(test_name, rrset->getName());
EXPECT_EQ(RRType::A(), rrset->getType());
EXPECT_EQ(RRClass::IN(), rrset->getClass());
@@ -112,98 +117,144 @@
EXPECT_TRUE(it->isLast());
}
-TEST_F(MessageTest, EDNS0DOBit)
+TEST_F(MessageTest, GetEDNS0DOBit)
{
// Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message, "testdata/message_fromWire1");
- EXPECT_FALSE(message.isDNSSECSupported());
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_FALSE(message_parse.isDNSSECSupported());
// If DO bit is on, DNSSEC is considered to be supported.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire2");
- EXPECT_TRUE(message.isDNSSECSupported());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire2");
+ EXPECT_TRUE(message_parse.isDNSSECSupported());
// If DO bit is off, DNSSEC is considered to be unsupported.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire3");
- EXPECT_FALSE(message.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, EDNS0UDPSize)
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire3");
+ EXPECT_FALSE(message_parse.isDNSSECSupported());
+}
+
+TEST_F(MessageTest, SetEDNS0DOBit)
+{
+ // By default, it's false, and we can enable/disable it.
+ EXPECT_FALSE(message_render.isDNSSECSupported());
+ message_render.setDNSSECSupported(true);
+ EXPECT_TRUE(message_render.isDNSSECSupported());
+ message_render.setDNSSECSupported(false);
+ EXPECT_FALSE(message_render.isDNSSECSupported());
+
+ // A message in the parse mode doesn't allow this flag to be set.
+ EXPECT_THROW(message_parse.setDNSSECSupported(true),
+ InvalidMessageOperation);
+ // Once converted to the render mode, it works as above
+ message_parse.makeResponse();
+ EXPECT_FALSE(message_parse.isDNSSECSupported());
+ message_parse.setDNSSECSupported(true);
+ EXPECT_TRUE(message_parse.isDNSSECSupported());
+ message_parse.setDNSSECSupported(false);
+ EXPECT_FALSE(message_parse.isDNSSECSupported());
+}
+
+TEST_F(MessageTest, GetEDNS0UDPSize)
{
// Without EDNS0, the default max UDP size is used.
- factoryFromFile(message, "testdata/message_fromWire1");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message.getUDPSize());
+ factoryFromFile(message_parse, "testdata/message_fromWire1");
+ EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
// If the size specified in EDNS0 > default max, use it.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire2");
- EXPECT_EQ(4096, message.getUDPSize());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire2");
+ EXPECT_EQ(4096, message_parse.getUDPSize());
// If the size specified in EDNS0 < default max, keep using the default.
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire8");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message.getUDPSize());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire8");
+ EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
+}
+
+TEST_F(MessageTest, SetEDNS0UDPSize)
+{
+ // The default size if unspecified
+ EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
+ // A common buffer size with EDNS, should succeed
+ message_render.setUDPSize(4096);
+ EXPECT_EQ(4096, message_render.getUDPSize());
+ // Unusual large value, but accepted
+ message_render.setUDPSize(0xffff);
+ EXPECT_EQ(0xffff, message_render.getUDPSize());
+ // Too small is value is rejected
+ EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
+
+ // A message in the parse mode doesn't allow the set operation.
+ EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
+ // Once converted to the render mode, it works as above.
+ message_parse.makeResponse();
+ message_parse.setUDPSize(4096);
+ EXPECT_EQ(4096, message_parse.getUDPSize());
+ message_parse.setUDPSize(0xffff);
+ EXPECT_EQ(0xffff, message_parse.getUDPSize());
+ EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
}
TEST_F(MessageTest, EDNS0ExtCode)
{
// Extended Rcode = BADVERS
- factoryFromFile(message, "testdata/message_fromWire10");
- EXPECT_EQ(Rcode::BADVERS(), message.getRcode());
+ factoryFromFile(message_parse, "testdata/message_fromWire10");
+ EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
// Maximum extended Rcode
- message.clear();
- factoryFromFile(message, "testdata/message_fromWire11");
- EXPECT_EQ(0xfff, message.getRcode().getCode());
+ message_parse.clear();
+ factoryFromFile(message_parse, "testdata/message_fromWire11");
+ EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
}
TEST_F(MessageTest, BadEDNS0)
{
// OPT RR in the answer section
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire4"),
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire4"),
DNSMessageFORMERR);
// multiple OPT RRs (in the additional section)
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire5"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire5"),
DNSMessageFORMERR);
// OPT RR of a non root name
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire6"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire6"),
DNSMessageFORMERR);
// Compressed owner name of OPT RR points to a root name.
// Not necessarily bogus, but very unusual and mostly pathological.
// We accept it, but is it okay?
- message.clear();
- EXPECT_NO_THROW(factoryFromFile(message, "testdata/message_fromWire7"));
+ message_parse.clear();
+ EXPECT_NO_THROW(factoryFromFile(message_parse,
+ "testdata/message_fromWire7"));
// Unsupported Version
- message.clear();
- EXPECT_THROW(factoryFromFile(message, "testdata/message_fromWire9"),
+ message_parse.clear();
+ EXPECT_THROW(factoryFromFile(message_parse, "testdata/message_fromWire9"),
DNSMessageBADVERS);
}
TEST_F(MessageTest, toWire)
{
- message.setQid(0x1035);
- message.setOpcode(Opcode::QUERY());
- message.setRcode(Rcode::NOERROR());
- message.setHeaderFlag(MessageFlag::QR());
- message.setHeaderFlag(MessageFlag::RD());
- message.setHeaderFlag(MessageFlag::AA());
- message.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
- RRType::A()));
+ message_render.setQid(0x1035);
+ message_render.setOpcode(Opcode::QUERY());
+ message_render.setRcode(Rcode::NOERROR());
+ message_render.setHeaderFlag(MessageFlag::QR());
+ message_render.setHeaderFlag(MessageFlag::RD());
+ message_render.setHeaderFlag(MessageFlag::AA());
+ message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(),
+ RRType::A()));
RRsetPtr rrset = RRsetPtr(new RRset(Name("test.example.com"), RRClass::IN(),
RRType::A(), RRTTL(3600)));
rrset->addRdata(in::A("192.0.2.1"));
rrset->addRdata(in::A("192.0.2.2"));
- message.addRRset(Section::ANSWER(), rrset);
-
- EXPECT_EQ(1, message.getRRCount(Section::QUESTION()));
- EXPECT_EQ(2, message.getRRCount(Section::ANSWER()));
- EXPECT_EQ(0, message.getRRCount(Section::AUTHORITY()));
- EXPECT_EQ(0, message.getRRCount(Section::ADDITIONAL()));
-
- message.toWire(renderer);
+ message_render.addRRset(Section::ANSWER(), rrset);
+
+ EXPECT_EQ(1, message_render.getRRCount(Section::QUESTION()));
+ EXPECT_EQ(2, message_render.getRRCount(Section::ANSWER()));
+ EXPECT_EQ(0, message_render.getRRCount(Section::AUTHORITY()));
+ EXPECT_EQ(0, message_render.getRRCount(Section::ADDITIONAL()));
+
+ message_render.toWire(renderer);
vector<unsigned char> data;
UnitTestUtil::readWireData("testdata/message_toWire1", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/rdata_nsec_unittest.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/rdata_nsec_unittest.cc Thu Mar 4 19:14:07 2010
@@ -58,8 +58,17 @@
{
const generic::NSEC rdata_nsec(nsec_txt);
EXPECT_EQ(0, rdata_nsec.compare(
- *rdataFactoryFromFile(RRType("NSEC"), RRClass("IN"),
- "testdata/rdata_nsec_fromWire")));
+ *rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
+ "testdata/rdata_nsec_fromWire1")));
+
+ // Too short RDLENGTH
+ EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
+ "testdata/rdata_nsec_fromWire2"),
+ InvalidRdataLength);
+
+ // This should be rejected
+ //rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
+ // "testdata/rdata_nsec_fromWire3")->toText();
}
TEST_F(Rdata_NSEC_Test, toWireRenderer_NSEC)
@@ -69,7 +78,7 @@
rdata_nsec.toWire(renderer);
vector<unsigned char> data;
- UnitTestUtil::readWireData("testdata/rdata_nsec_fromWire", data);
+ UnitTestUtil::readWireData("testdata/rdata_nsec_fromWire1", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
static_cast<const uint8_t *>(obuffer.getData()) + 2,
obuffer.getLength() - 2, &data[2], data.size() - 2);
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/rdata_rrsig_unittest.cc (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/rdata_rrsig_unittest.cc Thu Mar 4 19:14:07 2010
@@ -38,7 +38,7 @@
// there's nothing to specialize
};
-TEST_F(Rdata_RRSIG_Test, fromText_RRSIG)
+TEST_F(Rdata_RRSIG_Test, fromText)
{
string rrsig_txt("A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
@@ -50,7 +50,7 @@
}
-TEST_F(Rdata_RRSIG_Test, badText_RRSIG)
+TEST_F(Rdata_RRSIG_Test, badText)
{
EXPECT_THROW(const generic::RRSIG sig("SPORK"), InvalidRdataText);
EXPECT_THROW(const generic::RRSIG sig("A 555 4 43200 "
@@ -78,12 +78,6 @@
"NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
"f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidTime);
EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
- "19100223214617 19100222214617 8496 isc.org. "
- "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
- "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
- "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU"
- "f49t+sXKPzbipN9g+s1ZPiIyofc="), InvalidTime);
- EXPECT_THROW(const generic::RRSIG sig("A 5 4 43200 "
"20100223214617 20100222214617 999999 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
"diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/"
@@ -95,7 +89,7 @@
BadBase64String);
}
-TEST_F(Rdata_RRSIG_Test, toWireRenderer_RRSIG)
+TEST_F(Rdata_RRSIG_Test, toWireRenderer)
{
string rrsig_txt("A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
@@ -106,7 +100,7 @@
rdata_rrsig.toWire(renderer);
}
-TEST_F(Rdata_RRSIG_Test, toWireBuffer_RRSIG)
+TEST_F(Rdata_RRSIG_Test, toWireBuffer)
{
string rrsig_txt("A 5 4 43200 20100223214617 20100222214617 8496 isc.org. "
"evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz"
@@ -117,19 +111,22 @@
rdata_rrsig.toWire(obuffer);
}
-TEST_F(Rdata_RRSIG_Test, createFromWire_RRSIG)
+TEST_F(Rdata_RRSIG_Test, createFromWire)
{
string rrsig_txt("A 5 2 43200 20100327070149 20100225070149 2658 isc.org. "
"HkJk/xZTvzePU8NENl/ley8bbUumhk1hXciyqhLnz1VQFzkDooej6neX"
"ZgWZzQKeTKPOYWrnYtdZW4PnPQFeUl3orgLev7F8J6FZlDn0y/J/ThR5"
"m36Mo2/Gdxjj8lJ/IjPVkdpKyBpcnYND8KEIma5MyNCNeyO1UkfPQZGHNSQ=");
EXPECT_EQ(rrsig_txt, rdataFactoryFromFile(RRType("RRSIG"), RRClass("IN"),
- "testdata/rdata_rrsig_fromWire")->toText());
+ "testdata/rdata_rrsig_fromWire1")->toText());
generic::RRSIG rdata_rrsig(rrsig_txt);
EXPECT_EQ(0, rdata_rrsig.compare(
*rdataFactoryFromFile(RRType("RRSIG"), RRClass("IN"),
- "testdata/rdata_rrsig_fromWire")));
+ "testdata/rdata_rrsig_fromWire1")));
+
+ // RDLEN is too short
+ EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(),
+ "testdata/rdata_rrsig_fromWire2"),
+ InvalidRdataLength);
}
-
-
}
Modified: branches/each-nsec3/src/lib/dns/cpp/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/each-nsec3/src/lib/dns/cpp/tests/testdata/gen-wiredata.py.in (original)
+++ branches/each-nsec3/src/lib/dns/cpp/tests/testdata/gen-wiredata.py.in Thu Mar 4 19:14:07 2010
@@ -1,11 +1,14 @@
#!@PYTHON@
-import configparser, re, sys
+import configparser, re, time, sys
+from datetime import datetime
from optparse import OptionParser
re_hex = re.compile('0x[0-9a-fA-F]+')
-re_decimal = re.compile('\d+')
-re_ = re.compile('\d+$')
+re_decimal = re.compile('\d+$')
+
+dnssec_timefmt = '%Y%m%d%H%M%S'
+
dict_qr = { 'query' : 0, 'response' : 1 }
dict_opcode = { 'query' : 0, 'iquery' : 1, 'status' : 2, 'notify' : 4,
'update' : 5 }
@@ -30,9 +33,13 @@
rdict_rrtype = dict([(dict_rrtype[k], k.upper()) for k in dict_rrtype.keys()])
dict_rrclass = { 'in' : 1, 'ch' : 3, 'hs' : 4, 'any' : 255 }
rdict_rrclass = dict([(dict_rrclass[k], k.upper()) for k in dict_rrclass.keys()])
+dict_algorithm = { 'rsamd5' : 1, 'dh' : 2, 'dsa' : 3, 'ecc' : 4, 'rsasha1' : 5 }
+rdict_algorithm = dict([(dict_algorithm[k], k.upper()) for k in dict_algorithm.keys()])
+
header_xtables = { 'qr' : dict_qr, 'opcode' : dict_opcode,
'rcode' : dict_rcode }
question_xtables = { 'rrtype' : dict_rrtype, 'rrclass' : dict_rrclass }
+rrsig_xtables = { 'algorithm' : dict_algorithm }
def parse_value(value, xtable = {}):
if re.search(re_hex, value):
@@ -61,6 +68,14 @@
if len(l) == 0:
break
return wire
+
+def count_namelabels(name):
+ if name == '.': # special case
+ return 0
+ m = re.match('^(.*)\.$', name)
+ if m:
+ name = m.group(1)
+ return len(name.split('.'))
def get_config(config, section, configobj, xtables = {}):
try:
@@ -148,6 +163,46 @@
f.write('# RDLEN=%d\n' % self.rdlen)
f.write('%04x\n' % self.rdlen)
+class RRSIG:
+ rdlen = -1 # auto-calculate
+ covered = 1 # A
+ algorithm = 5 # RSA-SHA1
+ labels = -1 # auto-calculate (#labels of signer)
+ originalttl = 3600
+ expiration = int(time.mktime(datetime.strptime('20100131120000',
+ dnssec_timefmt).timetuple()))
+ inception = int(time.mktime(datetime.strptime('20100101120000',
+ dnssec_timefmt).timetuple()))
+ tag = 0x1035
+ signer = 'example.com'
+ signature = 0x123456789abcdef123456789abcdef
+ def dump(self, f):
+ name_wire = encode_name(self.signer)
+ sig_wire = '%x' % self.signature
+ rdlen = self.rdlen
+ if rdlen < 0:
+ rdlen = int(18 + len(name_wire) / 2 + len(str(sig_wire)) / 2)
+ labels = self.labels
+ if labels < 0:
+ labels = count_namelabels(self.signer)
+ f.write('\n# RRSIG RDATA (RDLEN=%d)\n' % rdlen)
+ f.write('%04x\n' % rdlen);
+ f.write('# Covered=%s Algorithm=%s Labels=%d OrigTTL=%d\n' %
+ (code_totext(self.covered, rdict_rrtype),
+ code_totext(self.algorithm, rdict_algorithm), labels,
+ self.originalttl))
+ f.write('%04x %02x %02x %08x\n' % (self.covered, self.algorithm, labels,
+ self.originalttl))
+ f.write('# Expiration=%s, Inception=%s\n' %
+ (str(self.expiration), str(self.inception)))
+ f.write('%08x %08x\n' % (self.expiration, self.inception))
+ f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
+ f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
+
+config_param = {'header' : (DNSHeader, header_xtables),
+ 'question' : (DNSQuestion, question_xtables),
+ 'edns' : (EDNS, {}), 'rrsig' : (RRSIG, {}) }
+
usage = '''usage: %prog [options] input_file'''
if __name__ == "__main__":
@@ -155,6 +210,9 @@
parser.add_option('-o', '--output', action='store', dest='output',
default=None, metavar='FILE',
help='output file name [default: prefix of input_file]')
+ parser.add_option('-m', '--mode', action='store', dest='mode',
+ default='message', metavar='[message|custom]',
+ help='specify dump mode [default: %default]')
(options, args) = parser.parse_args()
if len(args) == 0:
@@ -163,7 +221,7 @@
outputfile = options.output
if not outputfile:
- m = re.match('(.*)\.[^.]+$', sys.argv[1])
+ m = re.match('(.*)\.[^.]+$', configfile)
if m:
outputfile = m.group(1)
else:
@@ -176,16 +234,15 @@
print_header(output, configfile)
- header = DNSHeader()
- if get_config(config, 'header', header, header_xtables):
- header.dump(output)
-
- question = DNSQuestion()
- if get_config(config, 'question', question, question_xtables):
- question.dump(output)
-
- edns = EDNS()
- if get_config(config, 'edns', edns):
- edns.dump(output)
+ if options.mode == 'custom':
+ sections = config.get('custom', 'sections').split(':')
+ else:
+ sections = ['header', 'question', 'edns']
+
+ for s in sections:
+ section_param = config_param[s]
+ (obj, xtables) = (section_param[0](), section_param[1])
+ if get_config(config, s, obj, xtables):
+ obj.dump(output)
output.close()
More information about the bind10-changes
mailing list