Commit 8399a643 authored by Evan Hunt's avatar Evan Hunt

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
parent 1a2234a5
......@@ -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
], [
......
SUBDIRS = bind10 bindctl cfgmgr msgq parkinglot host cmdctl
SUBDIRS = bind10 bindctl cfgmgr msgq host cmdctl auth parkinglot
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
{
"data_specification": {
"module_name": "ParkingLot"
}
}
// 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 <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <algorithm>
#include <set>
#include <iostream>
#include <dns/cpp/buffer.h>
#include <dns/cpp/messagerenderer.h>
#include <dns/cpp/name.h>
#include <dns/cpp/question.h>
#include <dns/cpp/rrset.h>
#include <dns/cpp/rrttl.h>
#include <dns/cpp/message.h>
#include <cc/cpp/data.h>
#include "common.h"
#include "auth_srv.h"
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
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<struct sockaddr*>((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<string>(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] }");
}
// 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 <cc/cpp/data.h>
#include <auth/cpp/data_source_static.h>
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
// 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 <iostream>
FatalError::FatalError(std::string m) {
msg = m;
std::cerr << msg << std::endl;
exit(1);
}
// 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 <stdlib.h>
#include <string>
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:
#define AUTH_SPECFILE_LOCATION "@abs_top_srcdir@/src/bin/auth/auth.spec"
// 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 <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <stdlib.h>
#include <set>
#include <iostream>
#include <boost/foreach.hpp>
#include <dns/cpp/buffer.h>
#include <dns/cpp/name.h>
#include <dns/cpp/rrset.h>
#include <dns/cpp/message.h>
#include <cc/cpp/session.h>
#include <cc/cpp/data.h>
#include <config/cpp/ccsession.h>
#include "common.h"
#include "config.h"
#include "auth_srv.h"
#include <boost/foreach.hpp>
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);
}
......@@ -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:
......
......@@ -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
......
......@@ -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
......
SUBDIRS = cc config dns
SUBDIRS = cc config dns auth
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
- 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.
#include <dns/cpp/buffer.h>
#include <dns/cpp/name.h>
#include <dns/cpp/rrset.h>
#include <dns/cpp/message.h>
#include <cc/cpp/data.h>
#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);
};
}
}
// 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.
//