[svn] commit: r2544 - in /branches/trac232/src/lib/datasrc: data_source.cc data_source.h sqlite3_datasrc.cc sqlite3_datasrc.h

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jul 20 13:08:00 UTC 2010


Author: jelte
Date: Tue Jul 20 13:08:00 2010
New Revision: 2544

Log:
move doUpdate up to general data_source, as well as some common functionality.

Modified:
    branches/trac232/src/lib/datasrc/data_source.cc
    branches/trac232/src/lib/datasrc/data_source.h
    branches/trac232/src/lib/datasrc/sqlite3_datasrc.cc
    branches/trac232/src/lib/datasrc/sqlite3_datasrc.h

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 Tue Jul 20 13:08:00 2010
@@ -1338,6 +1338,124 @@
     }
 }
 
+isc::dns::Rcode
+DataSrc::updateCheckPrerequisite(DataSrcTransaction& transaction, RRsetPtr prereq)
+{
+    // section 3.2 of RFC2136
+    if (prereq->getClass() == RRClass::ANY()) {
+        if (prereq->getTTL().getValue() != 0 ||
+            prereq->getRdataCount() != 0) {
+            return (Rcode::FORMERR());
+        }
+        if (prereq->getType() == RRType::ANY()) {
+            if (!haveRRset(transaction, prereq)) {
+                return (Rcode::NXDOMAIN());
+            }
+        } else if (!haveRRset(transaction, prereq)) {
+            return (Rcode::NXRRSET());
+        }
+    } else if (prereq->getClass() == RRClass::NONE()) {
+        if (prereq->getTTL().getValue() != 0 ||
+            prereq->getRdataCount() != 0) {
+            return (Rcode::FORMERR());
+        }
+        if (prereq->getType() == RRType::ANY()) {
+            if (haveRRset(transaction, prereq)) {
+                return (Rcode::YXDOMAIN());
+            }
+        } else if (haveRRset(transaction, prereq)) {
+            return (Rcode::YXRRSET());
+        }
+    } else if (prereq->getClass() == transaction.getZoneClass()) {
+        if (prereq->getTTL().getValue() != 0) {
+            return (Rcode::FORMERR());
+        }
+        // 3.2.3 talks about rebuilding sets, but we already have full rrsets
+        if (!haveRRset(transaction, prereq)) {
+            return (Rcode::NXRRSET());
+        }
+    } else {
+        return (Rcode::FORMERR());
+    }
+    
+    return (Rcode::NOERROR());
+}
+
+Rcode
+DataSrc::updateProcessUpdate(DataSrcTransaction& transaction,
+                                    isc::dns::RRsetPtr update)
+{
+    // The RFC says to pre-scan them, but since we use a transaction
+    // we can roll back, we can process the RRsets one at a time
+
+    // TODO, NOTZONE check
+    
+    RRType update_type = update->getType();
+    if (update->getClass() != RRClass::ANY()) {
+        // do we have a direct check in rrtype to see if a specific
+        // type is known and not a meta type?
+        if (update_type == RRType::ANY() ||
+            update_type == RRType::IXFR() ||
+            update_type == RRType::AXFR()) {
+            return (Rcode::FORMERR());
+        }
+    } else if (update->getClass() == RRClass::ANY()) {
+        if (update->getTTL().getValue() != 0) {
+            return (Rcode::FORMERR());
+        }
+        if (update_type == RRType::IXFR() ||
+            update_type == RRType::AXFR()) {
+            return (Rcode::FORMERR());
+        }
+        if (update->getRdataCount() > 0) {
+            return (Rcode::FORMERR());
+        }
+    } else if (update->getClass() == RRClass::NONE()) {
+        if (update->getTTL().getValue() != 0) {
+            return (Rcode::FORMERR());
+        }
+    }
+
+    // Most types are blindly added, but some require special handling
+    if (update_type == RRType::SOA()) {
+        // check serial and delete old
+        RRsetList soa_list;
+        uint32_t flags = 0;
+        if (findExactRRset(update->getName(),
+                           update->getClass(),
+                           update_type,
+                           soa_list,
+                           flags,
+                           NULL) != SUCCESS ||
+            soa_list.size() != 1) {
+            return (Rcode::SERVFAIL());
+        } else {
+            // TODO: no serial arithmetic yet?
+            if (delRRset(transaction, *(soa_list.begin())) != SUCCESS) {
+                return (Rcode::SERVFAIL());
+            }
+            if (addRRset(transaction, update) != SUCCESS) {
+                return (Rcode::SERVFAIL());
+            }
+        }
+    // which other types need special handling? CNAME, WKS,...
+    // addRRset and delRRset should do 'the right thing' regarding
+    // types (any/none/specific) and rdata count
+    } else {
+        if (update->getClass() == RRClass::ANY() ||
+            update->getClass() == RRClass::NONE()) {
+            if (delRRset(transaction, update) != SUCCESS) {
+                return (Rcode::SERVFAIL());
+            }
+        } else {
+            if (addRRset(transaction, update) != SUCCESS) {
+                return (Rcode::SERVFAIL());
+            }
+        }
+    }
+    return (Rcode::NOERROR());
+}
+
 DataSrc::Result
 DataSrc::doIXFR(DataSrcTransaction& transaction UNUSED_PARAM,
                 const isc::dns::RRsetIterator start UNUSED_PARAM,
@@ -1413,6 +1531,57 @@
     return (NOT_IMPLEMENTED);
 }
 
+DataSrc::Result
+DataSrc::doUpdate(DataSrcTransaction& transaction UNUSED_PARAM,
+                         isc::dns::Message& msg UNUSED_PARAM) {
+    if (msg.getOpcode() != isc::dns::Opcode::UPDATE()) {
+        return ERROR;
+    }
+
+    // hmz, zone already in transaction. should we do transaction here?
+    // (and not as an argument) for now, simply check it
+    if (msg.getRRCount(isc::dns::Section::QUESTION()) != 1) {
+        return ERROR;
+    }
+    QuestionPtr question = *(msg.beginQuestion());
+    if (question->getName() != transaction.getZoneName()) {
+        return ERROR;
+    }
+    if (question->getType() != isc::dns::RRType::SOA()) {
+        return ERROR;
+    }
+    if (question->getClass() != transaction.getZoneClass()) {
+        return ERROR;
+    }
+
+    // check the prerequisites
+    RRsetIterator it;
+    for (it = msg.beginSection(isc::dns::Section::ANSWER());
+         it != msg.endSection(isc::dns::Section::ANSWER());
+         it++) {
+        RRsetPtr cur_prereq = *it;
+        isc::dns::Rcode prereq_result = updateCheckPrerequisite(transaction, cur_prereq);
+        if (prereq_result != Rcode::NOERROR()) {
+            msg.clear(Message::RENDER);
+            msg.setRcode(prereq_result);
+            return ERROR;
+        }
+    }
+
+    for (it = msg.beginSection(isc::dns::Section::AUTHORITY());
+         it != msg.endSection(isc::dns::Section::AUTHORITY());
+         it++) {
+        RRsetPtr cur_update = *it;
+        Rcode result = updateProcessUpdate(transaction, cur_update);
+        if (result != Rcode::NOERROR()) {
+            return ERROR;
+        }
+    }
+
+    // do we need to do anything with additional?
+    
+    return SUCCESS;
+}
 
 DataSrc::Result
 MetaDataSrc::findRRset(const isc::dns::Name& qname UNUSED_PARAM,

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 Tue Jul 20 13:08:00 2010
@@ -267,7 +267,10 @@
     //
     // Writable data sources
     //
-    // This certainly not the final API
+    // This not the final API
+
+    // For datasource that support writing, overwrite these
+    // methods. By default they will return NOT_IMPLEMENTED.
     virtual Result addRRset(DataSrcTransaction&  transaction,
                             isc::dns::ConstRRsetPtr rrset);
     virtual Result delRRset(DataSrcTransaction&  transaction,
@@ -275,14 +278,28 @@
     virtual Result delZone(DataSrcTransaction&  transaction);
     virtual Result replaceZone(DataSrcTransaction&  transaction,
                                const isc::dns::RRsetList& rrsets);
+
+    // The following methods are used by the 'high-level' ones below
+    //
+    // You can overwrite these functions if there is a specific reason
+    // In principle this should not be necessary
     virtual bool haveRRset(DataSrcTransaction& transaction,
                            isc::dns::ConstRRsetPtr rrset);
+    virtual isc::dns::Rcode updateCheckPrerequisite(DataSrcTransaction& transaction,
+                                            isc::dns::RRsetPtr prereq);
+    virtual isc::dns::Rcode updateProcessUpdate(DataSrcTransaction& transaction,
+                                        isc::dns::RRsetPtr update);
+
+    // General High-level functions. If your data source can make use
+    // of backend-specific shortcuts, you can overwrite these methods
     virtual Result startTransaction(DataSrcTransaction&  transaction);
     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);
+    virtual Result doUpdate(DataSrcTransaction& transaction,
+                            isc::dns::Message& msg);
 
 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 Tue Jul 20 13:08:00 2010
@@ -1141,7 +1141,6 @@
     }
 }
 
-
 DataSrc::Result
 Sqlite3DataSrc::delRRset(DataSrcTransaction& transaction,
                          isc::dns::ConstRRsetPtr rrset)
@@ -1176,182 +1175,5 @@
     return result;
 }
 
-isc::dns::Rcode
-Sqlite3DataSrc::updateCheckPrerequisite(DataSrcTransaction& transaction, RRsetPtr prereq)
-{
-    std::cout << "[XX] PREREQ: " << prereq->toText() << std::endl;
-    // section 3.2 of RFC2136
-    if (prereq->getClass() == RRClass::ANY()) {
-        if (prereq->getTTL().getValue() != 0 ||
-            prereq->getRdataCount() != 0) {
-            return Rcode::FORMERR();
-        }
-        if (prereq->getType() == RRType::ANY()) {
-            if (!haveRRset(transaction, prereq)) {
-                return Rcode::NXDOMAIN();
-            }
-        } else if (!haveRRset(transaction, prereq)) {
-            return Rcode::NXRRSET();
-        }
-    } else if (prereq->getClass() == RRClass::NONE()) {
-        if (prereq->getTTL().getValue() != 0 ||
-            prereq->getRdataCount() != 0) {
-            return Rcode::FORMERR();
-        }
-        if (prereq->getType() == RRType::ANY()) {
-            if (haveRRset(transaction, prereq)) {
-                return Rcode::YXDOMAIN();
-            }
-        } else if (haveRRset(transaction, prereq)) {
-            return Rcode::YXRRSET();
-        }
-    } else if (prereq->getClass() == transaction.getZoneClass()) {
-        if (prereq->getTTL().getValue() != 0) {
-            return Rcode::FORMERR();
-        }
-        // 3.2.3 talks about rebuilding sets, but we already have full rrsets
-        if (!haveRRset(transaction, prereq)) {
-            return Rcode::NXRRSET();
-        }
-    } else {
-        return Rcode::FORMERR();
-    }
-    
-    return Rcode::NOERROR();
-}
-
-Rcode
-Sqlite3DataSrc::updateProcessUpdate(DataSrcTransaction& transaction,
-                                    isc::dns::RRsetPtr update)
-{
-    // The RFC says to pre-scan them, but since we use a transaction
-    // we can roll back, we can process the RRsets one at a time
-
-    // TODO, NOTZONE check
-    
-    RRType update_type = update->getType();
-    if (update->getClass() != RRClass::ANY()) {
-        // do we have a direct check in rrtype to see if a specific
-        // type is known and not a meta type?
-        if (update_type == RRType::ANY() ||
-            update_type == RRType::IXFR() ||
-            update_type == RRType::AXFR()) {
-            return Rcode::FORMERR();
-        }
-    } else if (update->getClass() == RRClass::ANY()) {
-        if (update->getTTL().getValue() != 0) {
-            return Rcode::FORMERR();
-        }
-        if (update_type == RRType::IXFR() ||
-            update_type == RRType::AXFR()) {
-            return Rcode::FORMERR();
-        }
-        if (update->getRdataCount() > 0) {
-            return Rcode::FORMERR();
-        }
-    } else if (update->getClass() == RRClass::NONE()) {
-        if (update->getTTL().getValue() != 0) {
-            return Rcode::FORMERR();
-        }
-    }
-
-    // Most types are blindly added, but some require special handling
-    if (update_type == RRType::SOA()) {
-        // check serial and delete old
-        RRsetList soa_list;
-        uint32_t flags = 0;
-        if (findExactRRset(update->getName(),
-                           update->getClass(),
-                           update_type,
-                           soa_list,
-                           flags,
-                           NULL) != SUCCESS ||
-            soa_list.size() != 1) {
-            return Rcode::SERVFAIL();
-        } else {
-            // TODO: no serial arithmetic yet?
-            if (delRRset(transaction, *(soa_list.begin())) != SUCCESS) {
-                return Rcode::SERVFAIL();
-            }
-            if (addRRset(transaction, update) != SUCCESS) {
-                return Rcode::SERVFAIL();
-            }
-        }
-    // which other types need special handling? CNAME, WKS,...
-    // addRRset and delRRset should do 'the right thing' regarding
-    // types (any/none/specific) and rdata count
-    } else {
-        if (update->getClass() == RRClass::ANY() ||
-            update->getClass() == RRClass::NONE()) {
-            if (delRRset(transaction, update) != SUCCESS) {
-                return Rcode::SERVFAIL();
-            }
-        } else {
-            if (addRRset(transaction, update) != SUCCESS) {
-                return Rcode::SERVFAIL();
-            }
-        }
-    }
-    return Rcode::NOERROR();
-}
-
-DataSrc::Result
-Sqlite3DataSrc::doUpdate(DataSrcTransaction& transaction UNUSED_PARAM,
-                         isc::dns::Message& msg UNUSED_PARAM) {
-    if (msg.getOpcode() != isc::dns::Opcode::UPDATE()) {
-        return ERROR;
-    }
-
-    std::cout << "[XX] doUpdate(), message: " << std::endl;
-    std::cout << msg.toText() << std::endl;
-
-    // hmz, zone already in transaction. should we do transaction here?
-    // (and not as an argument) for now, simply check it
-    if (msg.getRRCount(isc::dns::Section::QUESTION()) != 1) {
-        return ERROR;
-    }
-    QuestionPtr question = *(msg.beginQuestion());
-    if (question->getName() != transaction.getZoneName()) {
-        return ERROR;
-    }
-    if (question->getType() != isc::dns::RRType::SOA()) {
-        return ERROR;
-    }
-    if (question->getClass() != transaction.getZoneClass()) {
-        return ERROR;
-    }
-
-    // check the prerequisites
-    RRsetIterator it;
-    for (it = msg.beginSection(isc::dns::Section::ANSWER());
-         it != msg.endSection(isc::dns::Section::ANSWER());
-         it++) {
-        RRsetPtr cur_prereq = *it;
-        isc::dns::Rcode prereq_result = updateCheckPrerequisite(transaction, cur_prereq);
-        cout << "[XX] PREREQ RCODE: " << prereq_result.toText() << endl;
-        if (prereq_result != Rcode::NOERROR()) {
-            msg.clear(Message::RENDER);
-            msg.setRcode(prereq_result);
-            return ERROR;
-        }
-    }
-
-    for (it = msg.beginSection(isc::dns::Section::AUTHORITY());
-         it != msg.endSection(isc::dns::Section::AUTHORITY());
-         it++) {
-        RRsetPtr cur_update = *it;
-        std::cout << "[XX] Update RR: " << cur_update->toText() << std::endl;
-        Rcode result = updateProcessUpdate(transaction, cur_update);
-        if (result != Rcode::NOERROR()) {
-            return ERROR;
-        }
-    }
-
-    // do we need to do anything with additional?
-    
-    return SUCCESS;
-}
-
-
-}
-}
+}
+}

Modified: branches/trac232/src/lib/datasrc/sqlite3_datasrc.h
==============================================================================
--- branches/trac232/src/lib/datasrc/sqlite3_datasrc.h (original)
+++ branches/trac232/src/lib/datasrc/sqlite3_datasrc.h Tue Jul 20 13:08:00 2010
@@ -121,13 +121,6 @@
     DataSrc::Result replaceZone(DataSrcTransaction& transaction,
                                 const isc::dns::RRsetList& rrset_list);
     DataSrc::Result delZone(DataSrcTransaction& transaction);
-/*
-    DataSrc::Result doIXFR(DataSrcTransaction& transaction,
-                           const isc::dns::RRsetIterator start,
-                           const isc::dns::RRsetIterator end);
-*/
-    DataSrc::Result doUpdate(DataSrcTransaction& transaction,
-                             isc::dns::Message& msg);
 
 private:
     DataSrc::Result addRR(int zone_id,
@@ -143,10 +136,6 @@
                           const isc::dns::RRType& rrtype,
                           const isc::dns::rdata::Rdata& rdata);
     DataSrc::Result delAll(int zone_id);
-    isc::dns::Rcode updateCheckPrerequisite(DataSrcTransaction& transaction,
-                                            isc::dns::RRsetPtr prereq);
-    isc::dns::Rcode updateProcessUpdate(DataSrcTransaction& transaction,
-                                        isc::dns::RRsetPtr update);
 
 private:
     enum Mode {




More information about the bind10-changes mailing list