[svn] commit: r3206 - in /branches/trac232/src/lib/datasrc: data_source.cc data_source.h tests/sqlite3_unittest.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Oct 14 09:35:00 UTC 2010
Author: jelte
Date: Thu Oct 14 09:34:59 2010
New Revision: 3206
Log:
added function based rrset generator for ixfr too
Modified:
branches/trac232/src/lib/datasrc/data_source.cc
branches/trac232/src/lib/datasrc/data_source.h
branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc
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 Thu Oct 14 09:34:59 2010
@@ -1549,6 +1549,83 @@
}
DataSrc::Result
+DataSrc::doIXFR(DataSrcTransaction& transaction UNUSED_PARAM,
+ isc::dns::RRsetPtr nextRRset(void*, void*),
+ void* arg1, void* arg2)
+{
+ if (transaction.getState() != DataSrcTransaction::RUNNING) {
+ std::cout << "[XX] 1" << std::endl;
+ return (DataSrc::ERROR);
+ }
+
+ RRsetPtr final_soa = nextRRset(arg1, arg2);
+ if (!final_soa) {
+ std::cout << "[XX] 2" << std::endl;
+ return (DataSrc::ERROR);
+ }
+ RRsetPtr first_soa = nextRRset(arg1, arg2);
+ if (!final_soa) {
+ std::cout << "[XX] 3" << std::endl;
+ return (DataSrc::ERROR);
+ }
+
+ RRsetPtr next_rrset, last_rrset;
+
+ if (first_soa->getType() == RRType::SOA()) {
+ if (!haveRRset(transaction, first_soa)) {
+ std::cout << "[XX] 4" << std::endl;
+ return (DataSrc::ERROR);
+ }
+ } else {
+ // Not a SOA, then this must be an AXFR-type response
+ RRsetContainer empty;
+ replaceZone(transaction, empty);
+
+ while (next_rrset = nextRRset(arg1, arg2)) {
+ addRRset(transaction, next_rrset);
+ }
+ return (DataSrc::SUCCESS);
+ }
+ bool deleting = true;
+
+ while (next_rrset = nextRRset(arg1, arg2)) {
+
+ // 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 (next_rrset->getType() == RRType::SOA()) {
+ // TODO: check if serial has increased compared to the last soa we saw
+ deleting = !deleting;
+ last_rrset = next_rrset;
+ } else {
+ if (deleting) {
+ // check if rrset exists, if not, something is very wrong, abort
+ if (haveRRset(transaction, next_rrset)) {
+ delRRset(transaction, next_rrset);
+ } else {
+ std::cout << "[XX] 6" << std::endl;
+ return (DataSrc::ERROR);
+ }
+ } else {
+ addRRset(transaction, next_rrset);
+ }
+ }
+ }
+ if (equalRRsets(last_rrset, final_soa)) {
+ // Finally replace the SOA
+ delRRset(transaction, first_soa);
+ addRRset(transaction, final_soa);
+ return (DataSrc::SUCCESS);
+ } else {
+ std::cout << "[XX] yup" << std::endl;
+ return (DataSrc::ERROR);
+ }
+ return (NOT_IMPLEMENTED);
+}
+
+
+DataSrc::Result
DataSrc::doUpdate(DataSrcTransaction& transaction UNUSED_PARAM,
isc::dns::Message& msg UNUSED_PARAM) {
if (msg.getOpcode() != isc::dns::Opcode::UPDATE()) {
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 Thu Oct 14 09:34:59 2010
@@ -495,6 +495,22 @@
const isc::dns::RRsetIterator start,
const isc::dns::RRsetIterator end);
+ /// \brief Perform an IXFR operation with data provided by the
+ /// given function.
+ /// The given function should return one RRset at a time, which
+ /// are processed as described in RFC1995
+ /// \param transaction the transaction to perform the operation in
+ /// \param nextRRset Function that returns the next RRsetPtr on
+ /// each call to it
+ /// \param arg1 This will be passed as the first argument to the
+ /// nextRRset function (defaults to NULL)
+ /// \param arg2 This will be passed as the second argument to the
+ /// nextRRset function (defaults to NULL)
+ /// \return SUCCESS on success, ERROR on failure.
+ virtual Result doIXFR(DataSrcTransaction& transaction,
+ isc::dns::RRsetPtr nextRRset(void*, void*),
+ void* arg1 = NULL, void* arg2 = NULL);
+
/// \brief Perform a DNS Dynamic update as desribed in RFC2136
/// \param transaction the transaction to perform the udpate in
/// \param msg the DNS UPDATE msg to handle
Modified: branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc (original)
+++ branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc Thu Oct 14 09:34:59 2010
@@ -1211,10 +1211,15 @@
size_t* i = reinterpret_cast<size_t*>(arg2);
std::cout << "[XX] getRRsetCallback_vector() called" << std::endl;
std::cout << "[XX] i: " << *i << std::endl;
+ std::cout << "[XX] s: " << v->size() << std::endl;
if (*i < v->size()) {
- return ((*v)[(*i)++]);
+ //return ((*v)[(*i)++]);
+ RRsetPtr result = ((*v)[(*i)++]);
+ std::cout << "Returning: " << result->toText() << std::endl;
+ return result;
} else {
+ std::cout << "Nothing in vector, returning empty Ptr" << std::endl;
return (RRsetPtr());
}
}
@@ -1450,6 +1455,53 @@
return 0;
}
+int
+rrsetsFromFile(ifstream& file, std::vector<RRsetPtr>& container)
+{
+ RRsetPtr prev_rrset = RRsetPtr();
+ while (! file.eof() ) {
+ RRsetPtr rrset = rrsetFromFile(file);
+ if (!rrset) {
+ if (prev_rrset) {
+ container.push_back(prev_rrset);
+ }
+ return 1;
+ }
+ if (prev_rrset) {
+ if (rrset) {
+ if (prev_rrset->getName() == rrset->getName() &&
+ prev_rrset->getType() == rrset->getType() &&
+ prev_rrset->getType() != RRType::SOA() &&
+ prev_rrset->getClass() == rrset->getClass()) {
+ RdataIteratorPtr it = rrset->getRdataIterator();
+ for (it->first(); !it->isLast(); it->next()) {
+ prev_rrset->addRdata(it->getCurrent());
+ }
+ rrset = RRsetPtr();
+ }
+ }
+ container.push_back(prev_rrset);
+ prev_rrset = rrset;
+ } else {
+ prev_rrset = rrset;
+ }
+ }
+ return 0;
+}
+
+int
+rrsetsFromFile(const char* file_name, std::vector<RRsetPtr>& container)
+{
+ ifstream myfile(file_name);
+ if (myfile.is_open()) {
+ rrsetsFromFile(myfile, container);
+ myfile.close();
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
static int
ixfrFromFile(Message& m, const char* file_name) {
ifstream myfile(file_name);
@@ -1461,6 +1513,7 @@
m.setRcode(isc::dns::Rcode::NOERROR());
if (myfile.is_open()) {
rrsetsFromFile(myfile, m, Section::ANSWER());
+ myfile.close();
} else {
return -1;
}
@@ -1535,7 +1588,7 @@
}
}
-TEST_F(Sqlite3DataSourceTest, ixfr_ok) {
+TEST_F(Sqlite3DataSourceTest, ixfr_ok_message) {
// reset database
ASSERT_EQ(0, install_writable_database());
@@ -1585,6 +1638,60 @@
data_source.doIXFR(transaction3,
ixfr_msg.beginSection(Section::ANSWER()),
ixfr_msg.endSection(Section::ANSWER()))
+ );
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.rollbackTransaction(transaction3));
+}
+
+TEST_F(Sqlite3DataSourceTest, ixfr_ok_function) {
+ // reset database
+ ASSERT_EQ(0, install_writable_database());
+
+ // use our copied writable datasource db
+ ASSERT_EQ(DataSrc::SUCCESS, data_source.close());
+ ASSERT_EQ(DataSrc::SUCCESS, data_source.init(SQLITE_DBFILE_WRITE));
+
+ checkSingleRRset(data_source,
+ "www.example.com. 3600 IN A 192.0.2.1\n",
+ www_name, RRClass::IN(), RRType::A());
+
+ std::vector<RRsetPtr> rrsets;
+ ASSERT_EQ(0, rrsetsFromFile(TEST_DATA_DIR "/ixfr_ok.rrs", rrsets));
+
+ // do IXFR, roll back
+ size_t i = 0;
+ DataSrcTransaction transaction1(&data_source, zone_name, RRClass::IN());
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.startTransaction(transaction1));
+ ASSERT_EQ(DataSrc::SUCCESS,
+ data_source.doIXFR(transaction1,
+ getRRsetCallback_vector, &rrsets, &i)
+ );
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.rollbackTransaction(transaction1));
+
+ checkSingleRRset(data_source,
+ "www.example.com. 3600 IN A 192.0.2.1\n",
+ www_name, RRClass::IN(), RRType::A());
+
+ // do IXFR, commit
+ i = 0;
+ DataSrcTransaction transaction2(&data_source, zone_name, RRClass::IN());
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.startTransaction(transaction2));
+ ASSERT_EQ(DataSrc::SUCCESS,
+ data_source.doIXFR(transaction2,
+ getRRsetCallback_vector, &rrsets, &i)
+ );
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.commitTransaction(transaction2));
+
+ checkSingleRRset(data_source,
+ "www.example.com. 3600 IN A 192.0.2.3\n",
+ www_name, RRClass::IN(), RRType::A());
+
+ // same IXFR should now fail, because the start serial doesn't match
+ i = 0;
+ DataSrcTransaction transaction3(&data_source, zone_name, RRClass::IN());
+ ASSERT_EQ(DataSrc::W_SUCCESS, data_source.startTransaction(transaction3));
+ ASSERT_EQ(DataSrc::ERROR,
+ data_source.doIXFR(transaction3,
+ getRRsetCallback_vector, &rrsets, &i)
);
ASSERT_EQ(DataSrc::W_SUCCESS, data_source.rollbackTransaction(transaction3));
}
More information about the bind10-changes
mailing list