[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