[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