[svn] commit: r2412 - in /branches/trac232/src: bin/auth/auth_srv.cc lib/datasrc/data_source.cc lib/datasrc/data_source.h lib/datasrc/sqlite3_datasrc.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Jul 5 15:59:03 UTC 2010
Author: jelte
Date: Mon Jul 5 15:59:02 2010
New Revision: 2412
Log:
initial simple IXFR (incoming) handler, currenlty specific for sqlite3, needs generalization and move to DataSrc.
Modified:
branches/trac232/src/bin/auth/auth_srv.cc
branches/trac232/src/lib/datasrc/data_source.cc
branches/trac232/src/lib/datasrc/data_source.h
branches/trac232/src/lib/datasrc/sqlite3_datasrc.cc
Modified: branches/trac232/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac232/src/bin/auth/auth_srv.cc (original)
+++ branches/trac232/src/bin/auth/auth_srv.cc Mon Jul 5 15:59:02 2010
@@ -506,7 +506,6 @@
return isc::config::createAnswer(1, exc.what());
}
}
-
ElementPtr
AuthSrv::ixfr(isc::data::ElementPtr args)
{
@@ -530,7 +529,12 @@
//cout << "X: " << ss.str() << endl;
string s;
myfile >> s;
+ if (s == "") {
+ continue;
+ }
+ std::cout << "[XX] read name: '" << s << "'" << std::endl;
Name n(s);
+ std::cout << "[XX] name read " << std::endl;
myfile >> s;
RRTTL ttl(s);
myfile >> s;
@@ -542,15 +546,18 @@
while (line[0] == ' ' || line[0] == '\t') {
line.erase(0, 1);
}
- std::cout << "[XX] rdata: " << line << std::endl;
+ std::cout << "[XX] rdata line: " << line << std::endl;
RdataPtr rdata = createRdata(rrtype, rrclass, line);
- std::cout << "[XX] rdata read: " << line << std::endl;
+ std::cout << "[XX] rdata line read" << std::endl;
RRsetPtr rrset = RRsetPtr(new RRset(n,
rrclass,
rrtype,
ttl));
+ std::cout << "[XX] rrset created" << std::endl;
rrset->addRdata(rdata);
+ std::cout << "[XX] rdata added" << std::endl;
m.addRRset(Section::ANSWER(), rrset, false);
+ std::cout << "[XX] rrset added" << std::endl;
}
}
std::cout << "[XX] read IXFR 'message' file" << std::endl;
@@ -561,8 +568,15 @@
impl_->data_sources_.findClosestEnclosure(match, rrclass);
DataSrc* datasource = (DataSrc*) match.bestDataSrc();
if (datasource) {
- DataSrcTransaction* transaction = datasource->startTransaction(zone_name);
- DataSrc result = datasource->doIXFR(transaction, m.beginSection(Section::ANSWER());
+ DataSrcTransaction* transaction;
+ DataSrc::Result result = datasource->startTransaction(&transaction, zone_name);
+ if (result != DataSrc::SUCCESS) {
+ return isc::config::createAnswer(result, "error starting transaction");
+ }
+
+ result = datasource->doIXFR(transaction,
+ m.beginSection(Section::ANSWER()),
+ m.endSection(Section::ANSWER()));
if (result != DataSrc::SUCCESS) {
return isc::config::createAnswer(result, "Error in doIXFR");
} else {
Modified: branches/trac232/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/data_source.cc (original)
+++ branches/trac232/src/lib/datasrc/data_source.cc Mon Jul 5 15:59:02 2010
@@ -962,6 +962,15 @@
}
DataSrc::Result
+DataSrc::doIXFR(DataSrcTransaction* transaction UNUSED_PARAM,
+ const isc::dns::RRsetIterator start UNUSED_PARAM,
+ const isc::dns::RRsetIterator end UNUSED_PARAM)
+{
+ return NOT_IMPLEMENTED;
+}
+
+
+DataSrc::Result
MetaDataSrc::findRRset(const isc::dns::Name& qname UNUSED_PARAM,
const isc::dns::RRClass& qclass UNUSED_PARAM,
const isc::dns::RRType& qtype UNUSED_PARAM,
@@ -1064,6 +1073,5 @@
return NOT_IMPLEMENTED;
}
-
-}
-}
+}
+}
Modified: branches/trac232/src/lib/datasrc/data_source.h
==============================================================================
--- branches/trac232/src/lib/datasrc/data_source.h (original)
+++ branches/trac232/src/lib/datasrc/data_source.h Mon Jul 5 15:59:02 2010
@@ -29,6 +29,7 @@
#include <dns/rrclass.h>
#include <dns/rrset.h>
#include <cc/data.h>
+#include <dns/message.h>
namespace isc {
@@ -165,6 +166,7 @@
// TODO: probably needs private constructor, so that only startTransaction can make them
// also probably should keep a pointer to a datasource
// should this also provide the outwards interface?
+//
class DataSrcTransaction {
public:
virtual ~DataSrcTransaction() {};
@@ -238,12 +240,7 @@
//
// Writable data sources
//
- // This certainly not the final API, we probably want to
- // make transactions mandatory (even if start/end are nops),
- // by either creating a transaction context, or even a 'writable'
- // class that creates the transaction on init, and move al write
- // functions there. (keeping in mind that high-level write
- // functions also need read functionality)
+ // This certainly not the final API
virtual Result addRRset(DataSrcTransaction* transaction,
isc::dns::ConstRRsetPtr rrset);
virtual Result delRRset(DataSrcTransaction* transaction,
@@ -254,6 +251,9 @@
virtual Result startTransaction(DataSrcTransaction** transaction, const isc::dns::Name& zonename);
virtual Result commitTransaction(DataSrcTransaction *transaction);
virtual Result rollbackTransaction(DataSrcTransaction *transaction);
+ virtual Result doIXFR(DataSrcTransaction* transaction,
+ const isc::dns::RRsetIterator start,
+ const isc::dns::RRsetIterator end);
private:
isc::dns::RRClass rrclass;
Modified: branches/trac232/src/lib/datasrc/sqlite3_datasrc.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/sqlite3_datasrc.cc (original)
+++ branches/trac232/src/lib/datasrc/sqlite3_datasrc.cc Mon Jul 5 15:59:02 2010
@@ -1135,17 +1135,102 @@
return result;
}
-DataSrc::Result
-doIXFR(DataSrcTransaction* transaction,
- const RRsetIterator start,
- const RRsetIterator end)
-{
- (void)transaction;
- (void)start;
- (void)end;
- return DataSrc::SUCCESS;
-}
-
-
-}
-}
+static bool
+equalRRsets(const RRsetPtr& a, const RRsetPtr& b) {
+ std::string as = a->toText();
+ std::string bs = b->toText();
+ return (as == bs);
+}
+
+// should we have this as a convenience function in DataSrc?
+static bool
+haveRRset(const AbstractDataSrc *datasrc, const RRsetPtr rrset) {
+ RRsetList rrset_list;
+ DataSrc::Result result;
+ uint32_t flags = 0;
+
+ result = datasrc->findExactRRset(rrset->getName(), rrset->getClass(),
+ rrset->getType(), rrset_list, flags, NULL);
+ return ((result == DataSrc::SUCCESS) &&
+ (rrset_list.size() == 1) &&
+ equalRRsets(rrset, *(rrset_list.begin()))
+ );
+}
+
+// TODO: this is a very general one, move to DataSrc?
+// also more specific return values on error
+DataSrc::Result
+Sqlite3DataSrc::doIXFR(DataSrcTransaction* transaction,
+ const RRsetIterator start,
+ const RRsetIterator end)
+{
+ RRsetIterator rrsets = start;
+ RRsetPtr final_soa = *rrsets;
+ rrsets++;
+ RRsetPtr first_soa = *rrsets;
+ rrsets++;
+ if (first_soa->getType() == RRType::SOA()) {
+ if (!haveRRset(this, first_soa)) {
+ rollbackTransaction(transaction);
+ std::cout << "[XX] Start SOA does not match mine: " << first_soa->toText() << std::endl;
+ return DataSrc::ERROR;
+ }
+ } else {
+ // Not a SOA, then this must be an AXFR-type response
+ delAll(((Sqlite3DataSrcTransaction*)transaction)->zone_id);
+
+ while (rrsets != end) {
+ addRRset(transaction, *rrsets++);
+ }
+ commitTransaction(transaction);
+ return DataSrc::SUCCESS;
+ }
+ bool deleting = true;
+
+ std::cout << "[XX] final soa: " << final_soa->toText() << std::endl;
+ RRsetPtr cur_rrset;
+ while (rrsets != end) {
+ cur_rrset = *rrsets;
+ std::cout << "[XX] cur rrset: " << cur_rrset->toText() << std::endl;
+
+ // If we see a SOA, it means we are switching operations (either
+ // we start deleting or adding depending on what we were doing
+ // before.
+ // We don't delete the actual SOA itself,
+ if (cur_rrset->getType() == RRType::SOA()) {
+ // TODO: check if serial has increased compared to the last soa we saw
+ deleting = !deleting;
+ } else {
+ if (deleting) {
+ // check if rrset exists, if not, something is very wrong, abort
+ if (haveRRset(this, cur_rrset)) {
+ std::cout << "[XX] delete: " << cur_rrset->toText() << std::endl;
+ delRRset(transaction, cur_rrset);
+ } else {
+ std::cout << "[XX] rrset for delete not found: " << cur_rrset->toText() << std::endl;
+ rollbackTransaction(transaction);
+ return DataSrc::ERROR;
+ }
+ } else {
+ std::cout << "[XX] add: " << cur_rrset->toText() << std::endl;
+ addRRset(transaction, cur_rrset);
+ }
+ }
+ rrsets++;
+ }
+ if (equalRRsets(cur_rrset, final_soa)) {
+ // Finally replace the SOA
+ delRRset(transaction, first_soa);
+ addRRset(transaction, final_soa);
+ commitTransaction(transaction);
+ return DataSrc::SUCCESS;
+ } else {
+ std::cout << "[XX] something went wrong" << std::endl;
+ rollbackTransaction(transaction);
+ return DataSrc::ERROR;
+ }
+}
+
+
+}
+}
More information about the bind10-changes
mailing list