[svn] commit: r1126 - in /trunk/src/lib/auth: data_source.cc data_source.h data_source_sqlite3.cc data_source_sqlite3.h data_source_static.cc data_source_static.h unittest_ds.cc unittest_ds.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Mar 5 08:30:38 UTC 2010
Author: each
Date: Fri Mar 5 08:30:37 2010
New Revision: 1126
Log:
checkpoint:
- added code for findCoveringNSEC3()
Modified:
trunk/src/lib/auth/data_source.cc
trunk/src/lib/auth/data_source.h
trunk/src/lib/auth/data_source_sqlite3.cc
trunk/src/lib/auth/data_source_sqlite3.h
trunk/src/lib/auth/data_source_static.cc
trunk/src/lib/auth/data_source_static.h
trunk/src/lib/auth/unittest_ds.cc
trunk/src/lib/auth/unittest_ds.h
Modified: trunk/src/lib/auth/data_source.cc
==============================================================================
--- trunk/src/lib/auth/data_source.cc (original)
+++ trunk/src/lib/auth/data_source.cc Fri Mar 5 08:30:37 2010
@@ -20,11 +20,14 @@
#include <boost/foreach.hpp>
+#include <dns/base32.h>
+#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rrset.h>
#include <dns/rrsetlist.h>
+#include <dns/sha1.h>
#include <cc/data.h>
@@ -689,5 +692,38 @@
}
}
-}
-}
+Nsec3Param::Nsec3Param(uint8_t a, uint8_t f, uint16_t i,
+ std::vector<uint8_t>& s) :
+ algorithm(a), flags(f), iterations(i), salt(s)
+{}
+
+string
+Nsec3Param::getHash(const Name& name) const {
+ OutputBuffer buf(0);
+
+ name.toWire(buf);
+ buf.writeData(&salt[0], salt.size());
+ uint8_t* in = (uint8_t*) buf.getData();
+ size_t inlength = buf.getLength();
+ uint8_t digest[SHA1_HASHSIZE];
+ int n = 0;
+
+ SHA1Context sha;
+ do {
+ SHA1Reset(&sha);
+ SHA1Input(&sha, in, inlength);
+ SHA1Result(&sha, digest);
+ in = digest;
+ inlength = SHA1_HASHSIZE;
+ } while (n++ < iterations);
+
+ vector<uint8_t> result;
+ for (int i = 0; i < SHA1_HASHSIZE; ++i) {
+ result.push_back(digest[i]);
+ }
+
+ return (encodeBase32(result));
+}
+
+}
+}
Modified: trunk/src/lib/auth/data_source.h
==============================================================================
--- trunk/src/lib/auth/data_source.h (original)
+++ trunk/src/lib/auth/data_source.h Fri Mar 5 08:30:37 2010
@@ -37,6 +37,7 @@
class NameMatch;
class Query;
+class Nsec3Param;
class DataSrc;
typedef boost::shared_ptr<DataSrc> DataSrcPtr;
@@ -141,6 +142,13 @@
isc::dns::Name& target,
const isc::dns::Name* zonename) const = 0;
+ // This MUST be implemented by concrete data sources which support
+ // NSEC3, but is optional for others
+ virtual Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const isc::dns::Name& qname,
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const = 0;
};
// Base class for a DNS Data Source
@@ -205,6 +213,13 @@
const isc::dns::Name& qname,
isc::dns::Name& target,
const isc::dns::Name* zonename) const = 0;
+
+ virtual Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const isc::dns::Name& qname,
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const = 0;
+
private:
isc::dns::RRClass rrclass;
};
@@ -278,6 +293,15 @@
return (NOT_IMPLEMENTED);
}
+ virtual Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const isc::dns::Name& qname,
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const
+ {
+ return (NOT_IMPLEMENTED);
+ }
+
private:
std::vector<ConstDataSrcPtr> data_sources;
};
@@ -300,6 +324,18 @@
const isc::dns::Name qname_;
};
+class Nsec3Param {
+public:
+ Nsec3Param(uint8_t a, uint8_t f, uint16_t i, std::vector<uint8_t>& s);
+
+ const uint8_t algorithm;
+ const uint8_t flags;
+ const uint16_t iterations;
+ const std::vector<uint8_t>& salt;
+
+ std::string getHash(const isc::dns::Name& name) const;
+};
+
}
}
Modified: trunk/src/lib/auth/data_source_sqlite3.cc
==============================================================================
--- trunk/src/lib/auth/data_source_sqlite3.cc (original)
+++ trunk/src/lib/auth/data_source_sqlite3.cc Fri Mar 5 08:30:37 2010
@@ -15,6 +15,7 @@
// $Id$
#include "data_source_sqlite3.h"
+
#include <dns/rrttl.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
@@ -123,21 +124,21 @@
rc = sqlite3_bind_int(query, 1, zone_id);
if (rc != SQLITE_OK) {
- throw("Could not bind 1 (record)");
+ throw("Could not bind 1 (query)");
}
rc = sqlite3_bind_text(query, 2, c_name, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) {
- throw("Could not bind 2 (record)");
+ throw("Could not bind 2 (query)");
}
if (query == q_record) {
rc = sqlite3_bind_text(query, 3, rdtype.toText().c_str(), -1,
SQLITE_STATIC);
if (rc != SQLITE_OK) {
- throw("Could not bind 3 (record)");
- }
- }
-
+ throw("Could not bind 3 (query)");
+ }
+ }
+
// loop
int target_ttl = -1;
int sig_ttl = -1;
@@ -365,6 +366,26 @@
throw(e);
}
+ const char* q_nsec3_str = "SELECT rdtype, ttl, rdata FROM nsec3 "
+ "WHERE zone_id=?1 AND hash == $2";
+ try {
+ q_nsec3 = prepare(q_nsec3_str);
+ } catch (const char* e) {
+ cout << e << endl << q_nsec3_str << endl;
+ cout << sqlite3_errmsg(db) << endl;
+ throw(e);
+ }
+
+ const char* q_prevnsec3_str = "SELECT rdtype, ttl, rdata FROM nsec3 "
+ "WHERE zone_id=?1 AND hash <= $2 "
+ "ORDER BY rhash DESC LIMIT 1";
+ try {
+ q_prevnsec3 = prepare(q_prevnsec3_str);
+ } catch (const char* e) {
+ cout << e << endl << q_prevnsec3_str << endl;
+ cout << sqlite3_errmsg(db) << endl;
+ throw(e);
+ }
}
void
@@ -392,6 +413,7 @@
"name STRING NOT NULL, "
"rdclass STRING NOT NULL DEFAULT 'IN', "
"dnssec BOOLEAN NOT NULL DEFAULT 0)");
+ execSetupQuery("CREATE INDEX zones_byname ON zones (name)");
execSetupQuery("CREATE TABLE records ("
"id INTEGER PRIMARY KEY, "
"zone_id INTEGER NOT NULL, "
@@ -403,7 +425,15 @@
"rdata STRING NOT NULL)");
execSetupQuery("CREATE INDEX records_byname ON records (name)");
execSetupQuery("CREATE INDEX records_byrname ON records (rname)");
- execSetupQuery("CREATE INDEX zones_byname ON zones (name)");
+ execSetupQuery("CREATE TABLE nsec3 ("
+ "id INTEGER PRIMARY KEY, "
+ "zone_id INTEGER NOT NULL, "
+ "hash STRING NOT NULL, "
+ "owner STRING NOT NULL, "
+ "ttl INTEGER NOT NULL, "
+ "rdtype STRING NOT NULL, "
+ "rdata STRING NOT NULL)");
+ execSetupQuery("CREATE INDEX nsec3_byhash ON nsec3 (hash)");
setupPreparedStatements();
cout << "Created new file and schema" << endl;
@@ -420,6 +450,8 @@
q_any = NULL;
q_count = NULL;
q_previous = NULL;
+ q_nsec3 = NULL;
+ q_prevnsec3 = NULL;
}
Sqlite3DataSrc::~Sqlite3DataSrc() {
@@ -469,14 +501,14 @@
int rc = sqlite3_bind_int(q_previous, 1, zone_id);
if (rc != SQLITE_OK) {
- throw ("Could not bind 1 (record)");
+ throw ("Could not bind 1 (previous)");
}
rc = sqlite3_bind_text(q_previous, 2, qname.reverse().toText().c_str(),
-1, SQLITE_STATIC);
if (rc != SQLITE_OK) {
- throw ("Could not bind 2 (record)");
- }
-
+ throw ("Could not bind 2 (previous)");
+ }
+
rc = sqlite3_step(q_previous);
if (rc != SQLITE_ROW) {
sqlite3_reset(q_previous);
@@ -486,6 +518,112 @@
// XXX: bad cast. we should revisit this.
target = Name((const char*)sqlite3_column_text(q_previous, 0));
sqlite3_reset(q_previous);
+ return (SUCCESS);
+}
+
+DataSrc::Result
+Sqlite3DataSrc::findCoveringNSEC3(const Query& q,
+ const Nsec3Param& nsec3param,
+ const Name& qname,
+ const Name& zonename,
+ RRsetList& target) const
+{
+ int zone_id = findClosest(zonename.toText().c_str(), NULL);
+ if (zone_id < 0) {
+ return (ERROR);
+ }
+
+ string hashstr = nsec3param.getHash(qname);
+
+ sqlite3_reset(q_prevnsec3);
+ sqlite3_clear_bindings(q_prevnsec3);
+
+ int rc = sqlite3_bind_int(q_prevnsec3, 1, zone_id);
+ if (rc != SQLITE_OK) {
+ throw ("Could not bind 1 (previous NSEC3)");
+ }
+
+ rc = sqlite3_bind_text(q_prevnsec3, 2, hashstr.c_str(), -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw ("Could not bind 2 (previous NSEC3)");
+ }
+
+ rc = sqlite3_step(q_prevnsec3);
+ const char* hash;
+ if (rc == SQLITE_ROW) {
+ hash = (const char*) sqlite3_column_text(q_prevnsec3, 0);
+ } else {
+ // We need to find the final NSEC3 in the chain.
+ // A valid NSEC3 hash is in base32, which contains no
+ // letters higher than V, so a search for the previous
+ // NSEC3 from "W" will always find it.
+ sqlite3_reset(q_prevnsec3);
+ rc = sqlite3_bind_text(q_prevnsec3, 2, "W", -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw ("Could not bind 2 (last NSEC3)");
+ }
+
+ rc = sqlite3_step(q_prevnsec3);
+ if (rc != SQLITE_ROW) {
+ return (ERROR);
+ }
+
+ hash = (const char*) sqlite3_column_text(q_prevnsec3, 0);
+ }
+
+ sqlite3_reset(q_nsec3);
+ sqlite3_clear_bindings(q_nsec3);
+
+ rc = sqlite3_bind_int(q_nsec3, 1, zone_id);
+ if (rc != SQLITE_OK) {
+ throw ("Could not bind 1 (NSEC3)");
+ }
+
+ rc = sqlite3_bind_text(q_nsec3, 2, hash, -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw ("Could not bind 2 (NSEC3)");
+ }
+
+ int target_ttl = -1;
+ int sig_ttl = -1;
+ const Name& name(Name(hash).concatenate(zonename));
+ RRsetPtr rrset(new RRset(name, RRClass::IN(), RRType::NSEC3(), RRTTL(0)));
+ if (!target[RRType::NSEC3()]) {
+ target.addRRset(rrset);
+ }
+
+ rc = sqlite3_step(q_nsec3);
+ while (rc == SQLITE_ROW) {
+ RRType type((const char*)sqlite3_column_text(q_nsec3, 1));
+ int ttl = sqlite3_column_int(q_nsec3, 2);
+ const char* rdata = (const char*)sqlite3_column_text(q_nsec3, 3);
+
+ if (type == RRType::NSEC3()) {
+ rrset->addRdata(createRdata(type, RRClass::IN(), rdata));
+ if (target_ttl == -1 || target_ttl > ttl) {
+ target_ttl = ttl;
+ }
+ rrset->setTTL(RRTTL(target_ttl));
+ } else {
+ RdataPtr rrsig = createRdata(RRType::RRSIG(), RRClass::IN(), rdata);
+ if (rrset->getRRsig()) {
+ rrset->getRRsig()->addRdata(rrsig);
+ } else {
+ RRsetPtr sigs = RRsetPtr(new RRset(name, RRClass::IN(),
+ RRType::RRSIG(), RRTTL(0)));
+ sigs->addRdata(rrsig);
+ rrset->addRRsig(sigs);
+ }
+ }
+
+ if (sig_ttl == -1 || sig_ttl > ttl) {
+ sig_ttl = ttl;
+ }
+ rrset->getRRsig()->setTTL(RRTTL(sig_ttl));
+ rc = sqlite3_step(q_nsec3);
+ }
+
+ sqlite3_reset(q_nsec3);
return (SUCCESS);
}
@@ -608,6 +746,16 @@
q_previous = NULL;
}
+ if (q_prevnsec3) {
+ release(q_prevnsec3);
+ q_prevnsec3 = NULL;
+ }
+
+ if (q_nsec3) {
+ release(q_nsec3);
+ q_nsec3 = NULL;
+ }
+
sqlite3_close(db);
db = NULL;
Modified: trunk/src/lib/auth/data_source_sqlite3.h
==============================================================================
--- trunk/src/lib/auth/data_source_sqlite3.h (original)
+++ trunk/src/lib/auth/data_source_sqlite3.h Fri Mar 5 08:30:37 2010
@@ -35,6 +35,7 @@
namespace auth {
class Query;
+class Nsec3Param;
class Sqlite3DataSrc : public DataSrc {
///
@@ -48,48 +49,54 @@
Sqlite3DataSrc& operator=(const Sqlite3DataSrc& source);
public:
Sqlite3DataSrc();
- virtual ~Sqlite3DataSrc();
+ ~Sqlite3DataSrc();
//@}
- virtual void findClosestEnclosure(NameMatch& match) const;
+ void findClosestEnclosure(NameMatch& match) const;
- virtual Result findRRset(const Query& q,
+ 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,
+ const isc::dns::Name* zonename) const;
+
+ 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,
+ const isc::dns::Name* zonename) const;
+
+ Result findAddrs(const Query& q,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
+ uint32_t& flags,
+ const isc::dns::Name* zonename) const;
+
+ Result findReferral(const Query& q,
+ const isc::dns::Name& qname,
+ const isc::dns::RRClass& qclass,
+ isc::dns::RRsetList& target,
+ uint32_t& flags,
+ const isc::dns::Name* zonename) const;
+
+ DataSrc::Result findPreviousName(const Query& q,
+ const isc::dns::Name& qname,
+ isc::dns::Name& target,
+ const isc::dns::Name* zonename) const;
+
+ Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
const isc::dns::Name& qname,
- const isc::dns::RRClass& qclass,
- const isc::dns::RRType& qtype,
- isc::dns::RRsetList& target,
- uint32_t& flags,
- const isc::dns::Name* zonename) const;
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const;
- virtual 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,
- const isc::dns::Name* zonename) const;
-
- virtual Result findAddrs(const Query& q,
- const isc::dns::Name& qname,
- const isc::dns::RRClass& qclass,
- isc::dns::RRsetList& target,
- uint32_t& flags,
- const isc::dns::Name* zonename) const;
-
- virtual Result findReferral(const Query& q,
- const isc::dns::Name& qname,
- const isc::dns::RRClass& qclass,
- isc::dns::RRsetList& target,
- uint32_t& flags,
- const isc::dns::Name* zonename) const;
-
- virtual DataSrc::Result findPreviousName(const Query& q,
- const isc::dns::Name& qname,
- isc::dns::Name& target,
- const isc::dns::Name* zonename) const;
-
- virtual Result init();
- virtual Result close();
+ Result init();
+ Result close();
private:
enum Mode {
@@ -126,6 +133,8 @@
sqlite3_stmt *q_any;
sqlite3_stmt *q_count;
sqlite3_stmt *q_previous;
+ sqlite3_stmt *q_nsec3;
+ sqlite3_stmt *q_prevnsec3;
};
}
Modified: trunk/src/lib/auth/data_source_static.cc
==============================================================================
--- trunk/src/lib/auth/data_source_static.cc (original)
+++ trunk/src/lib/auth/data_source_static.cc Fri Mar 5 08:30:37 2010
@@ -165,6 +165,14 @@
}
DataSrc::Result
+StaticDataSrc::findCoveringNSEC3(const Query& q, const Nsec3Param& param,
+ const Name& qname, const Name& zonename,
+ RRsetList& target) const
+{
+ return (NOT_IMPLEMENTED);
+}
+
+DataSrc::Result
StaticDataSrc::init()
{
return (SUCCESS);
Modified: trunk/src/lib/auth/data_source_static.h
==============================================================================
--- trunk/src/lib/auth/data_source_static.h (original)
+++ trunk/src/lib/auth/data_source_static.h Fri Mar 5 08:30:37 2010
@@ -80,6 +80,12 @@
isc::dns::Name& target,
const isc::dns::Name* zonename) const;
+ Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const isc::dns::Name& qname,
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const;
+
Result init();
Result close();
};
Modified: trunk/src/lib/auth/unittest_ds.cc
==============================================================================
--- trunk/src/lib/auth/unittest_ds.cc (original)
+++ trunk/src/lib/auth/unittest_ds.cc Fri Mar 5 08:30:37 2010
@@ -765,5 +765,15 @@
return (SUCCESS);
}
-}
-}
+DataSrc::Result
+TestDataSrc::findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const Name& qname,
+ const Name& zonename,
+ RRsetList& target) const
+{
+ return (NOT_IMPLEMENTED);
+}
+
+}
+}
Modified: trunk/src/lib/auth/unittest_ds.h
==============================================================================
--- trunk/src/lib/auth/unittest_ds.h (original)
+++ trunk/src/lib/auth/unittest_ds.h Fri Mar 5 08:30:37 2010
@@ -85,6 +85,12 @@
isc::dns::Name& target,
const isc::dns::Name* zonename) const;
+ Result findCoveringNSEC3(const Query& q,
+ const Nsec3Param& param,
+ const isc::dns::Name& qname,
+ const isc::dns::Name& zonename,
+ isc::dns::RRsetList& target) const;
+
Result init() { return (SUCCESS); }
Result close() { return (SUCCESS); }
More information about the bind10-changes
mailing list