[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