From 8399a64371ffeae3c8caebd14faa73f38fe85d57 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Sat, 30 Jan 2010 07:39:38 +0000 Subject: [PATCH] Merged experiments/each-query branch into parkinglot. (This now builds the b10-auth binary. The b10-parkinglot binary is still being built for reference purposes, but is expected to be removed. Both programs use port 5300, so they cannot be run simultaneously.) git-svn-id: svn://bind10.isc.org/svn/bind10/branches/parkinglot@690 e5f2f494-b856-4b98-b285-d166d9295462 --- configure.ac | 4 + src/bin/Makefile.am | 2 +- src/bin/auth/Makefile.am | 10 ++ src/bin/auth/auth.spec | 6 + src/bin/auth/auth_srv.cc | 123 ++++++++++++++++ src/bin/auth/auth_srv.h | 40 ++++++ src/bin/auth/common.cc | 23 +++ src/bin/auth/common.h | 36 +++++ src/bin/auth/config.h.in | 1 + src/bin/auth/main.cc | 140 ++++++++++++++++++ src/bin/bind10/bind10.py.in | 12 +- src/bin/bind10/bind10_test.in | 2 +- src/bin/bind10/run_bind10.sh.in | 2 +- src/lib/Makefile.am | 2 +- src/lib/auth/Makefile.am | 1 + src/lib/auth/cpp/Makefile.am | 9 ++ src/lib/auth/cpp/TODO | 5 + src/lib/auth/cpp/data_source.cc | 118 ++++++++++++++++ src/lib/auth/cpp/data_source.h | 154 ++++++++++++++++++++ src/lib/auth/cpp/data_source_plot.cc | 187 +++++++++++++++++++++++++ src/lib/auth/cpp/data_source_plot.h | 96 +++++++++++++ src/lib/auth/cpp/data_source_static.cc | 114 +++++++++++++++ src/lib/auth/cpp/data_source_static.h | 69 +++++++++ src/lib/auth/cpp/query.cc | 43 ++++++ src/lib/auth/cpp/query.h | 133 ++++++++++++++++++ src/lib/dns/cpp/message.h | 18 ++- src/lib/dns/cpp/rdata/hs_4/a_1.cc | 71 ++++++++++ src/lib/dns/cpp/rdata/hs_4/a_1.h | 42 ++++++ src/lib/dns/cpp/rrclass-placeholder.h | 25 ++++ src/lib/dns/cpp/rrset.h | 2 + 30 files changed, 1475 insertions(+), 15 deletions(-) create mode 100644 src/bin/auth/Makefile.am create mode 100644 src/bin/auth/auth.spec create mode 100644 src/bin/auth/auth_srv.cc create mode 100644 src/bin/auth/auth_srv.h create mode 100644 src/bin/auth/common.cc create mode 100644 src/bin/auth/common.h create mode 100644 src/bin/auth/config.h.in create mode 100644 src/bin/auth/main.cc create mode 100644 src/lib/auth/Makefile.am create mode 100644 src/lib/auth/cpp/Makefile.am create mode 100644 src/lib/auth/cpp/TODO create mode 100644 src/lib/auth/cpp/data_source.cc create mode 100644 src/lib/auth/cpp/data_source.h create mode 100644 src/lib/auth/cpp/data_source_plot.cc create mode 100644 src/lib/auth/cpp/data_source_plot.h create mode 100644 src/lib/auth/cpp/data_source_static.cc create mode 100644 src/lib/auth/cpp/data_source_static.h create mode 100644 src/lib/auth/cpp/query.cc create mode 100644 src/lib/auth/cpp/query.h create mode 100644 src/lib/dns/cpp/rdata/hs_4/a_1.cc create mode 100644 src/lib/dns/cpp/rdata/hs_4/a_1.h diff --git a/configure.ac b/configure.ac index 97be72d3c9..714823c6c4 100644 --- a/configure.ac +++ b/configure.ac @@ -151,6 +151,7 @@ AC_CONFIG_FILES([Makefile src/bin/cfgmgr/Makefile src/bin/host/Makefile src/bin/msgq/Makefile + src/bin/auth/Makefile src/bin/parkinglot/Makefile src/lib/Makefile src/lib/cc/Makefile @@ -166,6 +167,8 @@ AC_CONFIG_FILES([Makefile src/lib/config/python/isc/config/Makefile src/lib/dns/Makefile src/lib/dns/cpp/Makefile + src/lib/auth/Makefile + src/lib/auth/cpp/Makefile ]) AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py src/bin/cfgmgr/run_b10-cfgmgr.sh @@ -179,6 +182,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py src/bin/msgq/msgq.py src/bin/msgq/msgq_test src/bin/msgq/run_msgq.sh + src/bin/auth/config.h src/bin/parkinglot/config.h src/lib/dns/cpp/gen-rdatacode.py ], [ diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 8a78cff231..4cb065ee58 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -1 +1 @@ -SUBDIRS = bind10 bindctl cfgmgr msgq parkinglot host cmdctl +SUBDIRS = bind10 bindctl cfgmgr msgq host cmdctl auth parkinglot diff --git a/src/bin/auth/Makefile.am b/src/bin/auth/Makefile.am new file mode 100644 index 0000000000..09425c3295 --- /dev/null +++ b/src/bin/auth/Makefile.am @@ -0,0 +1,10 @@ +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_builddir)/src/lib/dns/cpp -I$(top_srcdir)/src/lib/dns/cpp -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext + +bin_PROGRAMS = b10-auth +b10_auth_SOURCES = auth_srv.cc auth_srv.h +b10_auth_SOURCES += common.cc common.h +b10_auth_SOURCES += main.cc +b10_auth_LDADD = $(top_builddir)/src/lib/dns/cpp/.libs/libdns.a +b10_auth_LDADD += $(top_builddir)/src/lib/auth/cpp/.libs/libauth.a +b10_auth_LDADD += $(top_builddir)/src/lib/config/cpp/libclient.a +b10_auth_LDADD += $(top_builddir)/src/lib/cc/cpp/libcc.a diff --git a/src/bin/auth/auth.spec b/src/bin/auth/auth.spec new file mode 100644 index 0000000000..6c37bf375a --- /dev/null +++ b/src/bin/auth/auth.spec @@ -0,0 +1,6 @@ +{ + "data_specification": { + "module_name": "ParkingLot" + } +} + diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc new file mode 100644 index 0000000000..40a5c02230 --- /dev/null +++ b/src/bin/auth/auth_srv.cc @@ -0,0 +1,123 @@ +// 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$ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "auth_srv.h" + +#include +#include + +using namespace std; + +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace isc::data; + +AuthSrv::AuthSrv(int port) { + int s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) + throw FatalError("failed to open socket"); + + struct sockaddr_in sin; + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(port); + + socklen_t sa_len = sizeof(sin); +#ifdef HAVE_SIN_LEN + sin.sin_len = sa_len; +#endif + + if (bind(s, (struct sockaddr *)&sin, sa_len) < 0) + throw FatalError("could not bind socket"); + + sock = s; +} + +void +AuthSrv::processMessage() { + struct sockaddr_storage ss; + socklen_t sa_len = sizeof(ss); + struct sockaddr* sa = static_cast((void*)&ss); + int s = sock; + Message msg; + char recvbuf[4096]; + int cc; + + if ((cc = recvfrom(s, recvbuf, sizeof(recvbuf), 0, sa, &sa_len)) > 0) { + InputBuffer buffer(recvbuf, cc); + try { + msg.fromWire(buffer); + } catch (...) { + cerr << "[AuthSrv] parse failed" << endl; + return; + } + + cout << "[AuthSrv] received a message:\n" << msg.toText() << endl; + + if (msg.getRRCount(Section::QUESTION()) != 1) { + return; + } + + QuestionPtr query = *msg.beginQuestion(); + + msg.makeResponse(); + msg.setHeaderFlag(MessageFlag::AA()); + msg.setRcode(Rcode::NOERROR()); + + // do the DataSource call here + Query q = Query(msg, false); + data_src.runQuery(q); + + OutputBuffer obuffer(4096); + MessageRenderer renderer(obuffer); + msg.toWire(renderer); + cout << "sending a response (" << + boost::lexical_cast(obuffer.getLength()) + << " bytes):\n" << msg.toText() << endl; + sendto(s, obuffer.getData(), obuffer.getLength(), 0, sa, sa_len); + } +} + +ElementPtr +AuthSrv::updateConfig(isc::data::ElementPtr config) { + //if (config->contains("port")) { + // todo: what to do with port change. restart automatically? + // ignore atm + //} + return isc::data::Element::createFromString("{ \"result\": [0] }"); +} diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h new file mode 100644 index 0000000000..8636d721b3 --- /dev/null +++ b/src/bin/auth/auth_srv.h @@ -0,0 +1,40 @@ +// 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 __AUTH_SRV_H +#define __AUTH_SRV_H 1 + +#include +#include + +class AuthSrv { +public: + explicit AuthSrv(int port); + //~AuthSrv() {} + int getSocket() { return (sock); } + void processMessage(); + void serve(std::string zone_name); + + isc::data::ElementPtr updateConfig(isc::data::ElementPtr config); +private: + + // TODO: make this a MetaDataSrc, but that one is abstract... + isc::dns::StaticDataSrc data_src; + int sock; +}; + +#endif // __AUTH_SRV_H + diff --git a/src/bin/auth/common.cc b/src/bin/auth/common.cc new file mode 100644 index 0000000000..2c01050b07 --- /dev/null +++ b/src/bin/auth/common.cc @@ -0,0 +1,23 @@ +// 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$ +#include "common.h" +#include + +FatalError::FatalError(std::string m) { + msg = m; + std::cerr << msg << std::endl; + exit(1); +} diff --git a/src/bin/auth/common.h b/src/bin/auth/common.h new file mode 100644 index 0000000000..6345093e99 --- /dev/null +++ b/src/bin/auth/common.h @@ -0,0 +1,36 @@ +// 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 __COMMON_H +#define __COMMON_H 1 + +#include +#include + +class FatalError : public std::exception { +public: + FatalError(std::string m = "fatal error"); + ~FatalError() throw() {} + const char* what() const throw() { return msg.c_str(); } +private: + std::string msg; +}; + +#endif // __COMMON_H + +// Local Variables: +// mode: c++ +// End: diff --git a/src/bin/auth/config.h.in b/src/bin/auth/config.h.in new file mode 100644 index 0000000000..b88a022cb5 --- /dev/null +++ b/src/bin/auth/config.h.in @@ -0,0 +1 @@ +#define AUTH_SPECFILE_LOCATION "@abs_top_srcdir@/src/bin/auth/auth.spec" diff --git a/src/bin/auth/main.cc b/src/bin/auth/main.cc new file mode 100644 index 0000000000..0c50c80592 --- /dev/null +++ b/src/bin/auth/main.cc @@ -0,0 +1,140 @@ +// 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$ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "auth_srv.h" + +#include + +using namespace std; + +const string PROGRAM = "Auth"; +const int DNSPORT = 5300; + +/* need global var for config/command handlers. + * todo: turn this around, and put handlers in the authserver + * class itself? */ +AuthSrv auth = AuthSrv(DNSPORT); + +static void +usage() { + cerr << "Usage: b10-auth [-p port]" << endl; + exit(1); +} + +isc::data::ElementPtr +my_config_handler(isc::data::ElementPtr config) +{ + return auth.updateConfig(config); +} + +isc::data::ElementPtr +my_command_handler(isc::data::ElementPtr command) { + isc::data::ElementPtr answer = isc::data::Element::createFromString("{ \"result\": [0] }"); + + cout << "[XX] Handle command: " << endl << command->str() << endl; + if (command->get(0)->stringValue() == "print_message") + { + cout << command->get(1)->get("message") << endl; + /* let's add that message to our answer as well */ + cout << "[XX] answer was: " << answer->str() << endl; + answer->get("result")->add(command->get(1)); + cout << "[XX] answer now: " << answer->str() << endl; + } + + return answer; +} + +int +main(int argc, char* argv[]) { + int ch; + int port = DNSPORT; + + while ((ch = getopt(argc, argv, "p:")) != -1) { + switch (ch) { + case 'p': + port = atoi(optarg); + break; + case '?': + default: + usage(); + } + } + + if (argc - optind > 0) + usage(); + + // initialize command channel + try { + CommandSession cs = CommandSession(AUTH_SPECFILE_LOCATION, + my_config_handler, + my_command_handler); + + // main server loop + fd_set fds; + int ps = auth.getSocket(); + int ss = cs.getSocket(); + int nfds = max(ps, ss) + 1; + int counter = 0; + + cout << "Server started." << endl; + while (true) { + FD_ZERO(&fds); + FD_SET(ps, &fds); + FD_SET(ss, &fds); + + int n = select(nfds, &fds, NULL, NULL, NULL); + if (n < 0) + throw FatalError("select error"); + + if (FD_ISSET(ps, &fds)) { + ++counter; + auth.processMessage(); + } + + /* isset not really necessary, but keep it for now */ + if (FD_ISSET(ss, &fds)) { + cs.check_command(); + } + } + } catch (isc::cc::SessionError se) { + cout << se.what() << endl; + exit(1); + } + + return (0); +} diff --git a/src/bin/bind10/bind10.py.in b/src/bin/bind10/bind10.py.in index b59b7eea0d..733991a715 100644 --- a/src/bin/bind10/bind10.py.in +++ b/src/bin/bind10/bind10.py.in @@ -194,16 +194,16 @@ class BoB: # XXX: this must be read from the configuration manager in the future # XXX: we hardcode port 5300 if self.verbose: - sys.stdout.write("Starting b10-parkinglot on port 5300\n") + sys.stdout.write("Starting b10-auth on port 5300\n") try: - parkinglot = ProcessInfo("b10-parkinglot", ["b10-parkinglot", "-p", "5300"]) + auth = ProcessInfo("b10-auth", ["b10-auth", "-p", "5300"]) except Exception as e: c_channel.process.kill() bind_cfgd.process.kill() - return "Unable to start b10-parkinglot; " + str(e) - self.processes[parkinglot.pid] = parkinglot + return "Unable to start b10-auth; " + str(e) + self.processes[auth.pid] = auth if self.verbose: - sys.stdout.write("Started b10-parkinglot (PID %d)\n" % parkinglot.pid) + sys.stdout.write("Started b10-auth (PID %d)\n" % auth.pid) # start the b10-cmdctl # XXX: we hardcode port 8080 @@ -214,7 +214,7 @@ class BoB: except Exception as e: c_channel.process.kill() bind_cfgd.process.kill() - parkinglot.process.kill() + auth.process.kill() return "Unable to start b10-cmdctl; " + str(e) self.processes[cmd_ctrld.pid] = cmd_ctrld if self.verbose: diff --git a/src/bin/bind10/bind10_test.in b/src/bin/bind10/bind10_test.in index 4ea8a697e5..2f9bbb6fb2 100755 --- a/src/bin/bind10/bind10_test.in +++ b/src/bin/bind10/bind10_test.in @@ -5,7 +5,7 @@ export PYTHON_EXEC BIND10_PATH=@abs_top_srcdir@/src/bin/bind10 -PATH=@abs_top_srcdir@/src/bin/msgq:@abs_top_srcdir@/src/bin/parkinglot:@abs_top_srcdir@/src/bin/bind-cfgd:$PATH +PATH=@abs_top_srcdir@/src/bin/msgq:@abs_top_srcdir@/src/bin/auth:@abs_top_srcdir@/src/bin/bind-cfgd:$PATH export PATH PYTHONPATH=@abs_top_srcdir@/src/lib/cc/python:${abs_top_src_dir}/lib/cc/python/ISC diff --git a/src/bin/bind10/run_bind10.sh.in b/src/bin/bind10/run_bind10.sh.in index 57b7dc2f5b..1f5da77f0c 100644 --- a/src/bin/bind10/run_bind10.sh.in +++ b/src/bin/bind10/run_bind10.sh.in @@ -5,7 +5,7 @@ export PYTHON_EXEC BIND10_PATH=@abs_top_builddir@/src/bin/bind10 -PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/parkinglot:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:$PATH +PATH=@abs_top_builddir@/src/bin/msgq:@abs_top_builddir@/src/bin/auth:@abs_top_builddir@/src/bin/cfgmgr:@abs_top_builddir@/src/bin/cmdctl:$PATH export PATH PYTHONPATH=@abs_top_srcdir@/src/lib/cc/python:@abs_top_srcdir@/src/lib/config/python diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 0b817edcbe..41e06e4ff9 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -1 +1 @@ -SUBDIRS = cc config dns +SUBDIRS = cc config dns auth diff --git a/src/lib/auth/Makefile.am b/src/lib/auth/Makefile.am new file mode 100644 index 0000000000..8389001c9c --- /dev/null +++ b/src/lib/auth/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = cpp diff --git a/src/lib/auth/cpp/Makefile.am b/src/lib/auth/cpp/Makefile.am new file mode 100644 index 0000000000..6a8d524200 --- /dev/null +++ b/src/lib/auth/cpp/Makefile.am @@ -0,0 +1,9 @@ +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_srcdir)/ext + +CLEANFILES = *.gcno *.gcda + +lib_LTLIBRARIES = libauth.la +libauth_la_SOURCES = data_source.h data_source.cc +libauth_la_SOURCES += data_source_static.h data_source_static.cc +#libauth_la_SOURCES += data_source_plot.h data_source_plot.cc +libauth_la_SOURCES += query.h query.cc diff --git a/src/lib/auth/cpp/TODO b/src/lib/auth/cpp/TODO new file mode 100644 index 0000000000..2567e9d4cb --- /dev/null +++ b/src/lib/auth/cpp/TODO @@ -0,0 +1,5 @@ +- NXDOMAIN case must add NSEC/NSEC3 data when wantDnssec() +- DataSrc should implement a method findAddrRRsets() which queries + for A and AAAA records. at the high level this would be implemented + as two queries in serial; low level subclasses could override it with + a single query. diff --git a/src/lib/auth/cpp/data_source.cc b/src/lib/auth/cpp/data_source.cc new file mode 100644 index 0000000000..0af581ec68 --- /dev/null +++ b/src/lib/auth/cpp/data_source.cc @@ -0,0 +1,118 @@ +#include +#include +#include +#include + +#include + +#include "data_source.h" + +namespace isc { +namespace dns { + +DSResult +DataSrc::runQuery(Query q) { + DSResult result; + RRsetList data, sigs; + Name container("."); + Message& m = q.message(); + + while (!q.tasks().empty()) { + bool found = false; + QueryTaskPtr task = q.tasks().front(); + q.tasks().pop(); + + const DataSrc* ds = findClosestEnclosure(task->qname, container, found); + + if (ds == NULL) { + result = ZONE_NOT_FOUND; + } else if (q.wantDnssec()) { + result = ds->findRRset(task->qname, task->qclass, task->qtype, + data, sigs); + // XXX validity check: + // for now, there must only be exactly one RRset in data + // and no more than one RRset in sigs. the rrtype of data + // must match the sigtype of sigs, if any + } else { + result = ds->findRRset(task->qname, task->qclass, task->qtype, + data); + } + + switch (result) { + case SUCCESS: + m.addRRset(task->section, data[0]); + if (q.wantDnssec() && sigs.size() == 1) { + m.addRRset(Section(task->section), sigs[0]); + } + + if (q.status() == QUERY_FINISHING) { + q.setStatus(QUERY_DONE); + return (SUCCESS); + } + + // if there are no more work items, add the authority section + if (q.tasks().empty() && q.status() == QUERY_INCOMPLETE) { + QueryTask *qt = new QueryTask(container, task->qclass, + RRType::NS(), + Section::AUTHORITY()); + q.tasks().push(QueryTaskPtr(qt)); + q.setStatus(QUERY_FINISHING); + } + continue; + + case CNAME: + m.addRRset(task->section, data[0]); + if (q.wantDnssec() && sigs.size() == 1) { + m.addRRset(Section(task->section), sigs[0]); + } + + // if (data[0].getType() == RRType::CNAME()) { + // // take apart the CNAME rdata and re-query HERE + // } + continue; + + case NAME_NOT_FOUND: + q.setStatus(QUERY_NODATA); + if (q.wantDnssec()) { + result = ds->findRRset(container, task->qclass, + RRType::SOA(), data, sigs); + } else { + result = ds->findRRset(container, task->qclass, + RRType::SOA(), data); + } + + if (result != SUCCESS) { + m.setRcode(Rcode::SERVFAIL()); + return (ERROR); + } + + m.setRcode(Rcode::NXDOMAIN()); + m.addRRset(Section::AUTHORITY(), data[0]); + if (q.wantDnssec() && sigs.size() == 1) { + m.addRRset(Section::AUTHORITY(), sigs[0]); + } + break; + + case TYPE_NOT_FOUND: + m.setRcode(Rcode::NOERROR()); + q.setStatus(QUERY_NODATA); + return (result); + + case ZONE_NOT_FOUND: + m.setRcode(Rcode::REFUSED()); + q.setStatus(QUERY_NODATA); + return (result); + + default: + m.setRcode(Rcode::SERVFAIL()); + q.setStatus(QUERY_NODATA); + return (result); + } + } + + return (result); +}; + + +} +} diff --git a/src/lib/auth/cpp/data_source.h b/src/lib/auth/cpp/data_source.h new file mode 100644 index 0000000000..e95410ea67 --- /dev/null +++ b/src/lib/auth/cpp/data_source.h @@ -0,0 +1,154 @@ +// 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 +#include +#include +#include + +namespace isc { +namespace dns { + +enum DSResult { + SUCCESS, + NOT_IMPLEMENTED, + ERROR, + CNAME, + ZONE_NOT_FOUND, + NAME_NOT_FOUND, + TYPE_NOT_FOUND +}; + +class DataSrc; + +class AbstractDataSrc { +public: + virtual ~AbstractDataSrc() {}; + + // 'High-level' methods. These will be implemented by the + // general DataSrc class, but MAY be overwritten by subclasses. + virtual DSResult runQuery(Query query) = 0; + + // Mandatory 'low-level' methods: These will NOT be implemented by + // the general DataSrc class; subclasses MUST implement them. + virtual DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target, + RRsetList& sigs) const = 0; + + virtual DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target) const = 0; + + virtual const DataSrc* findClosestEnclosure(const Name& qname, + Name& container, + bool& found) const = 0; + + // Optional 'low-level' methods. These will have stub implementations + // in the general DataSrc class but MAY be overwritten by subclasses + virtual DSResult init() = 0; + virtual DSResult close() = 0; + + //virtual const RRClass& getClass() const = 0; + //virtual const RRClass& setClass() const = 0; +}; + +// Base class for a DNS Data Source +class DataSrc : public AbstractDataSrc { +public: + DataSrc() : rrclass(RRClass::IN()) {} + DataSrc(const RRClass& c) : rrclass(c) {} + virtual ~DataSrc() {}; + + DSResult runQuery(Query q); + + virtual DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target, + RRsetList& sigs) const = 0; + + virtual DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target) const = 0; + + virtual const DataSrc* findClosestEnclosure(const Name& qname, + Name& container, + bool& found) const = 0; + + const RRClass& getClass() const { return rrclass; } + void setClass(RRClass& c) { rrclass = c; } + + DSResult init() { return NOT_IMPLEMENTED; } + DSResult close() { return NOT_IMPLEMENTED; } + +protected: + RRClass rrclass; +}; + +class MetaDataSrc : public DataSrc { +public: + MetaDataSrc() : DataSrc(RRClass::ANY()) {} + MetaDataSrc(const RRClass& c) : DataSrc(c) {} + virtual ~MetaDataSrc() {} + + void addDataSrc(DataSrc* ds) { + if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) { + dns_throw(Unexpected, "class mismatch"); + } + + data_sources.push_back(ds); + }; + + const DataSrc* findClosestEnclosure(const Name& qname, + Name& container, + bool& found) const + { + const DataSrc* best = NULL; + BOOST_FOREACH (DataSrc* ds, data_sources) { + const DataSrc* source; + + if (getClass() != RRClass::ANY() && ds->getClass() != getClass()) { + continue; + } + + source = ds->findClosestEnclosure(qname, container, found); + if (source != NULL) { + best = source; + } + } + + return (best); + }; + +private: + std::vector data_sources; +}; + +} +} + +#endif + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/auth/cpp/data_source_plot.cc b/src/lib/auth/cpp/data_source_plot.cc new file mode 100644 index 0000000000..1e345feb44 --- /dev/null +++ b/src/lib/auth/cpp/data_source_plot.cc @@ -0,0 +1,187 @@ + +#include + +#include + +#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; +using namespace isc::data; + +namespace { +const Name authors_name("authors.bind"); +const Name version_name("version.bind"); +} + +void +DataSourceParkingLot::serve(std::string zone_name) { + zones.serve(zone_name); +} + +void +DataSourceParkingLot::addARecord(std::string data) { + a_records.push_back(RdataPtr(new in::A(data))); +} + +void +DataSourceParkingLot::addAAAARecord(std::string data) { + aaaa_records.push_back(RdataPtr(new in::AAAA(data))); +} + +void +DataSourceParkingLot::addNSRecord(std::string data) { + ns_records.push_back(RdataPtr(new generic::NS(data))); +} + +void +DataSourceParkingLot::setSOARecord(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 = RdataPtr(new generic::SOA(Name("parking.example"), + Name("noc.parking.example"), + 1, 1800, 900, 604800, 86400)); +} + +bool +DataSourceParkingLot::hasZoneFor(const Name& name, Name &zone_name) +{ + if (name == authors_name) { + zone_name = authors_name; + return (true); + } else if (name == version_name) { + zone_name = version_name; + return (true); + } + return zones.findClosest(name, zone_name); +} + +SearchResult +DataSourceParkingLot::findRRsets(const isc::dns::Name& zone_name, + const isc::dns::Name& name, + const isc::dns::RRClass& clas, + const isc::dns::RRType& type) const +{ + SearchResult result; + + if (clas == RRClass::CH()) { + if (type == RRType::TXT()) { + if (name == authors_name) { + RRsetPtr rrset = RRsetPtr(new RRset(authors_name, RRClass::CH(), + RRType::TXT(), RRTTL(0))); + rrset->addRdata(generic::TXT("Han Feng")); + rrset->addRdata(generic::TXT("Kazunori Fujiwara")); + rrset->addRdata(generic::TXT("Michael Graff")); + rrset->addRdata(generic::TXT("Evan Hunt")); + rrset->addRdata(generic::TXT("Jelte Jansen")); + rrset->addRdata(generic::TXT("Jin Jian")); + rrset->addRdata(generic::TXT("JINMEI Tatuya")); + rrset->addRdata(generic::TXT("Naoki Kambe")); + rrset->addRdata(generic::TXT("Shane Kerr")); + rrset->addRdata(generic::TXT("Zhang Likun")); + rrset->addRdata(generic::TXT("Jeremy C. Reed")); + + result.addRRset(rrset); + result.setStatus(SearchResult::success); + } else if (name == version_name) { + RRsetPtr rrset = RRsetPtr(new RRset(version_name, RRClass::CH(), + RRType::TXT(), RRTTL(0))); + rrset->addRdata(generic::TXT("BIND10 0.0.1")); + result.addRRset(rrset); + result.setStatus(SearchResult::success); + } else { + result.setStatus(SearchResult::name_not_found); + } + } else if (type == RRType::NS()) { + if (name == authors_name || name == version_name) { + RRsetPtr rrset = RRsetPtr(new RRset(name, RRClass::CH(), + RRType::NS(), + RRTTL(0))); + rrset->addRdata(generic::NS(name)); + result.addRRset(rrset); + result.setStatus(SearchResult::success); + } else { + result.setStatus(SearchResult::name_not_found); + } + } else { + result.setStatus(SearchResult::name_not_found); + } + } else if (clas == RRClass::IN()) { + if (zones.contains(name)) { + RRsetPtr rrset = RRsetPtr(new RRset(name, clas, type, RRTTL(3600))); + result.setStatus(SearchResult::success); + if (type == RRType::A()) { + BOOST_FOREACH(RdataPtr a, a_records) { + rrset->addRdata(a); + } + } else if (type == RRType::AAAA()) { + BOOST_FOREACH(RdataPtr aaaa, aaaa_records) { + rrset->addRdata(aaaa); + } + } else if (type == RRType::NS()) { + BOOST_FOREACH(RdataPtr ns, ns_records) { + rrset->addRdata(ns); + } + } else if (type == RRType::SOA()) { + rrset->addRdata(soa); + } + result.addRRset(rrset); + } else { + // we don't have the name itself. Do we have the zone? + if (zones.contains(zone_name)) { + result.setStatus(SearchResult::name_not_found); + } else { + result.setStatus(SearchResult::zone_not_found); + } + } + } else { + result.setStatus(SearchResult::zone_not_found); + } + 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, + const Section& section, + const Name& zone_name, + const Name& name, + const RRClass& clas, + const RRType& type) const +{ + SearchResult result = findRRsets(zone_name, name, clas, type); + BOOST_FOREACH(RRsetPtr rrset, result) { + msg.addRRset(section, rrset); + } + return result.getStatus(); +} + + +} +} diff --git a/src/lib/auth/cpp/data_source_plot.h b/src/lib/auth/cpp/data_source_plot.h new file mode 100644 index 0000000000..ff9993503c --- /dev/null +++ b/src/lib/auth/cpp/data_source_plot.h @@ -0,0 +1,96 @@ + +// 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 +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" + +#include "data_source.h" + +#include "zoneset.h" + +namespace isc { +namespace dns { + +class DataSourceParkingLot : public DataSource { +public: + DataSourceParkingLot(); + + void init() {}; + void close() {}; + 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) const; + + /* 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(); }; + + 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); + + /// 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, + const isc::dns::Section& section, + const isc::dns::Name& zone_name, + const isc::dns::Name& name, + const isc::dns::RRClass& clas, + const isc::dns::RRType& type) const; + +private: + // + void setDefaultZoneData(); + + std::vector a_records, aaaa_records, ns_records; + isc::dns::rdata::RdataPtr soa; + ZoneSet zones; + +}; + +} +} + +#endif + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/auth/cpp/data_source_static.cc b/src/lib/auth/cpp/data_source_static.cc new file mode 100644 index 0000000000..e9c6d9a6c7 --- /dev/null +++ b/src/lib/auth/cpp/data_source_static.cc @@ -0,0 +1,114 @@ + + +#include "data_source_static.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace isc { +namespace dns { + +using namespace isc::dns; +using namespace isc::dns::rdata; + +StaticDataSrc::StaticDataSrc() : authors_name("authors.bind"), + version_name("version.bind") +{ + RRsetPtr authors = RRsetPtr(new RRset(authors_name, RRClass::CH(), + RRType::TXT(), RRTTL(3600))); + authors->addRdata(generic::TXT("Evan Hunt")); + authors->addRdata(generic::TXT("Han Feng")); + authors->addRdata(generic::TXT("Jelte Jansen")); + authors->addRdata(generic::TXT("Jeremy C. Reed")); + authors->addRdata(generic::TXT("Jin Jian")); + authors->addRdata(generic::TXT("JINMEI Tatuya")); + authors->addRdata(generic::TXT("Kazunori Fujiwara")); + authors->addRdata(generic::TXT("Michael Graff")); + authors->addRdata(generic::TXT("Naoki Kambe")); + authors->addRdata(generic::TXT("Shane Kerr")); + authors->addRdata(generic::TXT("Zhang Likun")); + + RRsetPtr version = RRsetPtr(new RRset(version_name, RRClass::CH(), + RRType::TXT(), RRTTL(3600))); + version->addRdata(generic::TXT("BIND10 0.0.0 (pre-alpha)")); +} + +const DataSrc* +StaticDataSrc::findClosestEnclosure(const Name& qname, Name& container, bool& found) const { + NameComparisonResult::NameRelation version_cmp = + qname.compare(version_name).getRelation(); + + if (version_cmp == NameComparisonResult::EQUAL || + version_cmp == NameComparisonResult::SUBDOMAIN) { + NameComparisonResult::NameRelation sub_cmp = + version_name.compare(container).getRelation(); + + if (sub_cmp == NameComparisonResult::SUBDOMAIN) { + container = authors_name; + found = true; + return this; + } else if (!found && sub_cmp == NameComparisonResult::EQUAL) { + found = true; + return this; + } else { + return NULL; + } + } + + NameComparisonResult::NameRelation authors_cmp = + qname.compare(authors_name).getRelation(); + + if (authors_cmp == NameComparisonResult::EQUAL || + authors_cmp == NameComparisonResult::SUBDOMAIN) { + NameComparisonResult::NameRelation sub_cmp = + authors_name.compare(container).getRelation(); + + if (sub_cmp == NameComparisonResult::SUBDOMAIN) { + container = authors_name; + found = true; + return this; + } else if (!found && sub_cmp == NameComparisonResult::EQUAL) { + found = true; + return this; + } else { + return NULL; + } + } + + return NULL; +} + +DSResult +StaticDataSrc::findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target) const +{ + if (qname == version_name) { + target.push_back(version); + return SUCCESS; + } else if (qname == authors_name) { + target.push_back(authors); + return SUCCESS; + } + return NAME_NOT_FOUND; +} + +DSResult +StaticDataSrc::findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target, RRsetList& sigs) const +{ + return findRRset(qname, qclass, qtype, target); +} + +} +} diff --git a/src/lib/auth/cpp/data_source_static.h b/src/lib/auth/cpp/data_source_static.h new file mode 100644 index 0000000000..00864b193c --- /dev/null +++ b/src/lib/auth/cpp/data_source_static.h @@ -0,0 +1,69 @@ +// 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$ + +// +// Sample Datasource implementation; this datasource only returns +// static content for the queries +// CH TXT version.bind +// and +// CH TXT authors.bind +// + +#ifndef __STATIC_DATA_SOURCE_H +#define __STATIC_DATA_SOURCE_H + +#include "data_source.h" + +namespace isc { +namespace dns { + +class StaticDataSrc : public DataSrc { +public: + StaticDataSrc(); + ~StaticDataSrc() {}; + + const DataSrc* findClosestEnclosure(const Name& qname, + Name& container, + bool& found) const; + + DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target, RRsetList& sigs) const; + + DSResult findRRset(const Name& qname, + const RRClass& qclass, + const RRType& qtype, + RRsetList& target) const; + + DSResult init() { return SUCCESS; }; + DSResult close() { return SUCCESS; } ; + +private: + const Name authors_name; + const Name version_name; + RRsetPtr authors; + RRsetPtr version; +}; + +} +} + +#endif + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/auth/cpp/query.cc b/src/lib/auth/cpp/query.cc new file mode 100644 index 0000000000..aad1b147c1 --- /dev/null +++ b/src/lib/auth/cpp/query.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2010 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$ + +#include +#include +#include +#include + +#include + +#include "query.h" + +namespace isc { +namespace dns { + +QueryTask::QueryTask(const Name& n, const RRClass& c, + const RRType& t, const Section& s) : + qname(n), qclass(c), qtype(t), section(s) +{ + // Empty constructor. It is defined outside the class statement + // because otherwise the linker will be confused. +} + +QueryTask::~QueryTask() { + // Empty destructor. It is defined outside the class statement + // because otherwise the linker will be confused. +} + +} +} diff --git a/src/lib/auth/cpp/query.h b/src/lib/auth/cpp/query.h new file mode 100644 index 0000000000..aa2d1e8890 --- /dev/null +++ b/src/lib/auth/cpp/query.h @@ -0,0 +1,133 @@ +// Copyright (C) 2010 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 __QUERY_H +#define __QUERY_H + +#include + +#include +#include +#include +#include +#include +#include + +namespace isc { +namespace dns { + +enum QueryStatus { + QUERY_INCOMPLETE, + QUERY_FINISHING, + QUERY_DONE, + QUERY_NODATA +}; + +/// +/// \brief exception to throw if a DNS Message is malformed +/// +class MalformedMessage : public Exception { +public: + MalformedMessage(const char* file, size_t line, const char* what) : + isc::dns::Exception(file, line, what) {} +}; + +// An individual task to be carried out by the query logic +class QueryTask { +public: + QueryTask(const Name& n, const RRClass& c, + const RRType& t, const Section& s); + virtual ~QueryTask(); + + const Name& qname; + const RRClass& qclass; + const RRType& qtype; + const Section& section; +}; + +typedef boost::shared_ptr QueryTaskPtr; +typedef std::queue QueryTaskQueue; + +class Query; +typedef boost::shared_ptr QueryPtr; + +// Data Source query +class Query { +public: + Query(Message& m, bool dnssec) { + message_ = &m; + want_additional = true; + want_dnssec = dnssec; + status_ = QUERY_INCOMPLETE; + + // Check message formatting + QuestionIterator qid = message_->beginQuestion(); + qid++; + if (qid != message_->endQuestion()) + dns_throw(MalformedMessage, "too many questions"); + + // Populate the query tasks queue with the initial question + QuestionPtr query = *message_->beginQuestion(); + qname_ = &query->getName(); + qclass_ = &query->getClass(); + qtype_ = &query->getType(); + QueryTask *qt = new QueryTask(*qname_, *qclass_, *qtype_, + Section::ANSWER()); + querytasks.push(QueryTaskPtr(qt)); + }; + + virtual ~Query() {} + + // wantAdditional() == true indicates that additional-section data + // should be looked up while processing this query. false indicates + // that we're only interested in answer-section data + bool wantAdditional() { return want_additional; } + void setWantAdditional(bool d) { want_additional = d; } + + // wantDnssec() == true indicates that DNSSEC data should be retrieved + // from the data source when this query is being processed + bool wantDnssec() { return want_dnssec; } + void setWantDnssec(bool d) { want_dnssec = d; } + + const Name& qname() { return *qname_; } + const RRClass& qclass() { return *qclass_; } + const RRType& qtype() { return *qtype_; } + + Message& message() { return *message_; } + QueryTaskQueue& tasks() { return querytasks; } + + QueryStatus status() { return status_; } + void setStatus(QueryStatus s) { status_ = s; } + +protected: + QueryStatus status_; + +private: + const Name* qname_; + const RRClass* qclass_; + const RRType* qtype_; + + Message* message_; + QueryTaskQueue querytasks; + + bool want_additional; + bool want_dnssec; +}; + +} +} + +#endif diff --git a/src/lib/dns/cpp/message.h b/src/lib/dns/cpp/message.h index 0c7ea9e7b7..7a0ead64f4 100644 --- a/src/lib/dns/cpp/message.h +++ b/src/lib/dns/cpp/message.h @@ -401,7 +401,15 @@ class Section { public: unsigned int getCode() const { return (code_); } bool operator==(const Section& other) const - { return (code_ == other.code_); } + { return (code_ == other.code_); } + + enum { + SECTION_QUESTION = 0U, + SECTION_ANSWER = 1U, + SECTION_AUTHORITY = 2U, + SECTION_ADDITIONAL = 3U + }; + static const Section& QUESTION(); static const Section& ANSWER(); static const Section& AUTHORITY(); @@ -414,28 +422,28 @@ private: inline const Section& Section::QUESTION() { - static Section s(0); + static Section s(SECTION_QUESTION); return (s); } inline const Section& Section::ANSWER() { - static Section s(1); + static Section s(SECTION_ANSWER); return (s); } inline const Section& Section::AUTHORITY() { - static Section s(2); + static Section s(SECTION_AUTHORITY); return (s); } inline const Section& Section::ADDITIONAL() { - static Section s(3); + static Section s(SECTION_ADDITIONAL); return (s); } diff --git a/src/lib/dns/cpp/rdata/hs_4/a_1.cc b/src/lib/dns/cpp/rdata/hs_4/a_1.cc new file mode 100644 index 0000000000..71579c0529 --- /dev/null +++ b/src/lib/dns/cpp/rdata/hs_4/a_1.cc @@ -0,0 +1,71 @@ +// Copyright (C) 2010 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$ + +#include + +#include "buffer.h" +#include "exceptions.h" +#include "messagerenderer.h" +#include "rdata.h" +#include "rdataclass.h" + +using namespace std; + +// BEGIN_ISC_NAMESPACE +// BEGIN_RDATA_NAMESPACE + +A::A(const string& addrstr) +{ + // TBD +} + +A::A(InputBuffer& buffer, size_t rdata_len) +{ + // TBD +} + +A::A(const A& source) +{ + // TBD +} + +void +A::toWire(OutputBuffer& buffer) const +{ + // TBD +} + +void +A::toWire(MessageRenderer& renderer) const +{ + // TBD +} + +string +A::toText() const +{ + // TBD + dns_throw(InvalidRdataText, "Not implemented yet"); +} + +int +A::compare(const Rdata& other) const +{ + return (0); // dummy. TBD +} + +// END_RDATA_NAMESPACE +// END_ISC_NAMESPACE diff --git a/src/lib/dns/cpp/rdata/hs_4/a_1.h b/src/lib/dns/cpp/rdata/hs_4/a_1.h new file mode 100644 index 0000000000..dcd2f7dafc --- /dev/null +++ b/src/lib/dns/cpp/rdata/hs_4/a_1.h @@ -0,0 +1,42 @@ +// Copyright (C) 2010 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$ + +// BEGIN_HEADER_GUARD + +#include + +#include "rdata.h" + +// BEGIN_ISC_NAMESPACE + +// BEGIN_COMMON_DECLARATIONS +// END_COMMON_DECLARATIONS + +// BEGIN_RDATA_NAMESPACE + +class A : public Rdata { +public: + // BEGIN_COMMON_MEMBERS + // END_COMMON_MEMBERS +}; + +// END_RDATA_NAMESPACE +// END_ISC_NAMESPACE +// END_HEADER_GUARD + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/dns/cpp/rrclass-placeholder.h b/src/lib/dns/cpp/rrclass-placeholder.h index fd6180c5fe..d081c9aa72 100644 --- a/src/lib/dns/cpp/rrclass-placeholder.h +++ b/src/lib/dns/cpp/rrclass-placeholder.h @@ -237,6 +237,15 @@ public: // BEGIN_WELL_KNOWN_CLASS_DECLARATIONS // END_WELL_KNOWN_CLASS_DECLARATIONS + + // \brief Meta-classes + enum { + RRCLASS_RESERVED0 = 0, + RRCLASS_NONE = 254, + RRCLASS_ANY = 255 + }; + static const RRClass& NONE(); + static const RRClass& ANY(); private: uint16_t classcode_; @@ -245,6 +254,22 @@ private: // BEGIN_WELL_KNOWN_CLASS_DEFINITIONS // END_WELL_KNOWN_CLASS_DEFINITIONS +inline const RRClass& +RRClass::NONE() +{ + static RRClass rrclass(RRCLASS_NONE); + + return (rrclass); +} + +inline const RRClass& +RRClass::ANY() +{ + static RRClass rrclass(RRCLASS_ANY); + + return (rrclass); +} + /// /// \brief Insert the \c RRClass as a string into stream. /// diff --git a/src/lib/dns/cpp/rrset.h b/src/lib/dns/cpp/rrset.h index b5c3a0a89f..0a74eece6c 100644 --- a/src/lib/dns/cpp/rrset.h +++ b/src/lib/dns/cpp/rrset.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -38,6 +39,7 @@ class AbstractRRset; typedef boost::shared_ptr RRsetPtr; class BasicRRset; typedef BasicRRset RRset; +typedef std::vector RRsetList; class BasicRRsetImpl; class RdataIterator; -- GitLab