Commit 5546f52f authored by Jelte Jansen's avatar Jelte Jansen
Browse files

temporary branch for example implementation of original data source proposal....

temporary branch for example implementation of original data source proposal. Mainly for archival purposes, will be removed once definite design is agreed upon.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jelte-datasource1@446 e5f2f494-b856-4b98-b285-d166d9295462
parent b5d9864f
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext
bin_PROGRAMS = parkinglot
parkinglot_SOURCES = common.cc common.h zoneset.h parkinglot.cc parkinglot.h ccsession.cc ccsession.h main.cc
parkinglot_SOURCES = common.cc common.h zoneset.h parkinglot.cc
parkinglot_SOURCES += parkinglot.h ccsession.cc ccsession.h main.cc
parkinglot_SOURCES += data_source_plot.h data_source_plot.cc
parkinglot_LDADD = $(top_srcdir)/src/lib/dns/libdns.a $(top_srcdir)/src/lib/cc/cpp/libcc.a
#include <boost/foreach.hpp>
#include "data_source_plot.h"
namespace isc {
namespace dns {
// this implementation returns fixed records,
// and does not allow update statements
using namespace isc::dns;
using namespace isc::dns::Rdata::IN;
using namespace isc::dns::Rdata::Generic;
using namespace isc::data;
void
DataSourceParkingLot::serve(std::string zone_name) {
zones.serve(zone_name);
}
void
DataSourceParkingLot::addARecord(std::string data) {
a_records.push_back(Rdata::RdataPtr(new A(data)));
}
void
DataSourceParkingLot::addAAAARecord(std::string data) {
aaaa_records.push_back(Rdata::RdataPtr(new AAAA(data)));
}
void
DataSourceParkingLot::addNSRecord(std::string data) {
ns_records.push_back(Rdata::RdataPtr(new NS(data)));
}
void
DataSourceParkingLot::setSOARecord(isc::dns::Rdata::RdataPtr soa_record) {
}
void
DataSourceParkingLot::setDefaultZoneData() {
clearARecords();
clearAAAARecords();
clearNSRecords();
addARecord("127.0.0.1");
addAAAARecord("::1");
addNSRecord("ns1.parking.example");
addNSRecord("ns2.parking.example");
addNSRecord("ns3.parking.example");
}
DataSourceParkingLot::DataSourceParkingLot() {
setDefaultZoneData();
soa = Rdata::RdataPtr(new SOA("parking.example", "noc.parking.example",
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) {
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()));
} else if (name == version_name) {
target->addRdata(Rdata::RdataPtr(TXT("BIND10 0.0.1").copy()));
} else {
std::cout << "ch txt but unknown name" << std::endl;
return DataSource::name_not_found;
}
return DataSource::success;
} else {
std::cout << "ch but not txt" << std::endl;
return DataSource::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))) {
if (type == RRType::A) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr a, a_records) {
target->addRdata(a);
}
} else if (type == RRType::AAAA) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr aaaa, aaaa_records) {
target->addRdata(aaaa);
}
} else if (type == RRType::NS) {
BOOST_FOREACH(isc::dns::Rdata::RdataPtr ns, ns_records) {
target->addRdata(ns);
}
} else if (type == RRType::SOA) {
target->addRdata(soa);
} else {
std::cout << "type not supported" << std::endl;
return name_not_found;
}
std::cout << "rrset: " << target->toText() << std::endl;
std::cout << "success" << std::endl;
return success;
} else {
std::cout << "zone not in zoneset" << std::endl;
return DataSource::zone_not_found;
}
} else {
std::cout << "not ch or in" << std::endl;
return DataSource::zone_not_found;
}
// no match at all, error?
return DataSource::error;
}
}
}
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#ifndef __DATA_SOURCE_SIMPLE_H
#define __DATA_SOURCE_SIMPLE_H
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/rrset.h>
#include <dns/message.h>
#include <cc/cpp/data.h>
#include "common.h"
#include "dns/data_source.h"
#include "dns/rrset.h"
#include "zoneset.h"
namespace isc {
namespace dns {
class DataSourceParkingLot : public DataSource {
public:
DataSourceParkingLot();
void init() {};
void close() {};
result findRRset(isc::dns::RRsetPtr& target, isc::dns::Name name,
isc::dns::RRClass clas, 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(); };
void clearNSRecords() { ns_records.clear(); };
void addARecord(std::string data);
void addAAAARecord(std::string data);
void addNSRecord(std::string data);
void setSOARecord(isc::dns::Rdata::RdataPtr soa_record);
private:
//
void setDefaultZoneData();
std::vector<isc::dns::Rdata::RdataPtr> a_records, aaaa_records, ns_records;
isc::dns::Rdata::RdataPtr soa;
ZoneSet zones;
};
}
}
#endif
......@@ -61,36 +61,7 @@ usage() {
isc::data::ElementPtr
my_config_handler(isc::data::ElementPtr config)
{
cout << "[XX] Handle config: " << endl << config->str() << endl;
if (config->contains("zones")) {
plot.clear_zones();
BOOST_FOREACH(isc::data::ElementPtr zone_el, config->get("zones")->listValue()) {
plot.serve(zone_el->stringValue());
}
}
if (config->contains("port")) {
// todo: what to do with port change. restart automatically?
// ignore atm
}
if (config->contains("a_records")) {
plot.clearARecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("a_records")->listValue()) {
plot.addARecord(rel->stringValue());
}
}
if (config->contains("aaaa_records")) {
plot.clearAAAARecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("aaaa_records")->listValue()) {
plot.addAAAARecord(rel->stringValue());
}
}
if (config->contains("ns_records")) {
plot.clearNSRecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("ns_records")->listValue()) {
plot.addNSRecord(rel->stringValue());
}
}
return isc::data::Element::createFromString("{ \"result\": [0] }");
return plot.updateConfig(config);
}
isc::data::ElementPtr
......
......@@ -42,48 +42,13 @@ using namespace isc::dns::Rdata::IN;
using namespace isc::dns::Rdata::Generic;
using namespace isc::data;
void
ParkingLot::addARecord(std::string data) {
a_records.push_back(Rdata::RdataPtr(new A(data)));
}
void
ParkingLot::addAAAARecord(std::string data) {
aaaa_records.push_back(Rdata::RdataPtr(new AAAA(data)));
}
void
ParkingLot::addNSRecord(std::string data) {
ns_records.push_back(Rdata::RdataPtr(new NS(data)));
}
void
ParkingLot::setSOARecord(isc::dns::Rdata::RdataPtr soa_record) {
}
void
ParkingLot::setDefaultZoneData() {
clearARecords();
clearAAAARecords();
clearNSRecords();
addARecord("127.0.0.1");
addAAAARecord("::1");
addNSRecord("ns1.parking.example");
addNSRecord("ns2.parking.example");
addNSRecord("ns3.parking.example");
}
ParkingLot::ParkingLot(int port) {
setDefaultZoneData();
/*ns1 = Rdata::RdataPtr(new NS("ns1.parking.example"));
ns2 = Rdata::RdataPtr(new NS("ns2.parking.example"));
ns3 = Rdata::RdataPtr(new NS("ns3.parking.example"));
a = Rdata::RdataPtr(new A("127.0.0.1"));
aaaa = Rdata::RdataPtr(new AAAA("::1"));
*/
soa = Rdata::RdataPtr(new SOA("parking.example", "noc.parking.example",
1, 1800, 900, 604800, TTL(86400)));
int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s < 0)
......@@ -107,6 +72,68 @@ ParkingLot::ParkingLot(int port) {
void
ParkingLot::processMessage() {
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];
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);
}
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);
}
break;
}
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;
......@@ -223,6 +250,7 @@ ParkingLot::processMessage() {
<< " bytes):\n" << msg.toText() << endl;
msg.getBuffer().sendTo(s, *sa, sa_len);
}
*/
}
void
......@@ -234,14 +262,44 @@ ParkingLot::command(pair<string,ElementPtr> cmd) {
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();
//zones.clear_zones();
BOOST_FOREACH(ElementPtr zone, zonelist_el->listValue()) {
zones.serve(zone->stringValue());
//zones.serve(zone->stringValue());
}
}
}
void
ParkingLot::serve(std::string zone_name) {
zones.serve(zone_name);
ElementPtr
ParkingLot::updateConfig(isc::data::ElementPtr config) {
if (config->contains("zones")) {
data_source.clear_zones();
BOOST_FOREACH(isc::data::ElementPtr zone_el, config->get("zones")->listValue()) {
data_source.serve(zone_el->stringValue());
}
}
if (config->contains("port")) {
// todo: what to do with port change. restart automatically?
// ignore atm
}
if (config->contains("a_records")) {
data_source.clearARecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("a_records")->listValue()) {
data_source.addARecord(rel->stringValue());
}
}
if (config->contains("aaaa_records")) {
data_source.clearAAAARecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("aaaa_records")->listValue()) {
data_source.addAAAARecord(rel->stringValue());
}
}
if (config->contains("ns_records")) {
data_source.clearNSRecords();
BOOST_FOREACH(isc::data::ElementPtr rel, config->get("ns_records")->listValue()) {
data_source.addNSRecord(rel->stringValue());
}
}
return isc::data::Element::createFromString("{ \"result\": [0] }");
}
......@@ -19,6 +19,7 @@
#include "zoneset.h"
#include <cc/cpp/data.h>
#include "data_source_plot.h"
class ParkingLot {
public:
......@@ -28,24 +29,11 @@ public:
void processMessage();
void command(std::pair<std::string,isc::data::ElementPtr>);
void serve(std::string zone_name);
void clear_zones() { zones.clear_zones(); };
void clearARecords() { a_records.clear(); };
void clearAAAARecords() { aaaa_records.clear(); };
void clearNSRecords() { ns_records.clear(); };
void addARecord(std::string data);
void addAAAARecord(std::string data);
void addNSRecord(std::string data);
void setSOARecord(isc::dns::Rdata::RdataPtr soa_record);
isc::data::ElementPtr updateConfig(isc::data::ElementPtr config);
private:
void setDefaultZoneData();
std::vector<isc::dns::Rdata::RdataPtr> a_records, aaaa_records, ns_records;
isc::dns::Rdata::RdataPtr soa;
ZoneSet zones;
isc::dns::DataSourceParkingLot data_source;
int sock;
};
......
......@@ -2,7 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext
lib_LIBRARIES = libdns.a
libdns_a_SOURCES = name.cc buffer.cc rrset.cc message.cc \
name.h buffer.h rrset.h message.h
name.h buffer.h rrset.h message.h data_source.cc data_source.h
TESTS =
if HAVE_GTEST
......
#include <dns/buffer.h>
#include <dns/name.h>
#include <dns/rrset.h>
#include <dns/message.h>
#include <cc/cpp/data.h>
#include "name.h"
#include "data_source.h"
namespace isc {
namespace dns {
DataSource::result
DataSource::getData(isc::dns::RRsetPtr query, isc::dns::Message& answer)
{
return DataSource::not_implemented;
}
}
}
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#ifndef __DATA_SOURCE_H
#define __DATA_SOURCE_H
#include "name.h"
#include "rrset.h"
namespace isc {
namespace dns {
// Base class for a DNS Data Source
class DataSource {
public:
enum result { success, not_implemented, error, zone_not_found,
name_not_found };
DataSource() {};
virtual ~DataSource() {};
//
// 'high-level' methods, these may or may not be overwritten;
// depending on the data source the default implementation
// may not be most efficient, but should at least provide
// the needed functionality
//
// fill in separate lists or simple fill in an answer Message object?
result getData(const RRsetPtr query, Message& answer);
// how to provide highlevel update data?
//result handleUpdate()
//
// mandatory 'low-level' methods, an implementation must overwrite these
//
virtual result findRRset(RRsetPtr& target, const Name name,
const RRClass clas, const RRType type) = 0;
//
// optional 'low-level' methods, an implementation may overwrite these,
// by default they return not_implemented
//
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 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; };
// check if the zone exists, and if so, return something that could
// be used as a pointer for the rest of these functions?
// do we need this? do we want this?
//virtual int getZone(void* zone, isc::dns::Name name);
};
}
}
#endif
......@@ -21,6 +21,8 @@
#include <functional>
#include <algorithm>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <dns/buffer.h>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment