[svn] commit: r469 - in /branches/jelte-datasource1/src: bin/parkinglot/data_source_plot.cc bin/parkinglot/data_source_plot.h bin/parkinglot/parkinglot.cc lib/dns/data_source.cc lib/dns/data_source.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Mon Jan 18 11:45:33 UTC 2010
Author: jelte
Date: Mon Jan 18 11:45:32 2010
New Revision: 469
Log:
datasource updates, add zone concept (with temporary(?) getZoneFor()), removed old code
Modified:
branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.cc
branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.h
branches/jelte-datasource1/src/bin/parkinglot/parkinglot.cc
branches/jelte-datasource1/src/lib/dns/data_source.cc
branches/jelte-datasource1/src/lib/dns/data_source.h
Modified: branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.cc
==============================================================================
--- branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.cc (original)
+++ branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.cc Mon Jan 18 11:45:32 2010
@@ -57,65 +57,113 @@
1, 1800, 900, 604800, TTL(86400)));
}
-isc::dns::DataSource::result
-DataSourceParkingLot:: findRRset(isc::dns::RRsetPtr& target, isc::dns::Name name,
- isc::dns::RRClass clas, isc::dns::RRType type) {
+bool
+DataSourceParkingLot::hasZoneFor(const Name& name, Name &zone_name)
+{
+ if (zones.contains(name.toText(true))) {
+ zone_name = Name(name);
+ return true;
+ } else {
+ /* try 1 level higher? i.e. www.asdf.nl? */
+ return false;
+ }
+}
+
+SearchResult
+DataSourceParkingLot:: findRRsets(const isc::dns::Name& zone_name,
+ const isc::dns::Name& name,
+ const isc::dns::RRClass& clas,
+ const isc::dns::RRType& type) {
+ SearchResult result;
Name authors_name("authors.bind");
Name version_name("version.bind");
-
+
std::cout << "findRRset()" << std::endl;
if (clas == RRClass::CH) {
if (type == RRType::TXT) {
if (name == authors_name) {
- target->addRdata(Rdata::RdataPtr(TXT("JINMEI Tatuya").copy()));
+ RRsetPtr rrset = RRsetPtr(new RRset(authors_name, RRClass::CH, RRType::TXT, TTL(3600)));
+ rrset->addRdata(Rdata::RdataPtr(TXT("JINMEI Tatuya").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Han Feng").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Kazunori Fujiwara").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Michael Graff").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Evan Hunt").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Jelte Jansen").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Jin Jian").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("JINMEI Tatuya").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Naoki Kambe").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Shane Kerr").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Zhang Likun").copy()));
+ rrset->addRdata(Rdata::RdataPtr(TXT("Jeremy C. Reed").copy()));
+
+ result.addRRset(rrset);
+ result.setStatus(SearchResult::success);
} else if (name == version_name) {
- target->addRdata(Rdata::RdataPtr(TXT("BIND10 0.0.1").copy()));
+ RRsetPtr rrset = RRsetPtr(new RRset(version_name, RRClass::CH, RRType::TXT, TTL(3600)));
+ rrset->addRdata(Rdata::RdataPtr(TXT("BIND10 0.0.1").copy()));
+ result.addRRset(rrset);
+ result.setStatus(SearchResult::success);
} else {
std::cout << "ch txt but unknown name" << std::endl;
- return DataSource::name_not_found;
+ result.setStatus(SearchResult::name_not_found);
}
- return DataSource::success;
} else {
- std::cout << "ch but not txt" << std::endl;
- return DataSource::name_not_found;
+ result.setStatus(SearchResult::name_not_found);
}
} else if (clas == RRClass::IN) {
// make zoneset contain Name instead of string?
std::cout << "Finding zone for " << name.toText() << std::endl;
if (zones.contains(name.toText(true))) {
+ RRsetPtr rrset = RRsetPtr(new RRset(name, clas, type, TTL(3600)));
+ result.setStatus(SearchResult::success);
if (type == RRType::A) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr a, a_records) {
- target->addRdata(a);
+ rrset->addRdata(a);
}
} else if (type == RRType::AAAA) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr aaaa, aaaa_records) {
- target->addRdata(aaaa);
+ rrset->addRdata(aaaa);
}
} else if (type == RRType::NS) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr ns, ns_records) {
- target->addRdata(ns);
+ rrset->addRdata(ns);
}
} else if (type == RRType::SOA) {
- target->addRdata(soa);
- } else {
- std::cout << "type not supported" << std::endl;
- return name_not_found;
+ rrset->addRdata(soa);
}
- std::cout << "rrset: " << target->toText() << std::endl;
-
- std::cout << "success" << std::endl;
- return success;
+ result.addRRset(rrset);
} else {
std::cout << "zone not in zoneset" << std::endl;
- return DataSource::zone_not_found;
+ result.setStatus(SearchResult::zone_not_found);
}
} else {
std::cout << "not ch or in" << std::endl;
- return DataSource::zone_not_found;
+ result.setStatus(SearchResult::zone_not_found);
}
- // no match at all, error?
- return DataSource::error;
+ return result;
}
+
+/// Do direct 'search' in database, no extra processing,
+/// and add the resulting rrsets to the specified section
+/// in the given message
+/// returns the status code of the searchresult
+/// Once the dns logic is moved from parkinglot to this class,
+/// we should probably make this private
+SearchResult::status_type
+DataSourceParkingLot::addToMessage(Message& msg,
+ section_t section,
+ const Name& zone_name,
+ const Name& name,
+ const isc::dns::RRClass& clas,
+ const isc::dns::RRType& type)
+{
+ SearchResult result = findRRsets(zone_name, name, clas, type);
+ BOOST_FOREACH(RRsetPtr rrset, result) {
+ msg.addRRset(section, rrset);
+ }
+ return result.getStatus();
+}
+
}
}
Modified: branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.h
==============================================================================
--- branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.h (original)
+++ branches/jelte-datasource1/src/bin/parkinglot/data_source_plot.h Mon Jan 18 11:45:32 2010
@@ -41,15 +41,16 @@
void init() {};
void close() {};
- result findRRset(isc::dns::RRsetPtr& target, isc::dns::Name name,
- isc::dns::RRClass clas, isc::dns::RRType type);
-
+ bool hasZoneFor(const Name& name, Name &zone_name);
+ SearchResult findRRsets(const isc::dns::Name& zone_name,
+ const isc::dns::Name& name,
+ const isc::dns::RRClass& clas,
+ const isc::dns::RRType& type);
/* move these to private (or to zoneset) and the calling functions
* from parkinglot to here? */
void serve(std::string zone_name);
void clear_zones() { zones.clear_zones(); };
- bool has_zone(const std::string& zone_name) { return zones.contains(zone_name); };
void clearARecords() { a_records.clear(); };
void clearAAAARecords() { aaaa_records.clear(); };
@@ -61,6 +62,17 @@
void setSOARecord(isc::dns::Rdata::RdataPtr soa_record);
+ /// Do direct 'search' in database, no extra processing,
+ /// and add the resulting rrsets to the specified section
+ /// in the given message
+ /// Once the dns logic is moved from parkinglot to this class,
+ /// we should probably make this private
+ SearchResult::status_type addToMessage(Message& msg,
+ section_t section,
+ const Name& zone_name,
+ const Name& name,
+ const isc::dns::RRClass& clas,
+ const isc::dns::RRType& type);
private:
//
Modified: branches/jelte-datasource1/src/bin/parkinglot/parkinglot.cc
==============================================================================
--- branches/jelte-datasource1/src/bin/parkinglot/parkinglot.cc (original)
+++ branches/jelte-datasource1/src/bin/parkinglot/parkinglot.cc Mon Jan 18 11:45:32 2010
@@ -96,176 +96,60 @@
RRsetPtr query = msg.getSection(SECTION_QUESTION)[0];
- DataSource::result result;
-
msg.makeResponse();
msg.setAA(true);
TTL default_ttl = TTL(3600);
- // ok this part of the api needs improvenemt
- RRset *rrset = new RRset(query->getName(), query->getClass(), query->getType(), default_ttl);
- RRsetPtr answer = RRsetPtr(rrset);
- RRset *ns_rrset = new RRset(query->getName(), query->getClass(), RRType::NS, default_ttl);
- RRsetPtr ns_answer = RRsetPtr(ns_rrset);
- RRset *soa_rrset = new RRset(query->getName(), query->getClass(), RRType::SOA, default_ttl);
- RRsetPtr soa_answer = RRsetPtr(soa_rrset);
-
- result = data_source.findRRset(answer, query->getName(), query->getClass(), query->getType());
- switch (result) {
- case DataSource::success:
- msg.addRRset(SECTION_ANSWER, answer);
- if (data_source.findRRset(ns_answer, query->getName(), query->getClass(), RRType::NS) == DataSource::success) {
- msg.addRRset(SECTION_AUTHORITY, ns_answer);
+ Name zname;
+ Name name = query->getName();
+ RRClass qclass = query->getClass();
+ RRType qtype = query->getType();
+ SearchResult::status_type status;
+ bool included_ns = false;
+ if (data_source.hasZoneFor(query->getName(), zname)) {
+ status = data_source.addToMessage(msg, SECTION_ANSWER, zname, name, qclass, qtype);
+ // rcode is based on this result?
+ if (status == SearchResult::name_not_found) {
+ if (qtype != RRType::NS) {
+ status = data_source.addToMessage(msg, SECTION_AUTHORITY, zname, zname, qclass, RRType::SOA);
+ }
+ } else {
+ if (qtype != RRType::NS) {
+ status = data_source.addToMessage(msg, SECTION_AUTHORITY, zname, zname, qclass, RRType::NS);
+ }
+ included_ns = true;
}
- break;
- case DataSource::zone_not_found:
- msg.setRcode(Message::RCODE_NXDOMAIN);
- break;
- case DataSource::name_not_found:
- if (data_source.findRRset(soa_answer, query->getName(), query->getClass(), RRType::SOA) == DataSource::success) {
- msg.addRRset(SECTION_AUTHORITY, soa_answer);
+ // If we included NS records, and their target falls below the zone, add glue
+ if (included_ns) {
+ BOOST_FOREACH(RRsetPtr rrset, msg.getSection(SECTION_ANSWER)) {
+ if (rrset->getType() == RRType::NS) {
+ BOOST_FOREACH(Rdata::RdataPtr rdata, rrset->getRdatalist()) {
+ /* no direct way to get the Name from the rdata fields? */
+ Name ns_name = Name(rdata->toText());
+ data_source.addToMessage(msg, SECTION_ADDITIONAL, zname, ns_name, qclass, RRType::A);
+ data_source.addToMessage(msg, SECTION_ADDITIONAL, zname, ns_name, qclass, RRType::AAAA);
+ }
+ }
+ }
+ BOOST_FOREACH(RRsetPtr rrset, msg.getSection(SECTION_AUTHORITY)) {
+ if (rrset->getType() == RRType::NS) {
+ BOOST_FOREACH(Rdata::RdataPtr rdata, rrset->getRdatalist()) {
+ /* no direct way to get the Name from the rdata fields? */
+ Name ns_name = Name(rdata->toText());
+ data_source.addToMessage(msg, SECTION_ADDITIONAL, zname, ns_name, qclass, RRType::A);
+ data_source.addToMessage(msg, SECTION_ADDITIONAL, zname, ns_name, qclass, RRType::AAAA);
+ }
+ }
+ }
}
- break;
+ } else {
+ msg.setRcode(Message::RCODE_SERVFAIL);
}
msg.toWire();
cout << "sending a response (" <<
boost::lexical_cast<string>(msg.getBuffer().getSize())
<< " bytes):\n" << msg.toText() << endl;
msg.getBuffer().sendTo(s, *sa, sa_len);
- }
-/*
- Name authors_name("authors.bind");
- Name version_name("version.bind");
- struct sockaddr_storage ss;
- socklen_t sa_len = sizeof(ss);
- struct sockaddr* sa = static_cast<struct sockaddr*>((void*)&ss);
- int s = sock;
- Message msg;
-
- if (msg.getBuffer().recvFrom(s, sa, &sa_len) > 0) {
- try {
- msg.fromWire();
- } catch (...) {
- cerr << "parse failed" << endl;
- return;
- }
-
- cout << "received a message:\n" << msg.toText() << endl;
-
- if (msg.getSection(SECTION_QUESTION).size() != 1)
- return;
-
- msg.makeResponse();
- msg.setAA(true);
-
- RRsetPtr query = msg.getSection(SECTION_QUESTION)[0];
-
- string name = query->getName().toText(true);
- if (query->getClass() == RRClass::CH &&
- query->getType() == RRType::TXT &&
- query->getName() == authors_name) {
- msg.setRcode(Message::RCODE_NOERROR);
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Han Feng")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Kazunori Fujiwara")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Michael Graff")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Evan Hunt")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Jelte Jansen")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Jin Jian")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("JINMEI Tatuya")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Naoki Kambe")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Shane Kerr")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Zhang Likun")));
- msg.addRR(SECTION_ANSWER, RR(authors_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("Jeremy C. Reed")));
- msg.addRR(SECTION_AUTHORITY, RR(authors_name, RRClass::CH,
- RRType::NS, TTL(0),
- NS("authors.bind")));
- } else if (query->getClass() == RRClass::CH &&
- query->getType() == RRType::TXT &&
- query->getName() == version_name) {
- msg.setRcode(Message::RCODE_NOERROR);
- msg.addRR(SECTION_ANSWER, RR(version_name, RRClass::CH,
- RRType::TXT, TTL(0),
- TXT("10.0.0s20091030")));
- msg.addRR(SECTION_AUTHORITY, RR(version_name, RRClass::CH,
- RRType::NS, TTL(0),
- NS("version.bind")));
- } else if (zones.contains(name)) {
- msg.setRcode(Message::RCODE_NOERROR);
- RRset* nsset = new RRset(query->getName(), RRClass::IN,
- RRType::NS, TTL(3600));
- BOOST_FOREACH(isc::dns::Rdata::RdataPtr ns, ns_records) {
- nsset->addRdata(ns);
- }
-
- if (query->getType() == RRType::NS)
- msg.addRRset(SECTION_ANSWER, RRsetPtr(nsset));
- else if (query->getType() == RRType::A) {
- msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
-
- BOOST_FOREACH(isc::dns::Rdata::RdataPtr a, a_records) {
- RR arr(query->getName(), RRClass::IN, RRType::A, TTL(3600), a);
- msg.addRR(SECTION_ANSWER, arr);
- }
- } else if (query->getType() == RRType::AAAA) {
- msg.addRRset(SECTION_AUTHORITY, RRsetPtr(nsset));
- BOOST_FOREACH(isc::dns::Rdata::RdataPtr aaaa, aaaa_records) {
- RR aaaarr(query->getName(), RRClass::IN, RRType::AAAA,
- TTL(3600), aaaa);
- msg.addRR(SECTION_ANSWER, aaaarr);
- }
- } else {
- RR soarr(query->getName(), RRClass::IN, RRType::SOA,
- TTL(3600), soa);
- msg.addRR(SECTION_AUTHORITY, soarr);
- }
- } else {
- msg.setRcode(Message::RCODE_NXDOMAIN);
- }
-
- msg.toWire();
- cout << "sending a response (" <<
- boost::lexical_cast<string>(msg.getBuffer().getSize())
- << " bytes):\n" << msg.toText() << endl;
- msg.getBuffer().sendTo(s, *sa, sa_len);
- }
-*/
-}
-
-void
-ParkingLot::command(pair<string,ElementPtr> cmd) {
- if (cmd.first == "shutdown")
- exit(0);
- else if (cmd.first == "config_update") {
- // what to do with port settings?
- ElementPtr zonelist_el = (cmd.second)->get("zones");
- // We could walk through both lists and remove and serve
- // accordingly, or simply clear all and add everything
- //zones.clear_zones();
- BOOST_FOREACH(ElementPtr zone, zonelist_el->listValue()) {
- //zones.serve(zone->stringValue());
- }
}
}
Modified: branches/jelte-datasource1/src/lib/dns/data_source.cc
==============================================================================
--- branches/jelte-datasource1/src/lib/dns/data_source.cc (original)
+++ branches/jelte-datasource1/src/lib/dns/data_source.cc Mon Jan 18 11:45:32 2010
@@ -12,10 +12,10 @@
namespace isc {
namespace dns {
-DataSource::result
+void
DataSource::getData(isc::dns::RRsetPtr query, isc::dns::Message& answer)
{
- return DataSource::not_implemented;
+ return;
}
}
Modified: branches/jelte-datasource1/src/lib/dns/data_source.h
==============================================================================
--- branches/jelte-datasource1/src/lib/dns/data_source.h (original)
+++ branches/jelte-datasource1/src/lib/dns/data_source.h Mon Jan 18 11:45:32 2010
@@ -23,11 +23,36 @@
namespace isc {
namespace dns {
+// do we need to make a template for this?
+// i.e. do we want this to be able to hold more types than RRset?
+class SearchResult {
+public:
+ enum status_type { success, error, not_implemented,
+ zone_not_found, name_not_found };
+
+ void addRRset(RRsetPtr rrset) { rrsets.push_back(rrset); }
+
+ status_type getStatus() { return status; }
+ void setStatus(status_type s) { status = s; }
+
+ /* forward iterator interface */
+ typedef std::vector<RRsetPtr>::iterator iterator;
+ typedef std::vector<RRsetPtr>::const_iterator const_iterator;
+ std::vector<RRsetPtr>::iterator begin() { return rrsets.begin(); }
+ std::vector<RRsetPtr>::iterator end() { return rrsets.end(); }
+ std::vector<RRsetPtr>::const_iterator begin() const { return rrsets.begin(); }
+ std::vector<RRsetPtr>::const_iterator end() const { return rrsets.end(); }
+
+private:
+ status_type status;
+ std::vector<RRsetPtr> rrsets;
+};
+
// Base class for a DNS Data Source
class DataSource {
public:
- enum result { success, not_implemented, error, zone_not_found,
- name_not_found };
+ //enum result { success, not_implemented, error, zone_not_found,
+ // name_not_found };
DataSource() {};
virtual ~DataSource() {};
@@ -40,7 +65,7 @@
//
// fill in separate lists or simple fill in an answer Message object?
- result getData(const RRsetPtr query, Message& answer);
+ void getData(const RRsetPtr query, Message& answer);
// how to provide highlevel update data?
//result handleUpdate()
@@ -49,8 +74,24 @@
//
// mandatory 'low-level' methods, an implementation must overwrite these
//
- virtual result findRRset(RRsetPtr& target, const Name name,
- const RRClass clas, const RRType type) = 0;
+ //
+ // for a 'catch-all' datasource, we need to be able to find
+ // out if it has a zone for a given name
+ //
+ // perhaps this should not set a zone Name, but rather a specific
+ // ZoneRef option (which could be datasource-specific, as it will
+ // only be used to pass along to other calls)
+ // Or even more abstract;
+ // SomeHandler initFind(name, whatever else);
+ virtual bool hasZoneFor(const Name& name, Name& zone_name) = 0;
+
+ // for the zone_name, see getZoneFor, perhaps this needs to be a more
+ // general handle
+ // And perhaps we need a function that does not have that argument too
+ virtual SearchResult findRRsets(const Name& zone_name,
+ const Name& name,
+ const RRClass& clas,
+ const RRType& type) = 0;
//
// optional 'low-level' methods, an implementation may overwrite these,
@@ -58,15 +99,15 @@
//
virtual void init() {};
virtual void close() {};
- virtual result addRR(Name name, int clas, int type,
- int ttl, Rdata::RdataPtr data)
- { return not_implemented; };
+ //virtual result addRR(Name name, int clas, int type,
+ // int ttl, Rdata::RdataPtr data)
+ // { return not_implemented; };
//virtual result delRR(isc::dns::Name name, int clas, int type) = 0;
// on name/class/type again? or use an already constructed object?
- virtual result getRRSigs(RRsetPtr target, const RRsetPtr rrset)
- { return not_implemented; };
- virtual result getNSECs(RRsetPtr target, const RRsetPtr rrset)
- { return not_implemented; };
+ //virtual result getRRSigs(RRsetPtr target, const RRsetPtr rrset)
+ // { return not_implemented; };
+ //virtual result getNSECs(RRsetPtr target, const RRsetPtr rrset)
+ // { return not_implemented; };
// check if the zone exists, and if so, return something that could
// be used as a pointer for the rest of these functions?
More information about the bind10-changes
mailing list