[svn] commit: r2346 - in /experiments/python-binding: ./ src/bin/auth/ src/bin/auth/tests/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cfgmgr/tests/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/loadzone/testdata/ src/bin/loadzone/tests/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/ src/bin/xfrout/tests/ src/lib/cc/ src/lib/config/tests/ src/lib/datasrc/ src/lib/datasrc/tests/ src/lib/datasrc/tests/testdata/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/rdata/generic/ src/lib/dns/tests/ src/lib/python/isc/ src/lib/python/isc/datasrc/ src/lib/python/isc/log/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jun 30 13:47:22 UTC 2010
Author: jelte
Date: Wed Jun 30 13:47:21 2010
New Revision: 2346
Log:
sync with trunk for merge
Added:
experiments/python-binding/src/bin/bind10/tests/args_test.py
- copied unchanged from r2345, trunk/src/bin/bind10/tests/args_test.py
experiments/python-binding/src/bin/cfgmgr/tests/
- copied from r2345, trunk/src/bin/cfgmgr/tests/
experiments/python-binding/src/bin/loadzone/tests/
- copied from r2345, trunk/src/bin/loadzone/tests/
experiments/python-binding/src/lib/python/isc/log/
- copied from r2345, trunk/src/lib/python/isc/log/
Removed:
experiments/python-binding/src/bin/loadzone/testdata/
Modified:
experiments/python-binding/ (props changed)
experiments/python-binding/ChangeLog
experiments/python-binding/configure.ac
experiments/python-binding/src/bin/auth/Makefile.am
experiments/python-binding/src/bin/auth/asio_link.cc
experiments/python-binding/src/bin/auth/asio_link.h
experiments/python-binding/src/bin/auth/auth_srv.cc
experiments/python-binding/src/bin/auth/main.cc
experiments/python-binding/src/bin/auth/tests/Makefile.am
experiments/python-binding/src/bin/bind10/bind10.py.in
experiments/python-binding/src/bin/bind10/tests/bind10_test.in
experiments/python-binding/src/bin/bindctl/bindcmd.py
experiments/python-binding/src/bin/cfgmgr/Makefile.am
experiments/python-binding/src/bin/cfgmgr/b10-cfgmgr.py.in (contents, props changed)
experiments/python-binding/src/bin/cfgmgr/b10-cfgmgr.xml (props changed)
experiments/python-binding/src/bin/cmdctl/cmdctl.py.in
experiments/python-binding/src/bin/host/Makefile.am
experiments/python-binding/src/bin/host/host.cc
experiments/python-binding/src/bin/loadzone/Makefile.am
experiments/python-binding/src/bin/loadzone/b10-loadzone.py.in
experiments/python-binding/src/bin/xfrin/ (props changed)
experiments/python-binding/src/bin/xfrin/tests/Makefile.am
experiments/python-binding/src/bin/xfrin/xfrin.py.in
experiments/python-binding/src/bin/xfrout/tests/Makefile.am
experiments/python-binding/src/bin/xfrout/tests/xfrout_test.py
experiments/python-binding/src/bin/xfrout/xfrout.py.in
experiments/python-binding/src/bin/xfrout/xfrout.spec.pre.in
experiments/python-binding/src/lib/cc/ (props changed)
experiments/python-binding/src/lib/cc/Makefile.am
experiments/python-binding/src/lib/cc/session.cc
experiments/python-binding/src/lib/cc/session_unittests.cc
experiments/python-binding/src/lib/config/tests/Makefile.am
experiments/python-binding/src/lib/datasrc/ (props changed)
experiments/python-binding/src/lib/datasrc/data_source.cc
experiments/python-binding/src/lib/datasrc/sqlite3_datasrc.cc
experiments/python-binding/src/lib/datasrc/tests/Makefile.am
experiments/python-binding/src/lib/datasrc/tests/datasrc_unittest.cc
experiments/python-binding/src/lib/datasrc/tests/test_datasrc.cc
experiments/python-binding/src/lib/datasrc/tests/test_datasrc.h
experiments/python-binding/src/lib/datasrc/tests/testdata/example.org
experiments/python-binding/src/lib/datasrc/tests/testdata/example.org.sqlite3
experiments/python-binding/src/lib/dns/ (props changed)
experiments/python-binding/src/lib/dns/Makefile.am
experiments/python-binding/src/lib/dns/message.cc
experiments/python-binding/src/lib/dns/name.cc
experiments/python-binding/src/lib/dns/python/Makefile.am
experiments/python-binding/src/lib/dns/python/tests/Makefile.am
experiments/python-binding/src/lib/dns/rdata/generic/rrsig_46.cc (props changed)
experiments/python-binding/src/lib/dns/rrsetlist.cc
experiments/python-binding/src/lib/dns/rrsetlist.h
experiments/python-binding/src/lib/dns/tests/ (props changed)
experiments/python-binding/src/lib/dns/tests/Makefile.am
experiments/python-binding/src/lib/python/isc/Makefile.am
experiments/python-binding/src/lib/python/isc/__init__.py
experiments/python-binding/src/lib/python/isc/datasrc/master.py
Modified: experiments/python-binding/ChangeLog
==============================================================================
--- experiments/python-binding/ChangeLog (original)
+++ experiments/python-binding/ChangeLog Wed Jun 30 13:47:21 2010
@@ -1,11 +1,73 @@
- 53. [bug] zhanglikun
+ 65. [func] shentingting
+ Added verbose options to exactly what is happening with loadzone.
+ Added loadzone test suite of different file formats to load.
+ (Trac #197, #199, #244, #161, #198, #174, #175, svn r2340)
+
+ 64. [func] jerry
+ Added python logging framework. It is for testing and experimenting
+ with logging ideas. Currently, it supports three channels(file,
+ syslog and stderr) and five levels(debug, info, warning, error and
+ critical).
+ (Trac #176, svn r2338)
+
+ 63. [func] shane
+ Added initial support for setuid(), using the "-u" flag. This will
+ be replaced in the future, but for now provides a reasonable
+ starting point.
+ (Trac #180, svn r2330)
+
+ 62. [func] jelte
+ bin/xfrin: Use the database_file as configured in Auth to transfers
+ bin/xfrout: Use the database_file as configured in Auth to transfers
+
+ 61. [bug] jelte
+ bin/auth: Enable b10-auth to be launched in source tree
+ (i.e. use a zone database file relative to that)
+
+ 60. [build] jinmei
+ Supported SunStudio C++ compiler. Note: gtest still doesn't work.
+ (Trac #251, svn r2310)
+
+ 59. [bug] jinmei
+ lib/datasrc,bin/auth: The authoritative server could return a
+ SERVFAIL with a partial answer if it finds a data source broken
+ while looking for an answer. This can happen, for example, if a
+ zone that doesn't have an NS RR is configured and loaded as a
+ sqlite3 data source. (Trac #249, r2286)
+
+ 58. [bug] jinmei
+ Worked around an interaction issue between ASIO and standard C++
+ library headers. Without this ASIO didn't work: sometimes the
+ application crashes, sometimes it blocked in the ASIO module.
+ (Trac #248, svn r2187, r2190)
+
+ 57. [func] jinmei
+ lib/datasrc: used a simpler version of Name::split (change 31) for
+ better readability. No behavior change. (Trac #200, svn r2159)
+
+ 56. [func]* jinmei
+ lib/dns: renamed the library name to libdns++ to avoid confusion
+ with the same name of library of BIND 9.
+ (Trac #190, svn r2153)
+
+ 55. [bug] shane
+ bin/xfrout: xfrout exception on Ctrl-C now no longer generates
+ exception for 'Interrupted system call'
+ (Track #136, svn r2147)
+
+ 54. [bug] zhanglikun
+ bin/xfrout: Enable b10-xfrout can be launched in source
+ code tree.
+ (Trac #224, svn r2103)
+
+ 53. [bug] zhanglikun
bin/bindctl: Generate a unique session ID by using
socket.gethostname() instead of socket.gethostbyname(),
since the latter one could make bindctl stall if its own
host name can't be resolved.
(Trac #228, svn r2096)
- 52. [func] zhanglikun
+ 52. [func] zhanglikun
bin/xfrout: When xfrout is launched, check whether the
socket file is being used by one running xfrout process,
if it is, exit from python. If the file isn't a socket file
@@ -67,6 +129,10 @@
Renamed libauth to libdatasrc.
38. [bug] zhanglikun
+ Send command 'shutdown' to Xfrin and Xfrout when boss receive SIGINT.
+ Remove unused socket file when Xfrout process exits. Make sure Xfrout
+ exit by itself when it receives SIGINT, instead of being killed by the
+ signal SIGTERM or SIGKILL sent from boss.
(Trac #135, #151, #134, svn r1797)
37. [build] jinmei
@@ -127,7 +193,7 @@
24. [func]
Support case-sensitive name compression in MessageRenderer.
- (svn r1704)
+ (Trac #142, svn r1704)
23. [func]
Support a simple name with possible compression. (svn r1701)
Modified: experiments/python-binding/configure.ac
==============================================================================
--- experiments/python-binding/configure.ac (original)
+++ experiments/python-binding/configure.ac Wed Jun 30 13:47:21 2010
@@ -9,11 +9,23 @@
# Checks for programs.
AC_PROG_CXX
-AC_PROG_CC
AC_PROG_LIBTOOL
# Use C++ language
-AC_LANG_CPLUSPLUS
+AC_LANG([C++])
+
+# Identify the compiler: this check must be after AC_PROG_CXX and AC_LANG.
+AM_CONDITIONAL(USE_GXX, test "X${GXX}" = "Xyes")
+AC_CHECK_DECL([__SUNPRO_CC], [SUNCXX="yes"], [SUNCXX="no"])
+
+# OS dependent compiler flags
+case "$host" in
+*-solaris*)
+ # Solaris requires special definitions to get some standard libraries
+ # (e.g. getopt(3)) available with common used header files.
+ CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__"
+ ;;
+esac
m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1])
AC_ARG_WITH([pythonpath],
@@ -93,8 +105,8 @@
# TODO: check for _sqlite3.py module
-#
-# B10_CXXFLAGS is the default C++ compiler flags. This will (and should) be
+# Compiler dependent settings: define some mandatory CXXFLAGS here.
+# We also use a separate variable B10_CXXFLAGS. This will (and should) be
# used as the default value for each specifc AM_CXXFLAGS:
# AM_CXXFLAGS = $(B10_CXXFLAGS)
# AM_CXXFLAGS += ... # add module specific flags
@@ -103,17 +115,24 @@
# gcc's -Wno-XXX option must be specified after -Wall or -Wextra, we cannot
# specify the default warning flags in CXXFLAGS and let specific modules
# "override" the default.
-#
-B10_CXXFLAGS=
-
-if test "X$GCC" = "Xyes"; then
-B10_CXXFLAGS="-g -Wall -Wextra -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
+
+CXXFLAGS=-g
+werror_ok=0
+
+# SunStudio compiler requires special compiler options for boost
+# (http://blogs.sun.com/sga/entry/boost_mini_howto)
+if test "$SUNCXX" = "yes"; then
+CXXFLAGS="$CXXFLAGS -library=stlport4 -features=tmplife -features=tmplrefstatic"
+fi
+
+# gcc specific settings:
+if test "X$GXX" = "Xyes"; then
+B10_CXXFLAGS="-Wall -Wextra -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare"
UNUSED_PARAM_ATTRIBUTE='__attribute__((unused))'
# Certain versions of gcc (g++) have a bug that incorrectly warns about
# the use of anonymous name spaces even if they're closed in a single
# translation unit. For these versions we have to disable -Werror.
-werror_ok=0
CXXFLAGS_SAVED="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $B10_CXXFLAGS -Werror"
AC_MSG_CHECKING(for in-TU anonymous namespace breakage)
@@ -124,13 +143,13 @@
B10_CXXFLAGS="$B10_CXXFLAGS -Werror"],
[AC_MSG_RESULT(yes)])
CXXFLAGS="$CXXFLAGS_SAVED"
-fi dnl GCC = yes
+fi dnl GXX = yes
AM_CONDITIONAL(GCC_WERROR_OK, test $werror_ok = 1)
AC_DEFINE_UNQUOTED(UNUSED_PARAM, $UNUSED_PARAM_ATTRIBUTE, Define to compiler keyword indicating a function argument is intentionally unused)
# produce PIC unless we disable shared libraries. need this for python bindings.
-if test $enable_shared != "no" -a "X$GCC" = "Xyes"; then
+if test $enable_shared != "no" -a "X$GXX" = "Xyes"; then
B10_CXXFLAGS="$B10_CXXFLAGS -fPIC"
fi
@@ -270,6 +289,11 @@
AC_SUBST(GTEST_LDFLAGS)
AC_SUBST(GTEST_LDADD)
+dnl check for pkg-config itself so we don't try the m4 macro without pkg-config
+AC_CHECK_PROG(HAVE_PKG_CONFIG, pkg-config, yes, no)
+if test "x$HAVE_PKG_CONFIG" = "xno" ; then
+ AC_MSG_ERROR(Please install pkg-config)
+fi
PKG_CHECK_MODULES(SQLITE, sqlite3 >= 3.3.9, enable_features="$enable_features SQLite3")
# I can't get some of the #include <asio.hpp> right without this
@@ -319,7 +343,7 @@
# run time performance. Hpefully we can find a better solution or the ASIO
# code will be updated by the time we really need it.
AC_CHECK_HEADERS(sys/devpoll.h, ac_cv_have_devpoll=yes, ac_cv_have_devpoll=no)
-if test "X$ac_cv_have_devpoll" = "Xyes" -a "X$GCC" = "Xyes"; then
+if test "X$ac_cv_have_devpoll" = "Xyes" -a "X$GXX" = "Xyes"; then
CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_DEV_POLL=1"
fi
@@ -348,8 +372,11 @@
src/bin/bindctl/Makefile
src/bin/bindctl/tests/Makefile
src/bin/cfgmgr/Makefile
+ src/bin/cfgmgr/tests/Makefile
src/bin/host/Makefile
src/bin/loadzone/Makefile
+ src/bin/loadzone/tests/correct/Makefile
+ src/bin/loadzone/tests/error/Makefile
src/bin/msgq/Makefile
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
@@ -368,6 +395,8 @@
src/lib/python/isc/cc/tests/Makefile
src/lib/python/isc/config/Makefile
src/lib/python/isc/config/tests/Makefile
+ src/lib/python/isc/log/Makefile
+ src/lib/python/isc/log/tests/Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
src/lib/dns/Makefile
@@ -380,6 +409,7 @@
src/lib/xfr/Makefile
])
AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
+ src/bin/cfgmgr/tests/b10-cfgmgr_test.py
src/bin/cmdctl/cmdctl.py
src/bin/cmdctl/run_b10-cmdctl.sh
src/bin/cmdctl/tests/cmdctl_test
@@ -398,6 +428,8 @@
src/bin/bindctl/bindctl-source.py
src/bin/bindctl/tests/bindctl_test
src/bin/loadzone/run_loadzone.sh
+ src/bin/loadzone/tests/correct/correct_test.sh
+ src/bin/loadzone/tests/error/error_test.sh
src/bin/loadzone/b10-loadzone.py
src/bin/usermgr/run_b10-cmdctl-usermgr.sh
src/bin/usermgr/b10-cmdctl-usermgr.py
@@ -409,7 +441,7 @@
src/lib/config/tests/data_def_unittests_config.h
src/lib/python/isc/config/tests/config_test
src/lib/python/isc/cc/tests/cc_test
- src/lib/dns/python/tests/libdns_python_test
+ src/lib/python/isc/log/tests/log_test
src/lib/dns/gen-rdatacode.py
src/lib/python/bind10_config.py
src/lib/dns/tests/testdata/gen-wiredata.py
@@ -425,6 +457,8 @@
chmod +x src/bin/bindctl/tests/bindctl_test
chmod +x src/bin/bindctl/run_bindctl.sh
chmod +x src/bin/loadzone/run_loadzone.sh
+ chmod +x src/bin/loadzone/tests/correct/correct_test.sh
+ chmod +x src/bin/loadzone/tests/error/error_test.sh
chmod +x src/bin/usermgr/run_b10-cmdctl-usermgr.sh
chmod +x src/bin/msgq/run_msgq.sh
chmod +x src/bin/msgq/tests/msgq_test
Modified: experiments/python-binding/src/bin/auth/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/auth/Makefile.am (original)
+++ experiments/python-binding/src/bin/auth/Makefile.am Wed Jun 30 13:47:21 2010
@@ -36,7 +36,10 @@
libasio_link_a_SOURCES = asio_link.cc asio_link.h
# Note: the ordering matters: -Wno-... must follow -Wextra (defined in
# B10_CXXFLAGS)
-libasio_link_a_CXXFLAGS = $(AM_CXXFLAGS) -Wno-unused-parameter
+libasio_link_a_CXXFLAGS = $(AM_CXXFLAGS)
+if USE_GXX
+libasio_link_a_CXXFLAGS += -Wno-unused-parameter
+endif
libasio_link_a_CPPFLAGS = $(AM_CPPFLAGS)
BUILT_SOURCES = spec_config.h
@@ -45,9 +48,9 @@
b10_auth_SOURCES += common.h
b10_auth_SOURCES += main.cc
b10_auth_LDADD = $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
-b10_auth_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
+b10_auth_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns++.a
b10_auth_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
-b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.a
+b10_auth_LDADD += $(top_builddir)/src/lib/cc/.libs/libcc.a
b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
b10_auth_LDADD += $(top_builddir)/src/bin/auth/libasio_link.a
b10_auth_LDADD += $(SQLITE_LIBS)
Modified: experiments/python-binding/src/bin/auth/asio_link.cc
==============================================================================
--- experiments/python-binding/src/bin/auth/asio_link.cc (original)
+++ experiments/python-binding/src/bin/auth/asio_link.cc Wed Jun 30 13:47:21 2010
@@ -16,6 +16,7 @@
#include <config.h>
+#include <unistd.h> // for some IPC/network system calls
#include <asio.hpp>
#include <boost/bind.hpp>
@@ -66,7 +67,13 @@
dispatch_axfr_query(const int tcp_sock, char const axfr_query[],
const uint16_t query_len)
{
- string path(UNIX_SOCKET_FILE);
+ string path;
+ if (getenv("B10_FROM_BUILD")) {
+ path = string(getenv("B10_FROM_BUILD")) + "/auth_xfrout_conn";
+ } else {
+ path = UNIX_SOCKET_FILE;
+ }
+
if (getenv("B10_FROM_BUILD")) {
path = string(getenv("B10_FROM_BUILD")) + "/auth_xfrout_conn";
}
Modified: experiments/python-binding/src/bin/auth/asio_link.h
==============================================================================
--- experiments/python-binding/src/bin/auth/asio_link.h (original)
+++ experiments/python-binding/src/bin/auth/asio_link.h Wed Jun 30 13:47:21 2010
@@ -24,7 +24,7 @@
class IOService {
public:
- IOService(AuthSrv* auth_server, const char* port,
+ IOService(AuthSrv* auth_server, const char* const port,
const bool use_ipv4, const bool use_ipv6);
~IOService();
void run();
Modified: experiments/python-binding/src/bin/auth/auth_srv.cc
==============================================================================
--- experiments/python-binding/src/bin/auth/auth_srv.cc (original)
+++ experiments/python-binding/src/bin/auth/auth_srv.cc Wed Jun 30 13:47:21 2010
@@ -243,7 +243,8 @@
impl_->data_sources_.doQuery(query);
} catch (const Exception& ex) {
if (impl_->verbose_mode_) {
- cerr << "[b10-auth] Internal error, returning SERVFAIL: " << ex.what() << endl;
+ cerr << "[b10-auth] Internal error, returning SERVFAIL: " <<
+ ex.what() << endl;
}
makeErrorMessage(message, response_renderer, Rcode::SERVFAIL(),
impl_->verbose_mode_);
@@ -273,9 +274,22 @@
bool is_default;
string item("database_file");
ElementPtr value = cs_->getValue(is_default, item);
+ final = Element::createFromString("{}");
+
+ // If the value is the default, and we are running from
+ // a specific directory ('from build'), we need to use
+ // a different value than the default (which may not exist)
+ // (btw, this should not be done here in the end, i think
+ // the from-source script should have a check for this,
+ // but for that we need offline access to config, so for
+ // now this is a decent solution)
+ if (is_default && getenv("B10_FROM_BUILD")) {
+ value = Element::create(string(getenv("B10_FROM_BUILD")) +
+ "/bind10_zones.sqlite3");
+ }
+ final->set(item, value);
+
db_file_ = value->stringValue();
- final = Element::createFromString("{}");
- final->set(item, value);
} else {
return (answer);
}
Modified: experiments/python-binding/src/bin/auth/main.cc
==============================================================================
--- experiments/python-binding/src/bin/auth/main.cc (original)
+++ experiments/python-binding/src/bin/auth/main.cc Wed Jun 30 13:47:21 2010
@@ -148,12 +148,12 @@
io_service = new asio_link::IOService(auth_server, port, use_ipv4,
use_ipv6);
- ModuleCCSession cs(specfile, io_service->get_io_service(), my_config_handler, my_command_handler);
+ ModuleCCSession cs(specfile, io_service->get_io_service(),
+ my_config_handler, my_command_handler);
auth_server->setConfigSession(&cs);
auth_server->updateConfig(ElementPtr());
-
cout << "[b10-auth] Server started." << endl;
io_service->run();
} catch (const std::exception& ex) {
Modified: experiments/python-binding/src/bin/auth/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/auth/tests/Makefile.am (original)
+++ experiments/python-binding/src/bin/auth/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -20,9 +20,9 @@
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
-run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns++.a
run_unittests_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
-run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/.libs/libcc.a
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
endif
Modified: experiments/python-binding/src/bin/bind10/bind10.py.in
==============================================================================
--- experiments/python-binding/src/bin/bind10/bind10.py.in (original)
+++ experiments/python-binding/src/bin/bind10/bind10.py.in Wed Jun 30 13:47:21 2010
@@ -57,6 +57,9 @@
import select
import random
from optparse import OptionParser, OptionValueError
+import io
+import pwd
+import posix
import isc.cc
@@ -108,21 +111,38 @@
when = time.time()
return max(when, self.restart_time)
+class ProcessInfoError(Exception): pass
+
class ProcessInfo:
"""Information about a process"""
dev_null = open(os.devnull, "w")
def __init__(self, name, args, env={}, dev_null_stdout=False,
- dev_null_stderr=False):
+ dev_null_stderr=False, uid=None, username=None):
self.name = name
self.args = args
self.env = env
self.dev_null_stdout = dev_null_stdout
self.dev_null_stderr = dev_null_stderr
self.restart_schedule = RestartSchedule()
+ self.uid = uid
+ self.username = username
self._spawn()
+ def _setuid(self):
+ """Function used before running a program that needs to run as a
+ different user."""
+ if self.uid is not None:
+ try:
+ posix.setuid(self.uid)
+ except OSError as e:
+ if e.errno == errno.EPERM:
+ # if we failed to change user due to permission report that
+ raise ProcessInfoError("Unable to change to user %s (uid %d)" % (self.username, self.uid))
+ else:
+ # otherwise simply re-raise whatever error we found
+ raise
def _spawn(self):
if self.dev_null_stdout:
@@ -138,14 +158,15 @@
# on construction (self.env).
spawn_env = os.environ
spawn_env.update(self.env)
- if not 'B10_FROM_SOURCE' in os.environ:
+ if 'B10_FROM_SOURCE' not in os.environ:
spawn_env['PATH'] = "@@LIBEXECDIR@@:" + spawn_env['PATH']
self.process = subprocess.Popen(self.args,
stdin=subprocess.PIPE,
stdout=spawn_stdout,
stderr=spawn_stderr,
close_fds=True,
- env=spawn_env,)
+ env=spawn_env,
+ preexec_fn=self._setuid)
self.pid = self.process.pid
self.restart_schedule.set_run_start_time()
@@ -155,7 +176,8 @@
class BoB:
"""Boss of BIND class."""
- def __init__(self, msgq_socket_file=None, auth_port=5300, verbose=False):
+ def __init__(self, msgq_socket_file=None, auth_port=5300, verbose=False,
+ setuid=None, username=None):
"""Initialize the Boss of BIND. This is a singleton (only one
can run).
@@ -171,6 +193,8 @@
self.processes = {}
self.dead_processes = {}
self.runnable = False
+ self.uid = setuid
+ self.username = username
def config_handler(self, new_config):
if self.verbose:
@@ -225,12 +249,14 @@
sys.stdout.write("[bind10] Starting b10-msgq\n")
try:
c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
- True, not self.verbose)
+ True, not self.verbose, uid=self.uid,
+ username=self.username)
except Exception as e:
return "Unable to start b10-msgq; " + str(e)
self.processes[c_channel.pid] = c_channel
if self.verbose:
- sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" % c_channel.pid)
+ sys.stdout.write("[bind10] Started b10-msgq (PID %d)\n" %
+ c_channel.pid)
# now connect to the c-channel
cc_connect_start = time.time()
@@ -250,7 +276,8 @@
sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
try:
bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
- c_channel_env)
+ c_channel_env, uid=self.uid,
+ username=self.username)
except Exception as e:
c_channel.process.kill()
return "Unable to start b10-cfgmgr; " + str(e)
@@ -271,23 +298,6 @@
self.ccs.start()
if self.verbose:
sys.stdout.write("[bind10] ccsession started\n")
-
- # start the xfrout before auth-server, to make sure every xfr-query can
- # be processed properly.
- xfrout_args = ['b10-xfrout']
- if self.verbose:
- sys.stdout.write("[bind10] Starting b10-xfrout\n")
- xfrout_args += ['-v']
- try:
- xfrout = ProcessInfo("b10-xfrout", xfrout_args,
- c_channel_env )
- except Exception as e:
- c_channel.process.kill()
- bind_cfgd.process.kill()
- return "Unable to start b10-xfrout; " + str(e)
- self.processes[xfrout.pid] = xfrout
- if self.verbose:
- sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" % xfrout.pid)
# start b10-auth
# XXX: this must be read from the configuration manager in the future
@@ -307,6 +317,28 @@
self.processes[auth.pid] = auth
if self.verbose:
sys.stdout.write("[bind10] Started b10-auth (PID %d)\n" % auth.pid)
+
+ # everything after the authoritative server can run as non-root
+ if self.uid is not None:
+ posix.setuid(self.uid)
+
+ # start the xfrout before auth-server, to make sure every xfr-query can
+ # be processed properly.
+ xfrout_args = ['b10-xfrout']
+ if self.verbose:
+ sys.stdout.write("[bind10] Starting b10-xfrout\n")
+ xfrout_args += ['-v']
+ try:
+ xfrout = ProcessInfo("b10-xfrout", xfrout_args,
+ c_channel_env )
+ except Exception as e:
+ c_channel.process.kill()
+ bind_cfgd.process.kill()
+ return "Unable to start b10-xfrout; " + str(e)
+ self.processes[xfrout.pid] = xfrout
+ if self.verbose:
+ sys.stdout.write("[bind10] Started b10-xfrout (PID %d)\n" %
+ xfrout.pid)
# start b10-xfrin
xfrin_args = ['b10-xfrin']
@@ -324,7 +356,8 @@
return "Unable to start b10-xfrin; " + str(e)
self.processes[xfrind.pid] = xfrind
if self.verbose:
- sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" % xfrind.pid)
+ sys.stdout.write("[bind10] Started b10-xfrin (PID %d)\n" %
+ xfrind.pid)
# start the b10-cmdctl
# XXX: we hardcode port 8080
@@ -344,7 +377,8 @@
return "Unable to start b10-cmdctl; " + str(e)
self.processes[cmd_ctrld.pid] = cmd_ctrld
if self.verbose:
- sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" % cmd_ctrld.pid)
+ sys.stdout.write("[bind10] Started b10-cmdctl (PID %d)\n" %
+ cmd_ctrld.pid)
self.runnable = True
@@ -435,11 +469,16 @@
sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
def restart_processes(self):
- """Restart any dead processes."""
+ """Restart any dead processes.
+ Returns the time when the next process is ready to be restarted.
+ If the server is shutting down, returns 0.
+ If there are no processes, returns None.
+ The values returned can be safely passed into select() as the
+ timeout value."""
next_restart = None
# if we're shutting down, then don't restart
if not self.runnable:
- return next_restart
+ return 0
# otherwise look through each dead process and try to restart
still_dead = {}
now = time.time()
@@ -510,6 +549,10 @@
def main():
global options
global boss_of_bind
+ # Enforce line buffering on stdout, even when not a TTY
+ sys.stdout = io.TextIOWrapper(sys.stdout.detach(), line_buffering=True)
+
+
# Parse any command-line options.
parser = OptionParser(version=__version__)
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
@@ -520,7 +563,42 @@
parser.add_option("-m", "--msgq-socket-file", dest="msgq_socket_file",
type="string", default=None,
help="UNIX domain socket file the b10-msgq daemon will use")
+ parser.add_option("-u", "--user", dest="user",
+ type="string", default=None,
+ help="Change user after startup (must run as root)")
(options, args) = parser.parse_args()
+ if args:
+ parser.print_help()
+ sys.exit(1)
+
+ # Check user ID.
+ setuid = None
+ username = None
+ if options.user:
+ # Try getting information about the user, assuming UID passed.
+ try:
+ pw_ent = pwd.getpwuid(int(options.user))
+ setuid = pw_ent.pw_uid
+ username = pw_ent.pw_name
+ except ValueError:
+ pass
+ except KeyError:
+ pass
+
+ # Next try getting information about the user, assuming user name
+ # passed.
+ # If the information is both a valid user name and user number, we
+ # prefer the name because we try it second. A minor point, hopefully.
+ try:
+ pw_ent = pwd.getpwnam(options.user)
+ setuid = pw_ent.pw_uid
+ username = pw_ent.pw_name
+ except KeyError:
+ pass
+
+ if setuid is None:
+ sys.stderr.write("bind10: invalid user: '%s'\n" % options.user)
+ sys.exit(1)
# Announce startup.
if options.verbose:
@@ -543,11 +621,12 @@
# Go bob!
boss_of_bind = BoB(options.msgq_socket_file, int(options.auth_port),
- options.verbose)
+ options.verbose, setuid, username)
startup_result = boss_of_bind.startup()
if startup_result:
sys.stderr.write("[bind10] Error on startup: %s\n" % startup_result)
sys.exit(1)
+ sys.stdout.write("[bind10] BIND 10 started\n")
# In our main loop, we check for dead processes or messages
# on the c-channel.
@@ -584,6 +663,7 @@
# shutdown
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
boss_of_bind.shutdown()
+ sys.exit(0)
if __name__ == "__main__":
main()
Modified: experiments/python-binding/src/bin/bind10/tests/bind10_test.in
==============================================================================
--- experiments/python-binding/src/bin/bind10/tests/bind10_test.in (original)
+++ experiments/python-binding/src/bin/bind10/tests/bind10_test.in Wed Jun 30 13:47:21 2010
@@ -27,5 +27,6 @@
export PYTHONPATH
cd ${BIND10_PATH}/tests
-exec ${PYTHON_EXEC} -O bind10_test.py $*
+${PYTHON_EXEC} -O bind10_test.py $*
+exec ${PYTHON_EXEC} -O args_test.py $*
Modified: experiments/python-binding/src/bin/bindctl/bindcmd.py
==============================================================================
--- experiments/python-binding/src/bin/bindctl/bindcmd.py (original)
+++ experiments/python-binding/src/bin/bindctl/bindcmd.py Wed Jun 30 13:47:21 2010
@@ -87,7 +87,7 @@
'''Generate one session id for the connection. '''
rand = os.urandom(16)
now = time.time()
- session_id = sha1(("%s%s%s" %(rand, now,
+ session_id = sha1(("%s%s%s" %(rand, now,
socket.gethostname())).encode())
digest = session_id.hexdigest()
return digest
Modified: experiments/python-binding/src/bin/cfgmgr/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/cfgmgr/Makefile.am (original)
+++ experiments/python-binding/src/bin/cfgmgr/Makefile.am Wed Jun 30 13:47:21 2010
@@ -1,8 +1,10 @@
+SUBDIRS = tests
+
pkglibexecdir = $(libexecdir)/@PACKAGE@
pkglibexec_SCRIPTS = b10-cfgmgr
-CLEANFILES = b10-cfgmgr
+CLEANFILES = b10-cfgmgr b10-cfgmgr.pyc
b10_cfgmgrdir = @localstatedir@/@PACKAGE@
#B10_cfgmgr_DATA =
Modified: experiments/python-binding/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- experiments/python-binding/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ experiments/python-binding/src/bin/cfgmgr/b10-cfgmgr.py.in Wed Jun 30 13:47:21 2010
@@ -14,6 +14,8 @@
# 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$
import sys; sys.path.append ('@@PYTHONPATH@@')
@@ -38,7 +40,8 @@
if cm:
cm.running = False
-if __name__ == "__main__":
+def main():
+ global cm
try:
cm = ConfigManager(DATA_PATH)
signal.signal(signal.SIGINT, signal_handler)
@@ -53,3 +56,6 @@
print("[b10-cfgmgr] Interrupted, exiting")
if cm:
cm.write_config()
+
+if __name__ == "__main__":
+ main()
Modified: experiments/python-binding/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- experiments/python-binding/src/bin/cmdctl/cmdctl.py.in (original)
+++ experiments/python-binding/src/bin/cmdctl/cmdctl.py.in Wed Jun 30 13:47:21 2010
@@ -416,7 +416,7 @@
def run(addr = 'localhost', port = 8080, idle_timeout = 1200, verbose = False):
''' Start cmdctl as one https server. '''
if verbose:
- sys.stdout.write("[b10-cmdctl] starting on :%s port:%d\n" %(addr, port))
+ sys.stdout.write("[b10-cmdctl] starting on %s port:%d\n" %(addr, port))
httpd = SecureHTTPServer((addr, port), SecureHTTPRequestHandler, idle_timeout, verbose)
httpd.serve_forever()
Modified: experiments/python-binding/src/bin/host/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/host/Makefile.am (original)
+++ experiments/python-binding/src/bin/host/Makefile.am Wed Jun 30 13:47:21 2010
@@ -7,7 +7,7 @@
bin_PROGRAMS = host
host_SOURCES = host.cc
-host_LDADD = $(top_builddir)/src/lib/dns/.libs/libdns.a
+host_LDADD = $(top_builddir)/src/lib/dns/.libs/libdns++.a
host_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
#man_MANS = host.1
Modified: experiments/python-binding/src/bin/host/host.cc
==============================================================================
--- experiments/python-binding/src/bin/host/host.cc (original)
+++ experiments/python-binding/src/bin/host/host.cc Wed Jun 30 13:47:21 2010
@@ -19,6 +19,8 @@
#include <sys/time.h> // for gettimeofday
#include <sys/socket.h> // networking functions and definitions on FreeBSD
+#include <unistd.h>
+
#include <string>
#include <iostream>
Modified: experiments/python-binding/src/bin/loadzone/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/loadzone/Makefile.am (original)
+++ experiments/python-binding/src/bin/loadzone/Makefile.am Wed Jun 30 13:47:21 2010
@@ -1,3 +1,5 @@
+SUBDIRS = tests/correct
+SUBDIRS += tests/error
bin_SCRIPTS = b10-loadzone
CLEANFILES = b10-loadzone
@@ -22,23 +24,27 @@
$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
# TODO: permissions handled later
-EXTRA_DIST += testdata/README
-EXTRA_DIST += testdata/dsset-subzone.example.com.
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/example.com.signed
-EXTRA_DIST += testdata/Kexample.com.+005+04456.key
-EXTRA_DIST += testdata/Kexample.com.+005+04456.private
-EXTRA_DIST += testdata/Kexample.com.+005+33495.key
-EXTRA_DIST += testdata/Kexample.com.+005+33495.private
-EXTRA_DIST += testdata/Ksql1.example.com.+005+12447.key
-EXTRA_DIST += testdata/Ksql1.example.com.+005+12447.private
-EXTRA_DIST += testdata/Ksql1.example.com.+005+33313.key
-EXTRA_DIST += testdata/Ksql1.example.com.+005+33313.private
-EXTRA_DIST += testdata/Ksql2.example.com.+005+38482.key
-EXTRA_DIST += testdata/Ksql2.example.com.+005+38482.private
-EXTRA_DIST += testdata/Ksql2.example.com.+005+63192.key
-EXTRA_DIST += testdata/Ksql2.example.com.+005+63192.private
-EXTRA_DIST += testdata/sql1.example.com
-EXTRA_DIST += testdata/sql1.example.com.signed
-EXTRA_DIST += testdata/sql2.example.com
-EXTRA_DIST += testdata/sql2.example.com.signed
+EXTRA_DIST += tests/normal/README
+EXTRA_DIST += tests/normal/dsset-subzone.example.com
+EXTRA_DIST += tests/normal/example.com
+EXTRA_DIST += tests/normal/example.com.signed
+EXTRA_DIST += tests/normal/Kexample.com.+005+04456.key
+EXTRA_DIST += tests/normal/Kexample.com.+005+04456.private
+EXTRA_DIST += tests/normal/Kexample.com.+005+33495.key
+EXTRA_DIST += tests/normal/Kexample.com.+005+33495.private
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+12447.key
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+12447.private
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+33313.key
+EXTRA_DIST += tests/normal/Ksql1.example.com.+005+33313.private
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+38482.key
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+38482.private
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+63192.key
+EXTRA_DIST += tests/normal/Ksql2.example.com.+005+63192.private
+EXTRA_DIST += tests/normal/sql1.example.com
+EXTRA_DIST += tests/normal/sql1.example.com.signed
+EXTRA_DIST += tests/normal/sql2.example.com
+EXTRA_DIST += tests/normal/sql2.example.com.signed
+
+pytest:
+ $(SHELL) tests/correct/correct_test.sh
+ $(SHELL) tests/error/error_test.sh
Modified: experiments/python-binding/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- experiments/python-binding/src/bin/loadzone/b10-loadzone.py.in (original)
+++ experiments/python-binding/src/bin/loadzone/b10-loadzone.py.in Wed Jun 30 13:47:21 2010
@@ -19,7 +19,8 @@
import re, getopt
import isc.datasrc
from isc.datasrc.master import MasterFile
-
+import time
+import os
#########################################################################
# usage: print usage note and exit
#########################################################################
@@ -57,23 +58,32 @@
if len(args) != 1:
usage()
zonefile = args[0]
-
+ verbose = os.isatty(sys.stdout.fileno())
try:
- master = MasterFile(zonefile, initial_origin)
+ master = MasterFile(zonefile, initial_origin, verbose)
except Exception as e:
- print("Error reading zone file: " + str(e))
+ sys.stderr.write("Error reading zone file: %s\n" % str(e))
exit(1)
try:
zone = master.zonename()
+ if verbose:
+ sys.stdout.write("Using SQLite3 database file %s\n" % dbfile)
+ sys.stdout.write("Zone name is %s\n" % zone)
+ sys.stdout.write("Loading file \"%s\"\n" % zonefile)
except Exception as e:
- print("Error reading zone file: " + str(e))
+ sys.stdout.write("\n")
+ sys.stderr.write("Error reading zone file: %s\n" % str(e))
exit(1)
try:
isc.datasrc.sqlite3_ds.load(dbfile, zone, master.zonedata)
+ if verbose:
+ master.closeverbose()
+ sys.stdout.write("\nDone.\n")
except Exception as e:
- print("Error loading database: " + str(e))
+ sys.stdout.write("\n")
+ sys.stderr.write("Error loading database: %s\n"% str(e))
exit(1)
if __name__ == "__main__":
Modified: experiments/python-binding/src/bin/xfrin/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/xfrin/tests/Makefile.am (original)
+++ experiments/python-binding/src/bin/xfrin/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -7,6 +7,6 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python \
+ env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
done
Modified: experiments/python-binding/src/bin/xfrin/xfrin.py.in
==============================================================================
--- experiments/python-binding/src/bin/xfrin/xfrin.py.in (original)
+++ experiments/python-binding/src/bin/xfrin/xfrin.py.in Wed Jun 30 13:47:21 2010
@@ -40,11 +40,14 @@
# installed on the system
if "B10_FROM_BUILD" in os.environ:
SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrin"
+ AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+ AUTH_SPECFILE_PATH = SPECFILE_PATH
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrin.spec"
+AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + "/auth.spec"
__version__ = 'BIND10'
@@ -434,7 +437,18 @@
db_file = args.get('db_file')
if not db_file:
#TODO, the db file path should be got in auth server's configuration
- db_file = '@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3'
+ # if we need access to this configuration more often, we
+ # should add it on start, and not remove it here
+ # (or, if we have writable ds, we might not need this in
+ # the first place)
+ self._cc.add_remote_config(AUTH_SPECFILE_LOCATION)
+ db_file, is_default = self._cc.get_remote_config_value("Auth", "database_file")
+ if is_default and "B10_FROM_BUILD" in os.environ:
+ # this too should be unnecessary, but currently the
+ # 'from build' override isn't stored in the config
+ # (and we don't have writable datasources yet)
+ db_file = os.environ["B10_FROM_BUILD"] + os.sep + "bind10_zones.sqlite3"
+ self._cc.remove_remote_config(AUTH_SPECFILE_LOCATION)
return (zone_name, master_addrinfo, db_file)
Modified: experiments/python-binding/src/bin/xfrout/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/bin/xfrout/tests/Makefile.am (original)
+++ experiments/python-binding/src/bin/xfrout/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -7,6 +7,6 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
+ env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
done
Modified: experiments/python-binding/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- experiments/python-binding/src/bin/xfrout/tests/xfrout_test.py (original)
+++ experiments/python-binding/src/bin/xfrout/tests/xfrout_test.py Wed Jun 30 13:47:21 2010
@@ -75,7 +75,8 @@
def setUp(self):
request = MySocket(socket.AF_INET,socket.SOCK_STREAM)
- self.xfrsess = MyXfroutSession(request, None, None)
+ self.log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
+ self.xfrsess = MyXfroutSession(request, None, None, self.log)
self.xfrsess.server = Dbserver()
self.mdata = bytes(b'\xd6=\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07example\x03com\x00\x00\xfc\x00\x01')
self.sock = MySocket(socket.AF_INET,socket.SOCK_STREAM)
@@ -193,7 +194,7 @@
def test_dns_xfrout_start_formerror(self):
# formerror
- self.assertRaises(MessageTooShort, self.xfrsess.dns_xfrout_start, self.sock, b"\xd6=\x00\x00\x00\x01\x00")
+ self.xfrsess.dns_xfrout_start(self.sock, b"\xd6=\x00\x00\x00\x01\x00")
sent_data = self.sock.readsent()
self.assertEqual(len(sent_data), 0)
@@ -236,26 +237,33 @@
reply_msg = self.sock.read_msg()
self.assertEqual(reply_msg.get_rr_count(Section.ANSWER()), 2)
- # set event
- self.xfrsess.server._shutdown_event.set()
- self.assertRaises(XfroutException, self.xfrsess._reply_xfrout_query, self.getmsg(), self.sock, "example.com.")
+class MyCCSession():
+ def __init__(self):
+ pass
+
+ def get_remote_config_value(self, module_name, identifier):
+ if module_name == "Auth" and identifier == "database_file":
+ return "initdb.file", False
+ else:
+ return "unknown", False
+
class MyUnixSockServer(UnixSockServer):
def __init__(self):
self._lock = threading.Lock()
self._transfers_counter = 0
self._shutdown_event = threading.Event()
- self._db_file = "initdb.file"
self._max_transfers_out = 10
+ self._cc = MyCCSession()
+ self._log = isc.log.NSLogger('xfrout', '', severity = 'critical', log_to_console = False )
class TestUnixSockServer(unittest.TestCase):
def setUp(self):
self.unix = MyUnixSockServer()
def test_updata_config_data(self):
- self.unix.update_config_data({'transfers_out':10, 'db_file':"db.file"})
+ self.unix.update_config_data({'transfers_out':10 })
self.assertEqual(self.unix._max_transfers_out, 10)
- self.assertEqual(self.unix._db_file, "db.file")
def test_get_db_file(self):
self.assertEqual(self.unix.get_db_file(), "initdb.file")
Modified: experiments/python-binding/src/bin/xfrout/xfrout.py.in
==============================================================================
--- experiments/python-binding/src/bin/xfrout/xfrout.py.in (original)
+++ experiments/python-binding/src/bin/xfrout/xfrout.py.in Wed Jun 30 13:47:21 2010
@@ -26,8 +26,10 @@
from socketserver import *
import os
from isc.config.ccsession import *
+from isc.log.log import *
from isc.cc import SessionError
import socket
+import select
import errno
from optparse import OptionParser, OptionValueError
try:
@@ -40,22 +42,25 @@
if "B10_FROM_BUILD" in os.environ:
SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
- UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE"] + "/auth_xfrout_conn"
+ AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
+ UNIX_SOCKET_FILE= os.environ["B10_FROM_BUILD"] + "/auth_xfrout_conn"
else:
PREFIX = "@prefix@"
DATAROOTDIR = "@datarootdir@"
SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+ AUTH_SPECFILE_PATH = SPECFILE_PATH
UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_xfrout_conn"
+
SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
-
+AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
MAX_TRANSFERS_OUT = 10
-verbose_mode = False
-
-
-class XfroutException(Exception): pass
-class TmpException(Exception): pass
+VERBOSE_MODE = False
class XfroutSession(BaseRequestHandler):
+ def __init__(self, request, client_address, server, log):
+ BaseRequestHandler.__init__(self, request, client_address, server)
+ self._log = log
+
def handle(self):
fd = recv_fd(self.request.fileno())
@@ -63,8 +68,7 @@
# This may happen when one xfrout process try to connect to
# xfrout unix socket server, to check whether there is another
# xfrout running.
- print("[b10-xfrout] Failed to receive the FD for XFR connection, "
- "maybe because another xfrout process was started.")
+ self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
return
data_len = self.request.recv(2)
@@ -73,9 +77,8 @@
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
try:
self.dns_xfrout_start(sock, msgdata)
- except TmpException as e:
- if verbose_mode:
- self.log_msg(str(e))
+ except Exception as e:
+ self._log.log_message("error", str(e))
sock.shutdown(socket.SHUT_RDWR)
sock.close()
@@ -88,9 +91,8 @@
try:
msg = Message(Message.PARSE)
Message.from_wire(msg, mdata)
- except TmpException as err:
- if verbose_mode:
- self.log_msg(str(err))
+ except Exception as err:
+ self._log.log_message("error", str(err))
return Rcode.FORMERR(), None
return Rcode.NOERROR(), msg
@@ -180,16 +182,11 @@
return self. _reply_query_with_error_rcode(msg, sock, rcode_)
try:
- if verbose_mode:
- self.log_msg("transfer of '%s/IN': AXFR started" % zone_name)
-
+ self._log.log_message("info", "transfer of '%s/IN': AXFR started" % zone_name)
self._reply_xfrout_query(msg, sock, zone_name)
-
- if verbose_mode:
- self.log_msg("transfer of '%s/IN': AXFR end" % zone_name)
- except TmpException as err:
- if verbose_mode:
- sys.stderr.write("[b10-xfrout] %s\n" % str(err))
+ self._log.log_message("info", "transfer of '%s/IN': AXFR end" % zone_name)
+ except Exception as err:
+ self._log.log_message("error", str(err))
self.server.decrease_transfers_counter()
return
@@ -261,7 +258,7 @@
# the message length to know if the rrset has been added sucessfully.
for rr_data in sqlite3_ds.get_zone_datas(zone_name, self.server.get_db_file()):
if self.server._shutdown_event.is_set(): # Check if xfrout is shutdown
- raise XfroutException("shutdown!")
+ self._log.log_message("error", "shutdown!")
# TODO: RRType.SOA() ?
if RRType(rr_data[5]) == RRType("SOA"): #ignore soa record
@@ -281,21 +278,24 @@
self._send_message_with_last_soa(msg, sock, rrset_soa)
- def log_msg(self, msg):
- print('[b10-xfrout] ', msg)
-
class UnixSockServer(ThreadingUnixStreamServer):
'''The unix domain socket server which accept xfr query sent from auth server.'''
- def __init__(self, sock_file, handle_class, shutdown_event, config_data):
+ def __init__(self, sock_file, handle_class, shutdown_event, config_data, cc, log):
self._remove_unused_sock_file(sock_file)
self._sock_file = sock_file
ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
self._lock = threading.Lock()
self._transfers_counter = 0
self._shutdown_event = shutdown_event
+ self._log = log
self.update_config_data(config_data)
+ self._cc = cc
+
+ def finish_request(self, request, client_address):
+ '''Finish one request by instantiating RequestHandlerClass.'''
+ self.RequestHandlerClass(request, client_address, self, self._log)
def _remove_unused_sock_file(self, sock_file):
'''Try to remove the socket file. If the file is being used
@@ -332,22 +332,27 @@
ThreadingUnixStreamServer.shutdown(self)
try:
os.unlink(self._sock_file)
- except:
- pass
+ except Exception as e:
+ self._log.log_message("error", str(e))
def update_config_data(self, new_config):
'''Apply the new config setting of xfrout module. '''
-
+ self._log.log_message('info', 'update config data start.')
self._lock.acquire()
self._max_transfers_out = new_config.get('transfers_out')
- self._db_file = new_config.get('db_file')
+ self._log.log_message('info', 'max transfer out : %d', self._max_transfers_out)
self._lock.release()
+ self._log.log_message('info', 'update config data complete.')
def get_db_file(self):
- self._lock.acquire()
- file = self._db_file
- self._lock.release()
+ file, is_default = self._cc.get_remote_config_value("Auth", "database_file")
+ # this too should be unnecessary, but currently the
+ # 'from build' override isn't stored in the config
+ # (and we don't have indirect python access to datasources yet)
+ if is_default and "B10_FROM_BUILD" in os.environ:
+ file = os.environ["B10_FROM_BUILD"] + os.sep + "bind10_zones.sqlite3"
return file
+
def increase_transfers_counter(self):
'''Return False, if counter + 1 > max_transfers_out, or else
@@ -367,29 +372,45 @@
self._lock.release()
def listen_on_xfr_query(unix_socket_server):
-
'''Listen xfr query in one single thread. Polls for shutdown
every 0.1 seconds, is there a better time?
'''
- unix_socket_server.serve_forever(poll_interval = 0.1)
+
+ while True:
+ try:
+ unix_socket_server.serve_forever(poll_interval = 0.1)
+ except select.error as err:
+ # serve_forever() calls select.select(), which can be
+ # interrupted.
+ # If it is interrupted, it raises select.error with the
+ # errno set to EINTR. We ignore this case, and let the
+ # normal program flow continue by trying serve_forever()
+ # again.
+ if err.args[0] != errno.EINTR: raise
+
class XfroutServer:
def __init__(self):
self._unix_socket_server = None
+ self._log = None
self._listen_sock_file = UNIX_SOCKET_FILE
self._shutdown_event = threading.Event()
self._cc = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
+ self._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
self._config_data = self._cc.get_full_config()
self._cc.start()
+ self._log = isc.log.NSLogger(self._config_data.get('log_name'), self._config_data.get('log_file'),
+ self._config_data.get('log_severity'), self._config_data.get('log_versions'),
+ self._config_data.get('log_max_bytes'), True)
self._start_xfr_query_listener()
-
def _start_xfr_query_listener(self):
'''Start a new thread to accept xfr query. '''
self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession,
- self._shutdown_event, self._config_data);
+ self._shutdown_event, self._config_data,
+ self._cc, self._log);
listener = threading.Thread(target = listen_on_xfr_query, args = (self._unix_socket_server,))
listener.start()
@@ -403,6 +424,9 @@
continue
self._config_data[key] = new_config[key]
+ if self._log:
+ self._log.update_config(new_config)
+
if self._unix_socket_server:
self._unix_socket_server.update_config_data(self._config_data)
@@ -428,8 +452,7 @@
def command_handler(self, cmd, args):
if cmd == "shutdown":
- if verbose_mode:
- print("[b10-xfrout] Received shutdown command")
+ self._log.log_message("info", "Received shutdown command.")
self.shutdown()
answer = create_answer(0)
else:
@@ -464,18 +487,18 @@
parser = OptionParser()
set_cmd_options(parser)
(options, args) = parser.parse_args()
- verbose_mode = options.verbose
+ VERBOSE_MODE = options.verbose
set_signal_handler()
xfrout_server = XfroutServer()
xfrout_server.run()
except KeyboardInterrupt:
- print("[b10-xfrout] exit xfrout process")
+ sys.stderr.write("[b10-xfrout] exit xfrout process")
except SessionError as e:
- print('[b10-xfrout] Error creating xfrout, '
- 'is the command channel daemon running?' )
+ sys.stderr.write("[b10-xfrout] Error creating xfrout,"
+ "is the command channel daemon running?")
except ModuleCCSessionError as e:
- print('[b10-xfrout] exit xfrout process:', e)
+ sys.stderr.write("info", '[b10-xfrout] exit xfrout process:', e)
if xfrout_server:
xfrout_server.shutdown()
Modified: experiments/python-binding/src/bin/xfrout/xfrout.spec.pre.in
==============================================================================
--- experiments/python-binding/src/bin/xfrout/xfrout.spec.pre.in (original)
+++ experiments/python-binding/src/bin/xfrout/xfrout.spec.pre.in Wed Jun 30 13:47:21 2010
@@ -12,7 +12,37 @@
"item_name": "db_file",
"item_type": "string",
"item_optional": False,
- "item_default": '@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3'
+ "item_default": "@@LOCALSTATEDIR@@/@PACKAGE@/zone.sqlite3"
+ },
+ {
+ "item_name": "log_name",
+ "item_type": "string",
+ "item_optional": False,
+ "item_default": "Xfrout"
+ },
+ {
+ "item_name": "log_file",
+ "item_type": "string",
+ "item_optional": False,
+ "item_default": "@@LOCALSTATEDIR@@/@PACKAGE@/log/Xfrout.log"
+ },
+ {
+ "item_name": "log_severity",
+ "item_type": "string",
+ "item_optional": False,
+ "item_default": "debug"
+ },
+ {
+ "item_name": "log_versions",
+ "item_type": "integer",
+ "item_optional": False,
+ "item_default": 5
+ },
+ {
+ "item_name": "log_max_bytes",
+ "item_type": "integer",
+ "item_optional": False,
+ "item_default": 1048576
}
],
"commands": [
Modified: experiments/python-binding/src/lib/cc/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/cc/Makefile.am (original)
+++ experiments/python-binding/src/lib/cc/Makefile.am Wed Jun 30 13:47:21 2010
@@ -6,10 +6,12 @@
# error. Unfortunately there doesn't seem to be an easy way to selectively
# avoid the error. As a short term workaround we suppress this warning
# for the entire this module. See also src/bin/auth/Makefile.am.
+if USE_GXX
AM_CXXFLAGS += -Wno-unused-parameter
+endif
-lib_LIBRARIES = libcc.a
-libcc_a_SOURCES = data.cc data.h session.cc session.h
+lib_LTLIBRARIES = libcc.la
+libcc_la_SOURCES = data.cc data.h session.cc session.h
CLEANFILES = *.gcno *.gcda session_config.h
@@ -27,8 +29,8 @@
# TODO: remove PTHREAD_LDFLAGS (and from configure too)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
-run_unittests_LDADD = libcc.a $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
+run_unittests_LDADD = libcc.la $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns++.a
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
endif
Modified: experiments/python-binding/src/lib/cc/session.cc
==============================================================================
--- experiments/python-binding/src/lib/cc/session.cc (original)
+++ experiments/python-binding/src/lib/cc/session.cc Wed Jun 30 13:47:21 2010
@@ -19,6 +19,17 @@
#include <stdint.h>
+// XXX: there seems to be a strange dependency between ASIO and std library
+// definitions. On some platforms if we include std headers before ASIO
+// headers unexpected behaviors will happen.
+// A middle term solution is to generalize our local wrapper interface
+// (currently only available for the auth server), where all such portability
+// issues are hidden, and to have other modules use the wrapper.
+#include <unistd.h> // for some IPC/network system calls
+#include <asio.hpp>
+#include <asio/error_code.hpp>
+#include <asio/system_error.hpp>
+
#include <cstdio>
#include <vector>
#include <iostream>
@@ -28,10 +39,6 @@
#include <boost/bind.hpp>
#include <boost/function.hpp>
-
-#include <asio.hpp>
-#include <asio/error_code.hpp>
-#include <asio/system_error.hpp>
#include <exceptions/exceptions.h>
Modified: experiments/python-binding/src/lib/cc/session_unittests.cc
==============================================================================
--- experiments/python-binding/src/lib/cc/session_unittests.cc (original)
+++ experiments/python-binding/src/lib/cc/session_unittests.cc Wed Jun 30 13:47:21 2010
@@ -15,10 +15,13 @@
// $Id: data_unittests.cc 1899 2010-05-21 12:03:59Z jelte $
#include "config.h"
+
+// XXX: the ASIO header must be included before others. See session.cc.
+#include <asio.hpp>
+
#include <gtest/gtest.h>
#include <session.h>
-#include <asio.hpp>
#include <exceptions/exceptions.h>
using namespace isc::cc;
Modified: experiments/python-binding/src/lib/config/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/config/tests/Makefile.am (original)
+++ experiments/python-binding/src/lib/config/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -2,7 +2,9 @@
AM_CXXFLAGS = $(B10_CXXFLAGS)
# see src/lib/cc/Makefile.am for -Wno-unused-parameter
+if USE_GXX
AM_CXXFLAGS += -Wno-unused-parameter
+endif
CLEANFILES = *.gcno *.gcda
@@ -20,6 +22,9 @@
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
run_unittests_LDADD += libfake_session.la
run_unittests_LDADD += $(top_builddir)/src/lib/config/libcfgclient.la
+# link *only* to data.o from lib/cc (more importantly, don't link in
+# the session class provided there, since we use our own fake_session
+# here)
run_unittests_LDADD += $(top_builddir)/src/lib/cc/data.o
endif
Modified: experiments/python-binding/src/lib/datasrc/data_source.cc
==============================================================================
--- experiments/python-binding/src/lib/datasrc/data_source.cc (original)
+++ experiments/python-binding/src/lib/datasrc/data_source.cc Wed Jun 30 13:47:21 2010
@@ -192,7 +192,7 @@
// Lookup failed
return (false);
}
-
+
// Referral bit is expected, so clear it when checking flags
if ((newtask.flags & ~DataSrc::REFERRAL) != 0) {
return (false);
@@ -202,18 +202,18 @@
}
// Match downward, from the zone apex to the query name, looking for
-// referrals.
+// referrals. Note that we exclude the apex name and query name themselves;
+// they'll be handled in a normal lookup in the zone.
inline bool
hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
QueryTaskPtr task)
{
- const int nlen = task->qname.getLabelCount();
- const int diff = nlen - zonename->getLabelCount();
+ const int diff = task->qname.getLabelCount() - zonename->getLabelCount();
if (diff > 1) {
bool found = false;
RRsetList ref;
- for (int i = diff; i > 1; --i) {
- const Name sub(task->qname.split(i - 1, nlen - i));
+ for (int i = diff - 1; i > 0; --i) {
+ const Name sub(task->qname.split(i));
if (refQuery(sub, q.qclass(), ds, zonename, ref)) {
found = true;
break;
@@ -360,11 +360,11 @@
// Find the closest provable enclosing name for QNAME
Name enclosure(zonename);
- const int nlen = task->qname.getLabelCount();
- const int diff = nlen - enclosure.getLabelCount();
+ const int diff = task->qname.getLabelCount() -
+ enclosure.getLabelCount();
string hash2;
for (int i = 1; i <= diff; ++i) {
- enclosure = task->qname.split(i, nlen - i);
+ enclosure = task->qname.split(i);
string nodehash(nsec3->getHash(enclosure));
if (nodehash == hash1) {
break;
@@ -434,8 +434,7 @@
return (DataSrc::SUCCESS);
}
- const int nlen = task->qname.getLabelCount();
- const int diff = nlen - zonename->getLabelCount();
+ const int diff = task->qname.getLabelCount() - zonename->getLabelCount();
if (diff < 1) {
return (DataSrc::SUCCESS);
}
@@ -445,7 +444,7 @@
bool cname = false;
for (int i = 1; i <= diff; ++i) {
- const Name& wname(star.concatenate(task->qname.split(i, nlen - i)));
+ const Name& wname(star.concatenate(task->qname.split(i)));
QueryTask newtask(wname, task->qclass, task->qtype, Section::ANSWER(),
QueryTask::AUTH_QUERY);
result = doQueryTask(ds, zonename, newtask, wild);
@@ -541,8 +540,7 @@
// (Note that RRtype DS queries need to go to the parent.)
const int nlabels = task->qname.getLabelCount() - 1;
NameMatch match(nlabels != 0 && task->qtype == RRType::DS() ?
- task->qname.split(1, task->qname.getLabelCount() - 1) :
- task->qname);
+ task->qname.split(1) : task->qname);
findClosestEnclosure(match, task->qclass);
const DataSrc* datasource = match.bestDataSrc();
const Name* zonename = match.closestName();
@@ -615,9 +613,12 @@
// the authority section.
RRsetList auth;
if (!refQuery(*zonename, q.qclass(), datasource, zonename,
- auth)) {
- m.setRcode(Rcode::SERVFAIL());
- return;
+ auth) ||
+ !auth.findRRset(RRType::NS(),
+ datasource->getClass())) {
+ isc_throw(DataSourceError,
+ "NS RR not found in " << *zonename << "/" <<
+ datasource->getClass());
}
copyAuth(q, auth);
@@ -706,8 +707,9 @@
result = addSOA(q, zonename, datasource);
if (result != SUCCESS) {
- m.setRcode(Rcode::SERVFAIL());
- return;
+ isc_throw(DataSourceError,
+ "SOA RR not found in" << *zonename <<
+ "/" << datasource->getClass());
}
}
Modified: experiments/python-binding/src/lib/datasrc/sqlite3_datasrc.cc
==============================================================================
--- experiments/python-binding/src/lib/datasrc/sqlite3_datasrc.cc (original)
+++ experiments/python-binding/src/lib/datasrc/sqlite3_datasrc.cc Wed Jun 30 13:47:21 2010
@@ -330,7 +330,7 @@
Sqlite3DataSrc::findClosest(const Name& name, unsigned int* position) const {
const unsigned int nlabels = name.getLabelCount();
for (unsigned int i = 0; i < nlabels; ++i) {
- const Name matchname(name.split(i, nlabels - i));
+ const Name matchname(name.split(i));
const int rc = hasExactZone(matchname.toText().c_str());
if (rc >= 0) {
if (position != NULL) {
@@ -356,9 +356,7 @@
return;
}
- match.update(*this, match.qname().split(position,
- match.qname().getLabelCount() -
- position));
+ match.update(*this, match.qname().split(position));
}
DataSrc::Result
Modified: experiments/python-binding/src/lib/datasrc/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/datasrc/tests/Makefile.am (original)
+++ experiments/python-binding/src/lib/datasrc/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -22,8 +22,8 @@
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
-run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
-run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns++.a
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/.libs/libcc.a
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
endif
Modified: experiments/python-binding/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- experiments/python-binding/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ experiments/python-binding/src/lib/datasrc/tests/datasrc_unittest.cc Wed Jun 30 13:47:21 2010
@@ -540,6 +540,15 @@
EXPECT_TRUE(it->isLast());
}
+TEST_F(DataSrcTest, DnameExact) {
+ // The example.org test zone has a DNAME RR for dname2.foo.example.org.
+ // A query for that name with a different RR type than DNAME shouldn't
+ // confuse delegation processing.
+ createAndProcessQuery(Name("dname2.foo.example.org"), RRClass::IN(),
+ RRType::A());
+ headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 1, 0);
+}
+
TEST_F(DataSrcTest, Cname) {
readAndProcessQuery("q_cname");
@@ -761,7 +770,7 @@
}
TEST_F(DataSrcTest, CNAMELoop) {
- createAndProcessQuery(Name("loop1.example.com"), RRClass::IN(),
+ createAndProcessQuery(Name("one.loop.example"), RRClass::IN(),
RRType::A());
}
@@ -843,8 +852,8 @@
EXPECT_EQ(0, ds.dataSrcCount());
}
-#if 0 // currently fails
-TEST_F(DataSrcTest, synthesizedCnameTooLong) {
+// currently fails
+TEST_F(DataSrcTest, DISABLED_synthesizedCnameTooLong) {
// qname has the possible max length (255 octets). it matches a DNAME,
// and the synthesized CNAME would exceed the valid length.
createAndProcessQuery(
@@ -854,6 +863,23 @@
"0123456789abcdef0123456789abcdef0123456789a.dname.example.org."),
RRClass::IN(), RRType::A());
}
-#endif
-
-}
+
+TEST_F(DataSrcTest, noNSZone) {
+ EXPECT_THROW(createAndProcessQuery(Name("www.nons.example"),
+ RRClass::IN(), RRType::A()),
+ DataSourceError);
+}
+
+TEST_F(DataSrcTest, noNSButDnameZone) {
+ EXPECT_THROW(createAndProcessQuery(Name("www.nons-dname.example"),
+ RRClass::IN(), RRType::A()),
+ DataSourceError);
+}
+
+TEST_F(DataSrcTest, noSOAZone) {
+ EXPECT_THROW(createAndProcessQuery(Name("notexist.nosoa.example"),
+ RRClass::IN(), RRType::A()),
+ DataSourceError);
+}
+
+}
Modified: experiments/python-binding/src/lib/datasrc/tests/test_datasrc.cc
==============================================================================
--- experiments/python-binding/src/lib/datasrc/tests/test_datasrc.cc (original)
+++ experiments/python-binding/src/lib/datasrc/tests/test_datasrc.cc Wed Jun 30 13:47:21 2010
@@ -17,6 +17,8 @@
#include "config.h"
#include <cassert>
+
+#include <algorithm>
#include <dns/tests/unittest_util.h>
#include "test_datasrc.h"
@@ -45,69 +47,297 @@
namespace datasrc {
namespace {
-const Name example("example.com");
-const Name sql1("sql1.example.com");
-const Name www_sql1("www.sql1.example.com");
-const Name www("www.example.com");
-const Name foo("foo.example.com");
-const Name dns01("dns01.example.com");
-const Name dns02("dns02.example.com");
-const Name dns03("dns03.example.com");
-const Name cnameint("cname-int.example.com");
-const Name cnameext("cname-ext.example.com");
-const Name dname("dname.example.com");
-const Name wild("*.wild.example.com");
-const Name wild2("*.wild2.example.com");
-const Name wild3("*.wild3.example.com");
-const Name subzone("subzone.example.com");
-const Name loop1("loop1.example.com");
-const Name loop2("loop2.example.com");
-
-RRsetPtr example_ns;
-RRsetPtr example_soa;
-RRsetPtr example_nsec;
-RRsetPtr www_a;
-RRsetPtr www_nsec;
-RRsetPtr foo_cname;
-RRsetPtr foo_nsec;
-RRsetPtr cnameint_cname;
-RRsetPtr cnameint_nsec;
-RRsetPtr cnameext_cname;
-RRsetPtr cnameext_nsec;
-RRsetPtr dns01_a;
-RRsetPtr dns01_nsec;
-RRsetPtr dns02_a;
-RRsetPtr dns02_nsec;
-RRsetPtr dns03_a;
-RRsetPtr dns03_nsec;
-RRsetPtr wild_a;
-RRsetPtr wild_nsec;
-RRsetPtr wild2_cname;
-RRsetPtr wild2_nsec;
-RRsetPtr wild3_cname;
-RRsetPtr wild3_nsec;
-RRsetPtr dname_dname;
-RRsetPtr dname_nsec;
-RRsetPtr sql1_ns;
-RRsetPtr sql1_soa;
-RRsetPtr sql1_nsec;
-RRsetPtr sql1_ds;
-RRsetPtr sql1_ds_nsec;
-RRsetPtr www_sql1_a;
-RRsetPtr www_sql1_nsec;
-RRsetPtr subzone_ns;
-RRsetPtr subzone_nsec;
-RRsetPtr subzone_glue1;
-RRsetPtr subzone_glue2;
-RRsetPtr subzone_ds;
-RRsetPtr loop1_cname;
-RRsetPtr loop2_cname;
+
+// This is a mock data source for testing. It can contain multiple zones.
+// The content of each zone should be configured in the form of RRData{}.
+// Each RRData element is a tuple of char strings, representing
+// "name, RRtype, RDATA". For simplicity we use the same single TTL for
+// RRs (TEST_TTL) defined below.
+// Multiple RRs of the same pair of (name, RRtype) can be defined, but
+// they must not be interleaved with other types of pair. For example,
+// This is okay:
+// {"example.com", "AAAA", "2001:db8::1"},
+// {"example.com", "AAAA", "2001:db8::2"},
+// ...
+// but this is invalid:
+// {"example.com", "AAAA", "2001:db8::1"},
+// {"example.com", "A", "192.0.2.1"},
+// {"example.com", "AAAA", "2001:db8::2"},
+// ...
+// If an RRset is associated with an RRSIG, the RRSIG must immediately follow
+// the RRset to be signed. Currently, only one (or zero) RRSIG can be
+// specified per RRset.
+//
+// Names are sorted internally, and don't have to be sorted in the data.
+//
+// A zone is defined in the form of ZoneData{}, which contains:
+// zone name (character string)
+// RRclass (character string)
+// A pointer to in-zone RRs in the form of RRData{}
+// A pointer to glue RRs in the form of RRData{}
+// Glues can be omitted, in which case a convenient constant "empty_records"
+// can be specified.
+
+// For simplicity we use the same single TTL for all test RRs.
+const uint32_t TEST_TTL = 3600;
+
+struct RRData {
+ const char* const name;
+ const char* const rrtype;
+ const char* const rdata;
+};
+
+struct ZoneData {
+ const char* const zone_name;
+ const char* const rrclass;
+ const struct RRData* records;
+ const struct RRData* glue_records;
+};
+
+//
+// zone data for example.com
+//
+const struct RRData example_com_records[] = {
+ // example.com
+ {"example.com", "NS", "dns01.example.com"},
+ {"example.com", "NS", "dns02.example.com"},
+ {"example.com", "NS", "dns03.example.com"},
+ {"example.com", "RRSIG", "NS 5 2 3600 20100322084538 20100220084538 33495 example.com. ClcrfjkQZUY5L6ZlCkU3cJHzcrEGrofKSVeeoeZ+w6yeEowFNVXs2YBo3tom53DiCrdD9rs3feVSLGW5rjsz/O6lDuomgQG+EVSnWa7GTIPBXj1BmDXXp3XxeldYmhf4UzaN5BA+RUA5E8NChNKuNNof76j2S9tilfN/kvpy4fw="},
+ {"example.com", "SOA", "master.example.com. admin.example.com. 1234 3600 1800 2419200 7200"},
+ {"example.com", "RRSIG", "SOA 5 2 3600 20100322084538 20100220084538 33495 example.com. KUun66Qaw36osk2BJS6U1fAy3PPDkNo2QK4meGNbDBY8q8b+f2o+IXJ14YCvssGl1ORW0CcLnDRxssnk8V/Svmj5iFhO+8HC2hnVBdi2zewvdVtwRb+lWwKN7pkXXwuy6g1t9WCd/j5FCc/wgxqtZUTPb6XgZcnHrORDMOTqLs4="},
+ {"example.com", "NSEC", "cname-ext.example.com. NS SOA MX RRSIG NSEC DNSKEY"},
+ {"example.com", "RRSIG", "NSEC 5 2 7200 20100322084538 20100220084538 33495 example.com. KxuVaPPKNPJzr/q+cJPiNlkHVTQK0LVsgTbSqruXQc25lAd0wn5oKUtxL1bEAchHkfA8eLzcYCj2ZqqAv9OJubw53mfskTad7UHs4Uj2RTrIsNGMCiZGgOpvNb9JcWpQtoyXVT1uNse+Qsbeir0eyeYIufUynFU041jtNrlJMio="},
+
+ // dns01.example.com
+ {"dns01.example.com", "A", "192.0.2.1"},
+ {"dns01.example.com", "RRSIG", "A 5 3 3600 20100322084538 20100220084538 33495 example.com. NIawlZLk8WZAjNux7oQM2mslfW52OZFFkWt++7FHu2SU98XqEeKfCMnpgtWe5T8Nr9cS8df901iEOJoWQzGTEaHYUBtEhsSjBVn7mKp3fz6473a2xxy75SUKZ0rxjNXSZ8Q5rnFmkX0HTH2Sg51mtjH6aC2pfheQnA2t193BnSg="},
+ {"dns01.example.com", "NSEC", "dns02.example.com. A RRSIG NSEC"},
+ {"dns01.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. EkyeshmMNP9xiAz6mDFDIwksTdmkF9zsFzLuVKAgK6eUk7St6tp5PSvjA8nWol0vdvvz4LK85a4ffTFEiNRyvWeYP2vOhEkyDcrwuCd8Vc3jh/8Sm1Js+nX7hJStrZGFvp2TWPpt9nKH5p3MxXvTb/YVurnue0xSeFAE17O3+I0="},
+
+ // dns02.example.com
+ {"dns02.example.com", "A", "192.0.2.2"},
+ {"dns02.example.com", "RRSIG", "A 5 3 3600 20100322084538 20100220084538 33495 example.com. XJtVMbUIRE0mk6Hn/Nx6k36jaxaBDPK2/IYB6vCQjJETz6gW4T6q/H/eY9/Lsw5iYPFhoBRDxT4XFj575t98kELXnJe1WhuMbRPlOhyOjxkLECaUne/sbFPOtbGFx9ohuojI0RgxxZiCFaO8wJuv6nfPuzmlLajWS6z9NZeOMIk="},
+ {"dns02.example.com", "NSEC", "dns03.example.com. A RRSIG NSEC"},
+ {"dns02.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. imBNTMB3sPU4kblcaAH6V7lCVt5xgtAybi3DA/SbLEulLaV2NE6vcoEn/AieaM4mOJicQnUDj/H+1hSEhzxU2tRM8zfVlvztxQWn6eh7ZR4mKfNDSvRUGU9ykhpwMyC7wjOt1j5bcSA/OTnLRAilslnJyOM4bSaxVEFo8YPjncY="},
+
+ // dns03.example.com
+ {"dns03.example.com", "A", "192.0.2.3"},
+ {"dns03.example.com", "RRSIG", "A 5 3 3600 20100322084538 20100220084538 33495 example.com. Ubrcm1H+F6m8khle7P9zU8eO+Jtuj+1Vx1MM5KAkmZPJwQe9uTcoCpQa6DXOGG9kajDTnNN1Be1gkZuJDTZJG4SmJLXLbNY3RDnxpGmWta3qs/VgDq78/YM8ropt1/s7YKyrCfGE2ff+FUB0mLObiG01ZV2gu5HJzgE7SEWLEiI="},
+ {"dns03.example.com", "NSEC", "foo.example.com. A RRSIG NSEC"},
+ {"dns03.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. nn829Xw5CJFnPHwI9WHeT5epQv+odtCkHnjlPFGoPTLOyiks+041UmMqtq3uiSp4d2meMSe9UuDvoROT0L6NTtQQvVqiDhTn0irTFw1uw7fO8ZTG7eyu6Ypfz0+HvfbNvd4kMoD2OTgADRXPVsCTwK+PBOIIG9YTEQfl8pCqW5g="},
+
+ // www.example.com
+ {"www.example.com", "A", "192.0.2.1"},
+ {"www.example.com", "RRSIG", "A 5 3 3600 20100322084538 20100220084538 33495 example.com. qyFyyV/mE8x4pdhudr5iycwhDsva31MzwO1kBR+bDKvzJg8mN8KxlPZrOlNNUhd3YRXQVwieMyxOTWRPXoxrNEDkNwimXkfe3rrHY7ibV9eNS4OIBUjb44VjCNr9CmQSzfuQ2yxO2r+YIuPYHRCjieD4xh6t9ay4IaCN/tDAJ+Q="},
+ {"www.example.com", "NSEC", "example.com. A RRSIG NSEC"},
+ {"www.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. ZLZlSVBa2oe4U+7SZASnypP2VkI5gg1/1cVGqYUvfYNIUkcVMWDgn7DZCfpmo+2vdlV/4VhAc+sjDd+X+e57XGnW8+lqZHvG6NMMhmSGmeATD3D+8lEJJGo0dxoN4rHJQyp/eT2S4nChz+D/ze+YRagYxGF7pXm9zcrw3kKZGTs="},
+
+ // *.wild.example.com
+ {"*.wild.example.com", "A", "192.0.2.2"},
+ {"*.wild.example.com", "RRSIG", "A 5 3 3600 20100322084538 20100220084538 33495 example.com. FdO+UWONgtLKFxUzzygGunw67F9y8SzsP7yOLEYVJclRR8X3Ii62L0gtQHq2y0TcKsXttRsD6XY+tM5P/pgXlTNi7Bk4Fgb0PIDPjOsfT4DrS80kWn0YbinM/4/FA1j5ru5sTTboOY5UGhvDnoA9ogNuQQYb2/3wkoH0PrA2Q/0="},
+ {"*.wild.example.com", "NSEC", "*.wild2.example.com. A RRSIG NSEC"},
+ {"*.wild.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. OoGYslRj4xjZnBuzgOqsrvkDAHWycmQzbUxCRmgWnCbXiobJK7/ynONH3jm8G3vGlU0lwpHkhNs6cUK+6Nu8W49X3MT0Xksl/brroLcXYLi3vfxnYUNMMpXdeFl6WNNfoJRo90F/f/TWXAClRrDS29qiG3G1PEJZikIxZsZ0tyM="},
+
+ // *.wild2.example.com
+ {"*.wild2.example.com", "CNAME", "www.example.com"},
+ {"*.wild2.example.com", "RRSIG", "CNAME 5 3 3600 20100410212307 20100311212307 33495 example.com. pGHtGdRBi4GKFSKszi6SsKvuBLDX8dFhZubU0tMojQ9SJuiFNF+WtxvdAYuUaoWP/9VLUaYmiw5u7JnzmR84DiXZPEs6DtD+UJdOZhaS7V7RTpE+tMOfVQBLpUnRWYtlTTmiBpFquzf3DdIxgUFhEPEuJJyp3LFRxJObCaq9 nvI="},
+ {"*.wild2.example.com", "NSEC", "*.wild3.example.com. CNAME RRSIG NSEC"},
+ {"*.wild2.example.com", "RRSIG", "NSEC 5 3 7200 20100410212307 20100311212307 33495 example.com. EuSzh6or8mbvwru2H7fyYeMpW6J8YZ528rabU38V/lMN0TdamghIuCneAvSNaZgwk2MSN1bWpZqB2kAipaM/ZI9/piLlTvVjjOQ8pjk0auwCEqT7Z7Qng3E92O9yVzO+WHT9QZn/fR6t60392In4IvcBGjZyjzQk8njIwbui xGA="},
+
+ // *.wild3.example.com -- a wildcard record with a lame CNAME
+ {"*.wild3.example.com", "CNAME", "spork.example.com"},
+ {"*.wild3.example.com", "RRSIG", "CNAME 5 3 3600 20100410212307 20100311212307 33495 example.com. pGHtGdRBi4GKFSKszi6SsKvuBLDX8dFhZubU0tMojQ9SJuiFNF+WtxvdAYuUaoWP/9VLUaYmiw5u7JnzmR84DiXZPEs6DtD+UJdOZhaS7V7RTpE+tMOfVQBLpUnRWYtlTTmiBpFquzf3DdIxgUFhEPEuJJyp3LFRxJObCaq9 nvI="},
+ {"*.wild3.example.com", "NSEC", "www.example.com. CNAME RRSIG NSEC"},
+ {"*.wild3.example.com", "RRSIG", "NSEC 5 3 7200 20100410212307 20100311212307 33495 example.com. EuSzh6or8mbvwru2H7fyYeMpW6J8YZ528rabU38V/lMN0TdamghIuCneAvSNaZgwk2MSN1bWpZqB2kAipaM/ZI9/piLlTvVjjOQ8pjk0auwCEqT7Z7Qng3E92O9yVzO+WHT9QZn/fR6t60392In4IvcBGjZyjzQk8njIwbui xGA="},
+
+ // foo.example.com
+ {"foo.example.com", "CNAME", "cnametest.flame.org"},
+ {"foo.example.com", "RRSIG", "CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. DSqkLnsh0gCeCPVW/Q8viy9GNP+KHmFGfWqyVG1S6koBtGN/VQQ16M4PHZ9Zssmf/JcDVJNIhAChHPE2WJiaPCNGTprsaUshf1Q2vMPVnkrJKgDY8SVRYMptmT8eaT0gGri4KhqRoFpMT5OYfesybwDgfhFSQQAh6ps3bIUsy4o="},
+ {"foo.example.com", "NSEC", "mail.example.com. CNAME RRSIG NSEC"},
+ {"foo.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. RTQwlSqui6StUYye1KCSOEr1d3irndWFqHBpwP7g7n+w8EDXJ8I7lYgwzHvlQt6BLAxe5fUDi7ct8M5hXvsm7FoWPZ5wXH+2/eJUCYxIw4vezKMkMwBP6M/YkJ2CMqY8DppYf60QaLDONQAr7AcK/naSyioeI5h6eaoVitUDMso="},
+
+ // cname-int.example.com
+ {"cname-int.example.com", "CNAME", "www.example.com."},
+ {"cname-int.example.com", "RRSIG", "CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. U1wjt0XY9xjTwvUmWSUcfLGMhCjfX2ylWfHrycy50x2oxcK9z94E1ejen9wDTIEBSGYgi6wpZ8RK0+02N1DWTGpDqNXd7aFRfDrWQJ/q/XJHDx0vlcmhkWhrT82LBfKxkrptOzchuSo/c0mpK+mpiIMc1VOwY+yuQ2ALfcD6EHw="},
+ {"cname-int.example.com", "NSEC", "dname.example.com. CNAME RRSIG NSEC"},
+ {"cname-int.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. rbV+gaxfrsoha59NOLF4EFyWQ+GuFCVK/8D77x1atan3HNlXBlZ1smgudKTaJ3CtlobIDt0MEdPxY1yn2Tskw/5mlP1PWf8oaP3BwGSQdn4gLI8+sMpNOPFEdXpxqxngm2F6/7fqniL1QuSAQBEdO+5UiCAgnncPmAsSJg3u1zg="},
+
+ // cname-ext.example.com
+ {"cname-ext.example.com", "CNAME", "www.sql1.example.com"},
+ {"cname-ext.example.com", "RRSIG", "CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. bGPIuZilyygvTThK4BrdECuaBcnZUgW/0d09iN2CrNjckchQl3dtbnMNirFsVs9hShDSldRNlQpiAVMpnPgXHhReNum7jmX6yqIH6s8GKIo91zr3VL/ramlezie5w4MilDHrxXLK2pb8IHmP+ZHivQ2EtdYQZgETWBWxr5FDfwk="},
+ {"cname-ext.example.com", "NSEC", "cname-int.example.com. CNAME RRSIG NSEC"},
+ {"cname-ext.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. inWsFwSDWG7TakjwbUTzTRpXz0WifelA5Kn3ABk6BVirIPmd+yQoNj2QZBDFAQwhnLPlNws2Oo4vgMsBMyx1Fv5eHgMUuCN3DUDaLlzlPtUb42CjOUa+jZBeTV/Hd7WZrirluASE1QFDprLdSSqoPPfAKvN3pORtW7y580dMOIM="},
+
+ // dname.example.com
+ {"dname.example.com", "DNAME", "sql1.example.com."},
+ {"dname.example.com", "RRSIG", "DNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. ae8U47oaiwWdurkSyzcsCAF6DxBqjukizwF7K7U6lQVMtfoUE14oiAqfj1fjH8YLDOO/Hd1twrd/u0vgjnI1Gg32YTi7cYOzwE912SV1u2B/y0awaQKWPBwOW0aI7vxelt1vMUF81xosiQD04gOIdDBTqbHKcDxum87iWbhk4Ug="},
+ {"dname.example.com", "NSEC", "dns01.example.com. DNAME RRSIG NSEC"},
+ {"dname.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. c21Fff2D8vBrLzohBnUeflkaRdUAnUxAFGp+UQ0miACDCMOFBlCS9v9g/2+orOnKfd3l4vyz55C310t8JXgXb119ofaZWj2zkdUe+X8Bax+sMS0Y5K/sUhSNvbJbozr9UYPdvjSVBiWgh3s9fsb+etKq9uFukAzGU/FuGYpO0r0="},
+
+ // subzone.example.com
+ {"subzone.example.com", "NS", "ns1.subzone.example.com"},
+ {"subzone.example.com", "NS", "ns2.subzone.example.com"},
+ {"subzone.example.com", "NSEC", "*.wild.example.com. NS DS RRSIG NSEC"},
+ {"subzone.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. Oe2kgIhsLtPJ4+lDZDxznV8/vEVoXKOBFN9lwWyebaKa19BaSXlQ+YVejmulmKDDjEucMvEfuItfn6w7bnU+DzOLk5D1lJCjwDlKz8u3xOAx16TiuQn4bgQAOiFtBQygmGGqO3BVpX+jxsmw7eH3emofy8uUqr/C4aopnwuf28g="},
+ {"subzone.example.com", "DS", "33313 5 1 0FDD7A2C11AA7F55D50FBF9B7EDDA2322C541A8D"},
+ {"subzone.example.com", "DS", "33313 5 2 00B99B7006F496D135B01AB17EDB469B4BE9E1973884DEA757BC4E3015A8C3AB"},
+ {"subzone.example.com", "RRSIG", "DS 5 3 3600 20100322084538 20100220084538 33495 example.com. dIqZKvpkJN1l92SOiWgJh3KbjErIN+EfojMsm4pEdV5xQdZwj6DNNEu6Kw4rRwdvrZIu0TyqPr3jSJb7o6R7vZgZzmLfVV/ojQah7rwuYHCFcfyZ4JyK2311fMhRR1QAvMsdcjdyA1XC140Cm6AnL3cH5rh/KUks/0ec3Ca7GNQ="},
+
+ // subset of child zone: sql1
+ {"sql1.example.com", "NS", "dns01.example.com"},
+ {"sql1.example.com", "NS", "dns02.example.com"},
+ {"sql1.example.com", "NS", "dns03.example.com"},
+
+ {"sql1.example.com", "DS", "33313 5 1 0FDD7A2C11AA7F55D50FBF9B7EDDA2322C541A8D"},
+ {"sql1.example.com", "DS", "33313 5 2 00B99B7006F496D135B01AB17EDB469B4BE9E1973884DEA757BC4E3015A8C3AB"},
+ {"sql1.example.com", "RRSIG", "DS 5 3 3600 20100322084538 20100220084538 33495 example.com. dIqZKvpkJN1l92SOiWgJh3KbjErIN+EfojMsm4pEdV5xQdZwj6DNNEu6Kw4rRwdvrZIu0TyqPr3jSJb7o6R7vZgZzmLfVV/ojQah7rwuYHCFcfyZ4JyK2311fMhRR1QAvMsdcjdyA1XC140Cm6AnL3cH5rh/KUks/0ec3Ca7GNQ="},
+ {"sql1.example.com", "NSEC", "subzone.example.com. NS DS RRSIG NSEC"},
+ {"sql1.example.com", "RRSIG", "NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. k9FRdFyk/cPdkmmaoZbGZPpzIzfbFWQ3QCHd2qhJa0xAXaEOT/GBL6aFqx9SlunDu2wgES+To5fWPZGi4NzWpp6c5t27rnATN/oCEQ/UYIJKmWbqrXdst0Ps5boznk7suK2Y+km31KxaIf3fDd/T3kZCVsR0aWKRRRatPb7GfLw="},
+
+ {NULL, NULL, NULL}
+};
+const struct RRData example_com_glue_records[] = {
+ {"ns1.subzone.example.com", "A", "192.0.2.1"},
+ {"ns2.subzone.example.com", "A", "192.0.2.2"},
+ {NULL, NULL, NULL}
+};
+
+//
+// zone data for sql1.example.com
+//
+const struct RRData sql1_example_com_records[] = {
+ {"sql1.example.com", "NS", "dns01.example.com"},
+ {"sql1.example.com", "NS", "dns02.example.com"},
+ {"sql1.example.com", "NS", "dns03.example.com"},
+ {"sql1.example.com", "RRSIG", "NS 5 3 3600 20100322084536 20100220084536 12447 sql1.example.com. 0CL8noy0NSgoWwuKd+Dc6vyIIw2BrAEBx0IJzcSB6GlB25x/zjEd6AJG0be13HN6jOaTX8iWTuCVrEYuXg76V+M4EvTZHjEScj0az74TrDv4Vdo459paGKCX9B8NLJW1mW4fzZrrXQ8jmBEZeS91Q5rJrO+UKJEuUz3LYdTPvao="},
+ {"sql1.example.com", "SOA", "master.example.com. admin.example.com. 678 3600 1800 2419200 7200"},
+ {"sql1.example.com", "RRSIG", "SOA 5 3 3600 20100322084536 20100220084536 12447 sql1.example.com. oakulfyljL/RAKgCKXEZ3KsG8BJj5WG4JK4moWFB6c9OKem6jIk8hKP2XlUVXFuOYJlRdIM4KicmR2GAK+5jJp6z5ShssstYTXo3QosVm6oCKumuFeLFHzcjfqP1D+F9NsvHldJIBnS/4ebPkmR5OENyCZXQF5HmN2awIj4CLjE="},
+ {"sql1.example.com", "NSEC", "www.sql1.example.com. NS SOA RRSIG NSEC DNSKEY"},
+ {"sql1.example.com", "RRSIG", "NSEC 5 3 7200 20100322084536 20100220084536 12447 sql1.example.com. v71CgdTYccCiTqfRcn6HsvISQa8ruvUfCKtpwym0RW/G27xlZn8otj2IMtWwkLxti8Rqqu+PTViLaOIbeVfHBcqzAd7U59cAOYoq3ODZx6auiE3C23HAKqUavKcP7Esaajm1cbcWy6Kyie4CAZc8M7EeKxgkXMKJGqBQzF+/FOo="},
+
+ // www.sql1.example.com
+ {"www.sql1.example.com", "A", "192.0.2.2"},
+ {"www.sql1.example.com", "RRSIG", "A 5 4 3600 20100322084536 20100220084536 12447 sql1.example.com. DNdVKxB3oBsB14NPoV9WG14Y/g4zMcIXLYnFjj9vRZRZJpAvbTEipiXlayuhOxnqU827OipETQyeULZmLsqIQ1wK4Fgf+9b5aJ8D85/o4wBka00X4hZ3MwDPRb4mjuogwBTBg5NRpNSzUfbkPGiav08BFwgg+Efm9veSB05arS0="},
+ {"www.sql1.example.com", "NSEC", "sql1.example.com. A RRSIG NSEC"},
+ {"www.sql1.example.com", "RRSIG", "NSEC 5 4 7200 20100322084536 20100220084536 12447 sql1.example.com. cJMJhDx/ND7/9j3zhyXe+6eaSsU7ByYpXhJzbe+OhjFgH0VasQXq7o1QB3I293UZ+yhkjgXap+9QtPlraaNaYyTyOMQ42OoxSefJpYz9CME/FI2tsUfyrCnLFxYRNet7sMS0q+hLqxRayuEHDFDp72hHPGLJQ8a7jq4SrIonT50="},
+
+ {NULL, NULL, NULL}
+};
+
+//
+// zone data for loop.example
+//
+const struct RRData loop_example_records[] = {
+ {"loop.example", "SOA", "master.loop.example admin.loop.example. "
+ "1234 3600 1800 2419200 7200"},
+ {"loop.example", "NS", "ns.loop.example"},
+ {"one.loop.example", "CNAME", "two.loop.example"},
+ {"two.loop.example", "CNAME", "one.loop.example"},
+ {NULL, NULL, NULL}
+};
+
+//
+// zone data for nons.example
+//
+const struct RRData nons_example_records[] = {
+ {"nons.example", "SOA", "master.nons.example admin.nons.example. "
+ "1234 3600 1800 2419200 7200"},
+ {"www.nons.example", "A", "192.0.2.1"},
+ {"ns.nons.example", "A", "192.0.2.2"},
+ {NULL, NULL, NULL}
+};
+
+//
+// zone data for nons-dname.example
+//
+const struct RRData nonsdname_example_records[] = {
+ {"nons-dname.example", "SOA", "master.nons-dname.example "
+ "admin.nons-dname.example. 1234 3600 1800 2419200 7200"},
+ {"nons-dname.example", "DNAME", "example.org"},
+ {"www.nons-dname.example", "A", "192.0.2.1"},
+ {"ns.nons-dname.example", "A", "192.0.2.2"},
+ {NULL, NULL, NULL}
+};
+
+//
+// zone data for nosoa.example
+//
+const struct RRData nosoa_example_records[] = {
+ {"nosoa.example", "NS", "ns.nosoa.example"},
+ {"www.nosoa.example", "A", "192.0.2.1"},
+ {"ns.nosoa.example", "A", "192.0.2.2"},
+ {NULL, NULL, NULL}
+};
+
+//
+// empty data set, for convenience.
+//
+const struct RRData empty_records[] = {
+ {NULL, NULL, NULL}
+};
+
+//
+// test zones
+//
+const struct ZoneData zone_data[] = {
+ { "example.com", "IN", example_com_records, example_com_glue_records },
+ { "sql1.example.com", "IN", sql1_example_com_records, empty_records },
+ { "loop.example", "IN", loop_example_records, empty_records },
+ { "nons.example", "IN", nons_example_records, empty_records },
+ { "nons-dname.example", "IN", nonsdname_example_records, empty_records },
+ { "nosoa.example", "IN", nosoa_example_records, empty_records }
+};
+const size_t NUM_ZONES = sizeof(zone_data) / sizeof(zone_data[0]);
+
+struct Zone {
+ Zone(const char* const name, const char* const class_txt) :
+ zone_name(Name(name)), rrclass(class_txt)
+ {}
+ Name zone_name;
+ RRClass rrclass;
+ vector<Name> names;
+ vector<RRsetPtr> rrsets;
+};
+vector<Zone> zones;
}
DataSrc::Result
TestDataSrc::init(const isc::data::ElementPtr config UNUSED_PARAM)
{
return init();
+}
+
+void
+buildZone(Zone& zone, const RRData* records, const bool is_glue) {
+ RRsetPtr prev_rrset;
+ for (int i = 0; records[i].name != NULL; ++i) {
+ Name name(records[i].name);
+ RRType rrtype(records[i].rrtype);
+ RRsetPtr rrset;
+ bool new_name = false;
+
+ if (!prev_rrset || prev_rrset->getName() != name) {
+ if (!is_glue) {
+ zone.names.push_back(name);
+ }
+ new_name = true;
+ }
+
+ if (new_name || prev_rrset->getType() != rrtype) {
+ rrset = RRsetPtr(new RRset(name, zone.rrclass, rrtype,
+ RRTTL(TEST_TTL)));
+ if (rrtype != RRType::RRSIG()) {
+ zone.rrsets.push_back(rrset);
+ }
+ } else {
+ rrset = prev_rrset;
+ }
+ rrset->addRdata(createRdata(rrtype, zone.rrclass, records[i].rdata));
+ if (rrtype == RRType::RRSIG()) {
+ prev_rrset->addRRsig(rrset);
+ }
+ prev_rrset = rrset;
+ }
}
DataSrc::Result
@@ -116,353 +346,15 @@
return (SUCCESS);
}
- RRset* rp;
- RRsetPtr rrsig;
-
- // example.com
- example_ns = RRsetPtr(new RRset(example, RRClass::IN(),
- RRType::NS(), RRTTL(3600)));
- example_ns->addRdata(generic::NS(dns01));
- example_ns->addRdata(generic::NS(dns02));
- example_ns->addRdata(generic::NS(dns03));
-
- rp = new RRset(example, RRClass::IN(), RRType::RRSIG(), RRTTL(3600));
- rrsig = RRsetPtr(rp);
- rrsig->addRdata(generic::RRSIG("NS 5 2 3600 20100322084538 20100220084538 33495 example.com. ClcrfjkQZUY5L6ZlCkU3cJHzcrEGrofKSVeeoeZ+w6yeEowFNVXs2YBo3tom53DiCrdD9rs3feVSLGW5rjsz/O6lDuomgQG+EVSnWa7GTIPBXj1BmDXXp3XxeldYmhf4UzaN5BA+RUA5E8NChNKuNNof76j2S9tilfN/kvpy4fw="));
- example_ns->addRRsig(rrsig);
-
- example_soa = RRsetPtr(new RRset(example, RRClass::IN(),
- RRType::SOA(), RRTTL(3600)));
- example_soa->addRdata(generic::SOA("master.example.com. admin.example.com. 1234 3600 1800 2419200 7200"));
-
- rrsig = RRsetPtr(new RRset(example, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("SOA 5 2 3600 20100322084538 20100220084538 33495 example.com. KUun66Qaw36osk2BJS6U1fAy3PPDkNo2QK4meGNbDBY8q8b+f2o+IXJ14YCvssGl1ORW0CcLnDRxssnk8V/Svmj5iFhO+8HC2hnVBdi2zewvdVtwRb+lWwKN7pkXXwuy6g1t9WCd/j5FCc/wgxqtZUTPb6XgZcnHrORDMOTqLs4="));
- example_soa->addRRsig(rrsig);
-
- example_nsec = RRsetPtr(new RRset(example, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- example_nsec->addRdata(generic::NSEC("cname-ext.example.com. NS SOA MX RRSIG NSEC DNSKEY"));
- rrsig = RRsetPtr(new RRset(example, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 2 7200 20100322084538 20100220084538 33495 example.com. KxuVaPPKNPJzr/q+cJPiNlkHVTQK0LVsgTbSqruXQc25lAd0wn5oKUtxL1bEAchHkfA8eLzcYCj2ZqqAv9OJubw53mfskTad7UHs4Uj2RTrIsNGMCiZGgOpvNb9JcWpQtoyXVT1uNse+Qsbeir0eyeYIufUynFU041jtNrlJMio="));
- example_nsec->addRRsig(rrsig);
-
- // sql1.example.com
- sql1_ns = RRsetPtr(new RRset(sql1, RRClass::IN(),
- RRType::NS(), RRTTL(3600)));
- sql1_ns->addRdata(generic::NS(dns01));
- sql1_ns->addRdata(generic::NS(dns02));
- sql1_ns->addRdata(generic::NS(dns03));
-
- rrsig = RRsetPtr(new RRset(sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NS 5 3 3600 20100322084536 20100220084536 12447 sql1.example.com. 0CL8noy0NSgoWwuKd+Dc6vyIIw2BrAEBx0IJzcSB6GlB25x/zjEd6AJG0be13HN6jOaTX8iWTuCVrEYuXg76V+M4EvTZHjEScj0az74TrDv4Vdo459paGKCX9B8NLJW1mW4fzZrrXQ8jmBEZeS91Q5rJrO+UKJEuUz3LYdTPvao="));
- sql1_ns->addRRsig(rrsig);
-
- sql1_soa = RRsetPtr(new RRset(sql1, RRClass::IN(),
- RRType::SOA(), RRTTL(3600)));
- sql1_soa->addRdata(generic::SOA("master.example.com. admin.example.com. 678 3600 1800 2419200 7200"));
-
- rrsig = RRsetPtr(new RRset(sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("SOA 5 3 3600 20100322084536 20100220084536 12447 sql1.example.com. oakulfyljL/RAKgCKXEZ3KsG8BJj5WG4JK4moWFB6c9OKem6jIk8hKP2XlUVXFuOYJlRdIM4KicmR2GAK+5jJp6z5ShssstYTXo3QosVm6oCKumuFeLFHzcjfqP1D+F9NsvHldJIBnS/4ebPkmR5OENyCZXQF5HmN2awIj4CLjE="));
- sql1_soa->addRRsig(rrsig);
-
- sql1_nsec = RRsetPtr(new RRset(sql1, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- sql1_nsec->addRdata(generic::NSEC("www.sql1.example.com. NS SOA RRSIG NSEC DNSKEY"));
- rrsig = RRsetPtr(new RRset(sql1, RRClass::IN(), RRType::RRSIG(), RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084536 20100220084536 12447 sql1.example.com. v71CgdTYccCiTqfRcn6HsvISQa8ruvUfCKtpwym0RW/G27xlZn8otj2IMtWwkLxti8Rqqu+PTViLaOIbeVfHBcqzAd7U59cAOYoq3ODZx6auiE3C23HAKqUavKcP7Esaajm1cbcWy6Kyie4CAZc8M7EeKxgkXMKJGqBQzF+/FOo="));
- sql1_nsec->addRRsig(rrsig);
- sql1_ds = RRsetPtr(new RRset(sql1, RRClass::IN(),
- RRType::DS(), RRTTL(3600)));
- sql1_ds->addRdata(generic::DS("33313 5 1 0FDD7A2C11AA7F55D50FBF9B7EDDA2322C541A8D"));
- sql1_ds->addRdata(generic::DS("33313 5 2 00B99B7006F496D135B01AB17EDB469B4BE9E1973884DEA757BC4E3015A8C3AB"));
-
- rrsig = RRsetPtr(new RRset(sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("DS 5 3 3600 20100322084538 20100220084538 33495 example.com. dIqZKvpkJN1l92SOiWgJh3KbjErIN+EfojMsm4pEdV5xQdZwj6DNNEu6Kw4rRwdvrZIu0TyqPr3jSJb7o6R7vZgZzmLfVV/ojQah7rwuYHCFcfyZ4JyK2311fMhRR1QAvMsdcjdyA1XC140Cm6AnL3cH5rh/KUks/0ec3Ca7GNQ="));
- sql1_ds->addRRsig(rrsig);
-
-
- sql1_ds_nsec = RRsetPtr(new RRset(sql1, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- sql1_ds_nsec->addRdata(generic::NSEC("subzone.example.com. NS DS RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. k9FRdFyk/cPdkmmaoZbGZPpzIzfbFWQ3QCHd2qhJa0xAXaEOT/GBL6aFqx9SlunDu2wgES+To5fWPZGi4NzWpp6c5t27rnATN/oCEQ/UYIJKmWbqrXdst0Ps5boznk7suK2Y+km31KxaIf3fDd/T3kZCVsR0aWKRRRatPb7GfLw="));
- sql1_ds_nsec->addRRsig(rrsig);
-
- // www.sql1.example.com
- www_sql1_a = RRsetPtr(new RRset(www_sql1,
- RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- www_sql1_a->addRdata(in::A("192.0.2.2"));
-
- rrsig = RRsetPtr(new RRset(www_sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 4 3600 20100322084536 20100220084536 12447 sql1.example.com. DNdVKxB3oBsB14NPoV9WG14Y/g4zMcIXLYnFjj9vRZRZJpAvbTEipiXlayuhOxnqU827OipETQyeULZmLsqIQ1wK4Fgf+9b5aJ8D85/o4wBka00X4hZ3MwDPRb4mjuogwBTBg5NRpNSzUfbkPGiav08BFwgg+Efm9veSB05arS0="));
- www_sql1_a->addRRsig(rrsig);
-
- www_sql1_nsec = RRsetPtr(new RRset(www_sql1,
- RRClass::IN(), RRType::NSEC(),
- RRTTL(3600)));
- www_sql1_nsec->addRdata(generic::NSEC("sql1.example.com. A RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(www_sql1, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 4 7200 20100322084536 20100220084536 12447 sql1.example.com. cJMJhDx/ND7/9j3zhyXe+6eaSsU7ByYpXhJzbe+OhjFgH0VasQXq7o1QB3I293UZ+yhkjgXap+9QtPlraaNaYyTyOMQ42OoxSefJpYz9CME/FI2tsUfyrCnLFxYRNet7sMS0q+hLqxRayuEHDFDp72hHPGLJQ8a7jq4SrIonT50="));
- www_sql1_nsec->addRRsig(rrsig);
-
- // dns01.example.com
- dns01_a = RRsetPtr(new RRset(dns01,
- RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- dns01_a->addRdata(in::A("192.0.2.1"));
-
- rrsig = RRsetPtr(new RRset(dns01, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 3 3600 20100322084538 20100220084538 33495 example.com. NIawlZLk8WZAjNux7oQM2mslfW52OZFFkWt++7FHu2SU98XqEeKfCMnpgtWe5T8Nr9cS8df901iEOJoWQzGTEaHYUBtEhsSjBVn7mKp3fz6473a2xxy75SUKZ0rxjNXSZ8Q5rnFmkX0HTH2Sg51mtjH6aC2pfheQnA2t193BnSg="));
- dns01_a->addRRsig(rrsig);
-
- dns01_nsec = RRsetPtr(new RRset(dns01, RRClass::IN(), RRType::NSEC(), RRTTL(3600)));
- dns01_nsec->addRdata(generic::NSEC("dns02.example.com. A RRSIG NSEC"));
-
- rrsig = RRsetPtr(new RRset(dns01, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. EkyeshmMNP9xiAz6mDFDIwksTdmkF9zsFzLuVKAgK6eUk7St6tp5PSvjA8nWol0vdvvz4LK85a4ffTFEiNRyvWeYP2vOhEkyDcrwuCd8Vc3jh/8Sm1Js+nX7hJStrZGFvp2TWPpt9nKH5p3MxXvTb/YVurnue0xSeFAE17O3+I0="));
- dns01_nsec->addRRsig(rrsig);
-
- // dns02.example.com
- dns02_a = RRsetPtr(new RRset(dns02, RRClass::IN(), RRType::A(), RRTTL(3600)));
- dns02_a->addRdata(in::A("192.0.2.2"));
-
- rrsig = RRsetPtr(new RRset(dns02, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 3 3600 20100322084538 20100220084538 33495 example.com. XJtVMbUIRE0mk6Hn/Nx6k36jaxaBDPK2/IYB6vCQjJETz6gW4T6q/H/eY9/Lsw5iYPFhoBRDxT4XFj575t98kELXnJe1WhuMbRPlOhyOjxkLECaUne/sbFPOtbGFx9ohuojI0RgxxZiCFaO8wJuv6nfPuzmlLajWS6z9NZeOMIk="));
- dns02_a->addRRsig(rrsig);
-
- dns02_nsec = RRsetPtr(new RRset(dns02, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- dns02_nsec->addRdata(generic::NSEC("dns03.example.com. A RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(dns02, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
-
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. imBNTMB3sPU4kblcaAH6V7lCVt5xgtAybi3DA/SbLEulLaV2NE6vcoEn/AieaM4mOJicQnUDj/H+1hSEhzxU2tRM8zfVlvztxQWn6eh7ZR4mKfNDSvRUGU9ykhpwMyC7wjOt1j5bcSA/OTnLRAilslnJyOM4bSaxVEFo8YPjncY="));
- dns02_nsec->addRRsig(rrsig);
-
- // dns03.example.com
- dns03_a = RRsetPtr(new RRset(dns03,
- RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- dns03_a->addRdata(in::A("192.0.2.3"));
-
- rrsig = RRsetPtr(new RRset(dns03, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 3 3600 20100322084538 20100220084538 33495 example.com. Ubrcm1H+F6m8khle7P9zU8eO+Jtuj+1Vx1MM5KAkmZPJwQe9uTcoCpQa6DXOGG9kajDTnNN1Be1gkZuJDTZJG4SmJLXLbNY3RDnxpGmWta3qs/VgDq78/YM8ropt1/s7YKyrCfGE2ff+FUB0mLObiG01ZV2gu5HJzgE7SEWLEiI="));
- dns03_a->addRRsig(rrsig);
-
- dns03_nsec = RRsetPtr(new RRset(dns03, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- dns03_nsec->addRdata(generic::NSEC("foo.example.com. A RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(dns03, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
-
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. nn829Xw5CJFnPHwI9WHeT5epQv+odtCkHnjlPFGoPTLOyiks+041UmMqtq3uiSp4d2meMSe9UuDvoROT0L6NTtQQvVqiDhTn0irTFw1uw7fO8ZTG7eyu6Ypfz0+HvfbNvd4kMoD2OTgADRXPVsCTwK+PBOIIG9YTEQfl8pCqW5g="));
- dns03_nsec->addRRsig(rrsig);
-
- // www.example.com
- www_a = RRsetPtr(new RRset(www, RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- www_a->addRdata(in::A("192.0.2.1"));
-
- rrsig = RRsetPtr(new RRset(www, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 3 3600 20100322084538 20100220084538 33495 example.com. qyFyyV/mE8x4pdhudr5iycwhDsva31MzwO1kBR+bDKvzJg8mN8KxlPZrOlNNUhd3YRXQVwieMyxOTWRPXoxrNEDkNwimXkfe3rrHY7ibV9eNS4OIBUjb44VjCNr9CmQSzfuQ2yxO2r+YIuPYHRCjieD4xh6t9ay4IaCN/tDAJ+Q="));
- www_a->addRRsig(rrsig);
-
- www_nsec = RRsetPtr(new RRset(www, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- www_nsec->addRdata(generic::NSEC("example.com. A RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(www, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. ZLZlSVBa2oe4U+7SZASnypP2VkI5gg1/1cVGqYUvfYNIUkcVMWDgn7DZCfpmo+2vdlV/4VhAc+sjDd+X+e57XGnW8+lqZHvG6NMMhmSGmeATD3D+8lEJJGo0dxoN4rHJQyp/eT2S4nChz+D/ze+YRagYxGF7pXm9zcrw3kKZGTs="));
- www_nsec->addRRsig(rrsig);
-
- // *.wild.example.com
- wild_a = RRsetPtr(new RRset(wild, RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- wild_a->addRdata(in::A("192.0.2.2"));
-
- rrsig = RRsetPtr(new RRset(wild, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("A 5 3 3600 20100322084538 20100220084538 33495 example.com. FdO+UWONgtLKFxUzzygGunw67F9y8SzsP7yOLEYVJclRR8X3Ii62L0gtQHq2y0TcKsXttRsD6XY+tM5P/pgXlTNi7Bk4Fgb0PIDPjOsfT4DrS80kWn0YbinM/4/FA1j5ru5sTTboOY5UGhvDnoA9ogNuQQYb2/3wkoH0PrA2Q/0="));
- wild_a->addRRsig(rrsig);
-
- wild_nsec = RRsetPtr(new RRset(wild, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- wild_nsec->addRdata(generic::NSEC("*.wild2.example.com. A RRSIG NSEC"));
-
- rrsig = RRsetPtr(new RRset(wild, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
-
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. OoGYslRj4xjZnBuzgOqsrvkDAHWycmQzbUxCRmgWnCbXiobJK7/ynONH3jm8G3vGlU0lwpHkhNs6cUK+6Nu8W49X3MT0Xksl/brroLcXYLi3vfxnYUNMMpXdeFl6WNNfoJRo90F/f/TWXAClRrDS29qiG3G1PEJZikIxZsZ0tyM="));
- wild_nsec->addRRsig(rrsig);
-
- // *.wild2.example.com
- wild2_cname = RRsetPtr(new RRset(wild2, RRClass::IN(), RRType::CNAME(),
- RRTTL(3600)));
- wild2_cname->addRdata(generic::CNAME("www.example.com"));
-
- rrsig = RRsetPtr(new RRset(wild2, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("CNAME 5 3 3600 20100410212307 20100311212307 33495 example.com. pGHtGdRBi4GKFSKszi6SsKvuBLDX8dFhZubU0tMojQ9SJuiFNF+WtxvdAYuUaoWP/9VLUaYmiw5u7JnzmR84DiXZPEs6DtD+UJdOZhaS7V7RTpE+tMOfVQBLpUnRWYtlTTmiBpFquzf3DdIxgUFhEPEuJJyp3LFRxJObCaq9 nvI="));
- wild2_cname->addRRsig(rrsig);
-
- wild2_nsec = RRsetPtr(new RRset(wild2, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- wild2_nsec->addRdata(generic::NSEC("*.wild3.example.com. CNAME RRSIG NSEC"));
-
- rrsig = RRsetPtr(new RRset(wild2, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
-
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100410212307 20100311212307 33495 example.com. EuSzh6or8mbvwru2H7fyYeMpW6J8YZ528rabU38V/lMN0TdamghIuCneAvSNaZgwk2MSN1bWpZqB2kAipaM/ZI9/piLlTvVjjOQ8pjk0auwCEqT7Z7Qng3E92O9yVzO+WHT9QZn/fR6t60392In4IvcBGjZyjzQk8njIwbui xGA="));
- wild2_nsec->addRRsig(rrsig);
-
- // *.wild3.example.com -- a wildcard record with a lame CNAME
- wild3_cname = RRsetPtr(new RRset(wild3, RRClass::IN(), RRType::CNAME(),
- RRTTL(3600)));
- wild3_cname->addRdata(generic::CNAME("spork.example.com"));
-
- rrsig = RRsetPtr(new RRset(wild3, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("CNAME 5 3 3600 20100410212307 20100311212307 33495 example.com. pGHtGdRBi4GKFSKszi6SsKvuBLDX8dFhZubU0tMojQ9SJuiFNF+WtxvdAYuUaoWP/9VLUaYmiw5u7JnzmR84DiXZPEs6DtD+UJdOZhaS7V7RTpE+tMOfVQBLpUnRWYtlTTmiBpFquzf3DdIxgUFhEPEuJJyp3LFRxJObCaq9 nvI="));
- wild3_cname->addRRsig(rrsig);
-
- wild3_nsec = RRsetPtr(new RRset(wild3, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- wild3_nsec->addRdata(generic::NSEC("www.example.com. CNAME RRSIG NSEC"));
-
- rrsig = RRsetPtr(new RRset(wild3, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
-
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100410212307 20100311212307 33495 example.com. EuSzh6or8mbvwru2H7fyYeMpW6J8YZ528rabU38V/lMN0TdamghIuCneAvSNaZgwk2MSN1bWpZqB2kAipaM/ZI9/piLlTvVjjOQ8pjk0auwCEqT7Z7Qng3E92O9yVzO+WHT9QZn/fR6t60392In4IvcBGjZyjzQk8njIwbui xGA="));
- wild3_nsec->addRRsig(rrsig);
-
- // foo.example.com
- foo_cname = RRsetPtr(new RRset(foo, RRClass::IN(), RRType::CNAME(),
- RRTTL(3600)));
- foo_cname->addRdata(generic::CNAME("cnametest.flame.org"));
-
- rrsig = RRsetPtr(new RRset(foo, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. DSqkLnsh0gCeCPVW/Q8viy9GNP+KHmFGfWqyVG1S6koBtGN/VQQ16M4PHZ9Zssmf/JcDVJNIhAChHPE2WJiaPCNGTprsaUshf1Q2vMPVnkrJKgDY8SVRYMptmT8eaT0gGri4KhqRoFpMT5OYfesybwDgfhFSQQAh6ps3bIUsy4o="));
- foo_cname->addRRsig(rrsig);
-
- foo_nsec = RRsetPtr(new RRset(foo, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- foo_nsec->addRdata(generic::NSEC("mail.example.com. CNAME RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(foo, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. RTQwlSqui6StUYye1KCSOEr1d3irndWFqHBpwP7g7n+w8EDXJ8I7lYgwzHvlQt6BLAxe5fUDi7ct8M5hXvsm7FoWPZ5wXH+2/eJUCYxIw4vezKMkMwBP6M/YkJ2CMqY8DppYf60QaLDONQAr7AcK/naSyioeI5h6eaoVitUDMso="));
- foo_nsec->addRRsig(rrsig);
-
- // cname-int.example.com
- cnameint_cname = RRsetPtr(new RRset(cnameint, RRClass::IN(),
- RRType::CNAME(), RRTTL(3600)));
- cnameint_cname->addRdata(generic::CNAME("www.example.com."));
-
- rrsig = RRsetPtr(new RRset(cnameint, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. U1wjt0XY9xjTwvUmWSUcfLGMhCjfX2ylWfHrycy50x2oxcK9z94E1ejen9wDTIEBSGYgi6wpZ8RK0+02N1DWTGpDqNXd7aFRfDrWQJ/q/XJHDx0vlcmhkWhrT82LBfKxkrptOzchuSo/c0mpK+mpiIMc1VOwY+yuQ2ALfcD6EHw="));
- cnameint_cname->addRRsig(rrsig);
-
- cnameint_nsec = RRsetPtr(new RRset(cnameint, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- cnameint_nsec->addRdata(generic::NSEC("dname.example.com. CNAME RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(cnameint, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. rbV+gaxfrsoha59NOLF4EFyWQ+GuFCVK/8D77x1atan3HNlXBlZ1smgudKTaJ3CtlobIDt0MEdPxY1yn2Tskw/5mlP1PWf8oaP3BwGSQdn4gLI8+sMpNOPFEdXpxqxngm2F6/7fqniL1QuSAQBEdO+5UiCAgnncPmAsSJg3u1zg="));
- cnameint_nsec->addRRsig(rrsig);
-
- // cname-ext.example.com
- cnameext_cname = RRsetPtr(new RRset(cnameext, RRClass::IN(),
- RRType::CNAME(), RRTTL(3600)));
- cnameext_cname->addRdata(generic::CNAME("www.sql1.example.com"));
-
- rrsig = RRsetPtr(new RRset(cnameext, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("CNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. bGPIuZilyygvTThK4BrdECuaBcnZUgW/0d09iN2CrNjckchQl3dtbnMNirFsVs9hShDSldRNlQpiAVMpnPgXHhReNum7jmX6yqIH6s8GKIo91zr3VL/ramlezie5w4MilDHrxXLK2pb8IHmP+ZHivQ2EtdYQZgETWBWxr5FDfwk="));
- cnameext_cname->addRRsig(rrsig);
-
- cnameext_nsec = RRsetPtr(new RRset(cnameext, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- cnameext_nsec->addRdata(generic::NSEC("cname-int.example.com. CNAME RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(cnameext, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. inWsFwSDWG7TakjwbUTzTRpXz0WifelA5Kn3ABk6BVirIPmd+yQoNj2QZBDFAQwhnLPlNws2Oo4vgMsBMyx1Fv5eHgMUuCN3DUDaLlzlPtUb42CjOUa+jZBeTV/Hd7WZrirluASE1QFDprLdSSqoPPfAKvN3pORtW7y580dMOIM="));
- cnameext_nsec->addRRsig(rrsig);
-
- // dname.example.com
- dname_dname = RRsetPtr(new RRset(dname, RRClass::IN(), RRType::DNAME(),
- RRTTL(3600)));
- dname_dname->addRdata(generic::DNAME("sql1.example.com."));
-
- rrsig = RRsetPtr(new RRset(dname, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("DNAME 5 3 3600 20100322084538 20100220084538 33495 example.com. ae8U47oaiwWdurkSyzcsCAF6DxBqjukizwF7K7U6lQVMtfoUE14oiAqfj1fjH8YLDOO/Hd1twrd/u0vgjnI1Gg32YTi7cYOzwE912SV1u2B/y0awaQKWPBwOW0aI7vxelt1vMUF81xosiQD04gOIdDBTqbHKcDxum87iWbhk4Ug="));
- dname_dname->addRRsig(rrsig);
-
- dname_nsec = RRsetPtr(new RRset(dname, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- dname_nsec->addRdata(generic::NSEC("dns01.example.com. DNAME RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(dname, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. c21Fff2D8vBrLzohBnUeflkaRdUAnUxAFGp+UQ0miACDCMOFBlCS9v9g/2+orOnKfd3l4vyz55C310t8JXgXb119ofaZWj2zkdUe+X8Bax+sMS0Y5K/sUhSNvbJbozr9UYPdvjSVBiWgh3s9fsb+etKq9uFukAzGU/FuGYpO0r0="));
- dname_nsec->addRRsig(rrsig);
-
- // subzone.example.com
- subzone_ns = RRsetPtr(new RRset(subzone, RRClass::IN(), RRType::NS(),
- RRTTL(3600)));
- subzone_ns->addRdata(generic::NS(Name("ns1.subzone.example.com")));
- subzone_ns->addRdata(generic::NS(Name("ns2.subzone.example.com")));
-
- subzone_ds = RRsetPtr(new RRset(subzone, RRClass::IN(), RRType::DS(),
- RRTTL(3600)));
-
- subzone_glue1 = RRsetPtr(new RRset(Name("ns1.subzone.example.com"),
- RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- subzone_glue1->addRdata(in::A("192.0.2.1"));
- subzone_glue2 = RRsetPtr(new RRset(Name("ns2.subzone.example.com"),
- RRClass::IN(), RRType::A(),
- RRTTL(3600)));
- subzone_glue2->addRdata(in::A("192.0.2.2"));
-
- subzone_ds = RRsetPtr(new RRset(subzone, RRClass::IN(), RRType::DS(),
- RRTTL(3600)));
-
- subzone_ds->addRdata(generic::DS("33313 5 1 0FDD7A2C11AA7F55D50FBF9B7EDDA2322C541A8D"));
- subzone_ds->addRdata(generic::DS("33313 5 2 00B99B7006F496D135B01AB17EDB469B4BE9E1973884DEA757BC4E3015A8C3AB"));
-
- rrsig = RRsetPtr(new RRset(subzone, RRClass::IN(), RRType::RRSIG(),
- RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("DS 5 3 3600 20100322084538 20100220084538 33495 example.com. dIqZKvpkJN1l92SOiWgJh3KbjErIN+EfojMsm4pEdV5xQdZwj6DNNEu6Kw4rRwdvrZIu0TyqPr3jSJb7o6R7vZgZzmLfVV/ojQah7rwuYHCFcfyZ4JyK2311fMhRR1QAvMsdcjdyA1XC140Cm6AnL3cH5rh/KUks/0ec3Ca7GNQ="));
- subzone_ds->addRRsig(rrsig);
-
- subzone_nsec = RRsetPtr(new RRset(subzone, RRClass::IN(),
- RRType::NSEC(), RRTTL(3600)));
- subzone_nsec->addRdata(generic::NSEC("*.wild.example.com. NS DS RRSIG NSEC"));
- rrsig = RRsetPtr(new RRset(subzone, RRClass::IN(), RRType::RRSIG(), RRTTL(3600)));
- rrsig->addRdata(generic::RRSIG("NSEC 5 3 7200 20100322084538 20100220084538 33495 example.com. Oe2kgIhsLtPJ4+lDZDxznV8/vEVoXKOBFN9lwWyebaKa19BaSXlQ+YVejmulmKDDjEucMvEfuItfn6w7bnU+DzOLk5D1lJCjwDlKz8u3xOAx16TiuQn4bgQAOiFtBQygmGGqO3BVpX+jxsmw7eH3emofy8uUqr/C4aopnwuf28g="));
- subzone_nsec->addRRsig(rrsig);
-
- loop1_cname = RRsetPtr(new RRset(loop1, RRClass::IN(), RRType::CNAME(),
- RRTTL(3600)));
- loop1_cname->addRdata(generic::CNAME(loop2));
- loop2_cname = RRsetPtr(new RRset(loop2, RRClass::IN(), RRType::CNAME(),
- RRTTL(3600)));
- loop2_cname->addRdata(generic::CNAME(loop1));
+ if (zones.empty()) {
+ for (int i = 0; i < NUM_ZONES; ++i) {
+ Zone zone(zone_data[i].zone_name, zone_data[i].rrclass);
+ buildZone(zone, zone_data[i].records, false);
+ buildZone(zone, zone_data[i].glue_records, true);
+ sort(zone.names.begin(), zone.names.end());
+ zones.push_back(zone);
+ }
+ }
initialized = true;
return (SUCCESS);
@@ -470,276 +362,160 @@
void
TestDataSrc::findClosestEnclosure(NameMatch& match,
- const RRClass& qclass) const {
+ const RRClass& qclass) const
+{
const Name& qname = match.qname();
- NameComparisonResult::NameRelation cmp;
if (qclass != getClass() && qclass != RRClass::ANY()) {
return;
}
- cmp = qname.compare(sql1).getRelation();
- if (cmp == NameComparisonResult::EQUAL ||
- cmp == NameComparisonResult::SUBDOMAIN) {
- match.update(*this, sql1);
- return;
- }
-
- cmp = qname.compare(example).getRelation();
- if (cmp == NameComparisonResult::EQUAL ||
- cmp == NameComparisonResult::SUBDOMAIN) {
- match.update(*this, example);
- return;
- }
-
-}
+ vector<Zone>::const_iterator it;
+ vector<Zone>::const_iterator best_it = zones.end();
+ unsigned int best_common_labels = 0;
+ for (it = zones.begin(); it != zones.end(); ++it) {
+ const NameComparisonResult cmp = qname.compare(it->zone_name);
+ const NameComparisonResult::NameRelation reln = cmp.getRelation();
+
+ if ((reln == NameComparisonResult::EQUAL ||
+ reln == NameComparisonResult::SUBDOMAIN) &&
+ cmp.getCommonLabels() > best_common_labels) {
+ best_it = it;
+ best_common_labels = cmp.getCommonLabels();
+ }
+ }
+
+ if (best_it != zones.end()) {
+ match.update(*this, best_it->zone_name);
+ }
+}
+
+struct ZoneNameMatch : public unary_function<Name, bool> {
+ ZoneNameMatch(const Name& name) : name_(name) {}
+ bool operator()(const Zone& zone) const {
+ return (zone.zone_name == name_);
+ }
+ const Name& name_;
+};
+
+// XXX: the main data source module can override the returned RRset.
+// That's bad and should be fixed (Trac #254), but for now we work around it.
+RRsetPtr
+copyRRset(RRsetPtr const source) {
+ RRsetPtr rrset = RRsetPtr(new RRset(source->getName(), source->getClass(),
+ source->getType(), source->getTTL()));
+ RdataIteratorPtr it = source->getRdataIterator();
+ for (it->first(); !it->isLast(); it->next()) {
+ rrset->addRdata(it->getCurrent());
+ }
+ if (source->getRRsig()) {
+ rrset->addRRsig(copyRRset(source->getRRsig()));
+ }
+
+ return (rrset);
+}
+
+class TestDataSrc::RRsetMatch {
+public:
+ struct MatchResult {
+ MatchResult(const bool name_found, const bool has_delegation) :
+ name_found_(name_found), has_delegation_(has_delegation)
+ {}
+ bool name_found_;
+ bool has_delegation_;
+ };
+ RRsetMatch(const Name& name, const RRType& rrtype, const Mode mode,
+ RRsetList& target, uint32_t& flags) :
+ name_(name), rrtype_(rrtype), mode_(mode), target_(target),
+ flags_(flags), name_found_(false), has_delegation_(false)
+ {}
+ void operator()(const RRsetPtr& rrset) {
+ if (rrset->getName() != name_) {
+ return;
+ }
+ name_found_ = true;
+
+ if (rrset->getType() == RRType::NS() ||
+ rrset->getType() == RRType::DNAME()) {
+ has_delegation_ = true;
+ }
+
+ if (mode_ == DELEGATION) {
+ if (rrset->getType() == RRType::NS() ||
+ rrset->getType() == RRType::DNAME() ||
+ rrset->getType() == RRType::DS()) {
+ target_.addRRset(copyRRset(rrset));
+ }
+ } else if (mode_ == ADDRESS) {
+ if (rrset->getType() == RRType::A() ||
+ rrset->getType() == RRType::AAAA()) {
+ target_.addRRset(copyRRset(rrset));
+ }
+ } else {
+ if (rrtype_ == RRType::NSEC() &&
+ rrset->getType() == RRType::CNAME()) {
+ // XXX: ignore CNAME if the qtype is NSEC.
+ // tricky, but necessary.
+ return;
+ }
+ if (rrtype_ == RRType::ANY() || rrtype_ == rrset->getType() ||
+ rrset->getType() == RRType::CNAME() ||
+ rrset->getType() == RRType::DNAME()) {
+ target_.addRRset(copyRRset(rrset));
+ if (rrset->getType() == RRType::CNAME()) {
+ flags_ |= CNAME_FOUND;
+ }
+ if (rrset->getType() == RRType::DNAME()) {
+ flags_ |= REFERRAL;
+ }
+ }
+ }
+
+ }
+ MatchResult getResult() { return (MatchResult(name_found_,
+ has_delegation_)); }
+ const Name& name_;
+ const RRType& rrtype_;
+ const Mode mode_;
+ RRsetList& target_;
+ uint32_t& flags_;
+ bool name_found_;
+ bool has_delegation_;
+};
void
TestDataSrc::findRecords(const Name& name, const RRType& rdtype,
- RRsetList& target, const Name* zonename, const Mode mode,
- uint32_t& flags) const
-{
- const bool any = (rdtype == RRType::ANY());
+ RRsetList& target, const Name* zonename,
+ const Mode mode, uint32_t& flags) const
+{
flags = 0;
assert(zonename != NULL);
- if (*zonename == sql1) {
- if (name == sql1 && mode == DELEGATION) {
- target.addRRset(sql1_ns);
- flags |= REFERRAL;
- } else if (name == sql1) {
- flags |= REFERRAL;
- if (any) {
- target.addRRset(sql1_ns);
- target.addRRset(sql1_nsec);
- } else if (rdtype == RRType::NS()) {
- target.addRRset(sql1_ns);
- } else if (rdtype == RRType::SOA()) {
- target.addRRset(sql1_soa);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(sql1_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == www_sql1) {
- if (any) {
- target.addRRset(www_sql1_a);
- target.addRRset(www_sql1_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(www_sql1_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(www_sql1_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
+
+ vector<Zone>::const_iterator zone = find_if(zones.begin(), zones.end(),
+ ZoneNameMatch(*zonename));
+ if (zone == zones.end()) {
+ return;
+ }
+
+ const RRsetMatch::MatchResult match_result =
+ for_each(zone->rrsets.begin(), zone->rrsets.end(),
+ RRsetMatch(name, rdtype, mode, target, flags)).getResult();
+ if (match_result.has_delegation_) {
+ flags |= REFERRAL;
+ }
+ if (target.size() == 0) {
+ if (match_result.name_found_) {
+ flags |= TYPE_NOT_FOUND;
} else {
flags |= NAME_NOT_FOUND;
}
- } else {
- if (name == example && mode == DELEGATION) {
- target.addRRset(example_ns);
- flags |= REFERRAL;
- } else if (name == example) {
- flags |= REFERRAL;
- if (any) {
- target.addRRset(example_ns);
- target.addRRset(example_soa);
- target.addRRset(example_nsec);
- } else if (rdtype == RRType::NS()) {
- target.addRRset(example_ns);
- } else if (rdtype == RRType::SOA()) {
- target.addRRset(example_soa);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(example_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == sql1 && mode == DELEGATION) {
- target.addRRset(sql1_ns);
- target.addRRset(sql1_ds);
- target.addRRset(sql1_ds_nsec);
- flags |= REFERRAL;
- } else if (name == sql1) {
- flags |= REFERRAL;
- if (any) {
- target.addRRset(sql1_ns);
- target.addRRset(sql1_ds);
- target.addRRset(sql1_ds_nsec);
- } else if (rdtype == RRType::DS()) {
- target.addRRset(sql1_ds);
- } else if (rdtype == RRType::NS()) {
- target.addRRset(sql1_ns);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(sql1_ds_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == subzone && mode == DELEGATION) {
- target.addRRset(subzone_ns);
- target.addRRset(subzone_ds);
- flags |= REFERRAL;
- } else if (name == subzone) {
- flags |= REFERRAL;
- if (any) {
- target.addRRset(subzone_ns);
- target.addRRset(subzone_nsec);
- } else if (rdtype == RRType::NS()) {
- target.addRRset(subzone_ns);
- } else if (rdtype == RRType::DS()) {
- target.addRRset(subzone_ds);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(subzone_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == dns01 && mode == ADDRESS) {
- target.addRRset(dns01_a);
- } else if (name == dns01) {
- if (any) {
- target.addRRset(dns01_a);
- target.addRRset(dns01_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(dns01_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(dns01_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == dns02 && mode == ADDRESS) {
- target.addRRset(dns02_a);
- } else if (name == dns02) {
- if (any) {
- target.addRRset(dns02_a);
- target.addRRset(dns02_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(dns02_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(dns02_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == dns03 && mode == ADDRESS) {
- target.addRRset(dns03_a);
- } else if (name == dns03) {
- if (any) {
- target.addRRset(dns03_a);
- target.addRRset(dns03_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(dns03_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(dns03_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == wild) {
- if (any) {
- target.addRRset(wild_a);
- target.addRRset(wild_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(wild_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(wild_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == wild2) {
- if (any) {
- target.addRRset(wild2_cname);
- target.addRRset(wild2_nsec);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(wild2_nsec);
- } else {
- target.addRRset(wild2_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- }
- } else if (name == wild3) {
- if (any) {
- target.addRRset(wild3_cname);
- target.addRRset(wild3_nsec);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(wild3_nsec);
- } else {
- target.addRRset(wild3_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- }
- } else if (name == www) {
- if (any) {
- target.addRRset(www_a);
- target.addRRset(www_nsec);
- } else if (rdtype == RRType::A()) {
- target.addRRset(www_a);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(www_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == foo) {
- if (rdtype == RRType::NSEC()) {
- target.addRRset(foo_nsec);
- } else {
- target.addRRset(foo_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- }
- } else if (name == cnameint) {
- if (rdtype == RRType::NSEC()) {
- target.addRRset(cnameint_nsec);
- } else {
- target.addRRset(cnameint_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- }
- } else if (name == cnameext) {
- if (rdtype == RRType::NSEC()) {
- target.addRRset(cnameext_nsec);
- } else {
- target.addRRset(cnameext_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- }
- } else if (name == dname) {
- flags |= REFERRAL;
- if (any) {
- target.addRRset(dname_dname);
- target.addRRset(dname_nsec);
- } else if (rdtype == RRType::DNAME()) {
- target.addRRset(dname_dname);
- } else if (rdtype == RRType::NSEC()) {
- target.addRRset(dns01_nsec);
- } else {
- flags |= TYPE_NOT_FOUND;
- }
- } else if (name == Name("ns1.subzone.example.com") && mode == ADDRESS) {
- target.addRRset(subzone_glue1);
- } else if (name == Name("ns2.subzone.example.com") && mode == ADDRESS) {
- target.addRRset(subzone_glue2);
- } else if (name == loop1) {
- target.addRRset(loop1_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- } else if (name == loop2) {
- target.addRRset(loop1_cname);
- if (rdtype != RRType::CNAME()) {
- flags |= CNAME_FOUND;
- }
- } else {
- flags |= NAME_NOT_FOUND;
- }
- }
- return;
+ }
}
DataSrc::Result
TestDataSrc::findRRset(const Name& qname,
- const RRClass& qclass UNUSED_PARAM,
+ const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
uint32_t& flags,
@@ -755,7 +531,7 @@
DataSrc::Result
TestDataSrc::findExactRRset(const Name& qname,
- const RRClass& qclass UNUSED_PARAM,
+ const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
uint32_t& flags,
@@ -770,7 +546,7 @@
flags &= ~REFERRAL;
// CNAMEs don't count in this case
- if (flags & CNAME_FOUND) {
+ if ((flags & CNAME_FOUND) != 0) {
flags &= ~CNAME_FOUND;
flags |= TYPE_NOT_FOUND;
}
@@ -780,7 +556,7 @@
DataSrc::Result
TestDataSrc::findAddrs(const Name& qname,
- const RRClass& qclass UNUSED_PARAM,
+ const RRClass& qclass,
RRsetList& target,
uint32_t& flags,
const Name* zonename) const
@@ -795,7 +571,7 @@
DataSrc::Result
TestDataSrc::findReferral(const Name& qname,
- const RRClass& qclass UNUSED_PARAM,
+ const RRClass& qclass,
RRsetList& target,
uint32_t& flags,
const Name* zonename) const
@@ -815,42 +591,30 @@
{
assert(zonename != NULL);
- if (*zonename == example) {
- if (qname >= example && qname < cnameext) {
- target = example;
- } else if (qname < cnameint) {
- target = cnameext;
- } else if (qname < dname) {
- target = cnameint;
- } else if (qname < dns01) {
- target = dname;
- } else if (qname < dns02) {
- target = dns01;
- } else if (qname < dns03) {
- target = dns02;
- } else if (qname < foo) {
- target = dns03;
- } else if (qname < sql1) {
- target = foo;
- } else if (qname < subzone) {
- target = sql1;
- } else if (qname < wild) {
- target = subzone;
- } else if (qname < wild2) {
- target = wild;
- } else if (qname < wild3) {
- target = wild2;
- } else if (qname < www) {
- target = wild3;
- } else {
- target = www;
- }
+ vector<Zone>::const_iterator zone = find_if(zones.begin(), zones.end(),
+ ZoneNameMatch(*zonename));
+ if (zone == zones.end()) {
+ return (ERROR);
+ }
+
+ if (zone->names.empty()) {
+ return (ERROR);
+ }
+
+ // if found, next_name >= qname.
+ vector<Name>::const_iterator next_name =
+ lower_bound(zone->names.begin(), zone->names.end(), qname);
+ if (next_name == zone->names.end()) {
+ // if no such name was found, the previous name is the last name.
+ target = zone->names.back();
+ } else if (*next_name == qname) {
+ target = *next_name;
+ } else if (next_name == zone->names.begin()) {
+ // if qname < first_name, the "previous name" is the last name.
+ target = zone->names.back();
} else {
- if (qname >= sql1 || qname < www_sql1) {
- target = sql1;
- } else {
- target = www_sql1;
- }
+ // otherwise, qname and next_name share the same previous name.
+ target = *(next_name - 1);
}
return (SUCCESS);
}
Modified: experiments/python-binding/src/lib/datasrc/tests/test_datasrc.h
==============================================================================
--- experiments/python-binding/src/lib/datasrc/tests/test_datasrc.h (original)
+++ experiments/python-binding/src/lib/datasrc/tests/test_datasrc.h Wed Jun 30 13:47:21 2010
@@ -96,6 +96,7 @@
ADDRESS,
DELEGATION
};
+ class RRsetMatch;
void findRecords(const isc::dns::Name& name, const isc::dns::RRType& rdtype,
isc::dns::RRsetList& target,
Modified: experiments/python-binding/src/lib/datasrc/tests/testdata/example.org
==============================================================================
--- experiments/python-binding/src/lib/datasrc/tests/testdata/example.org (original)
+++ experiments/python-binding/src/lib/datasrc/tests/testdata/example.org Wed Jun 30 13:47:21 2010
@@ -11,3 +11,4 @@
sub.example.org. NS ns.sub.example.org.
ns.sub.example.org. A 192.0.2.101
dname.example.org. DNAME dname.example.info.
+dname2.foo.example.org. DNAME dname2.example.info.
Modified: experiments/python-binding/src/lib/datasrc/tests/testdata/example.org.sqlite3
==============================================================================
Binary files - no diff available.
Modified: experiments/python-binding/src/lib/dns/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/dns/Makefile.am (original)
+++ experiments/python-binding/src/lib/dns/Makefile.am Wed Jun 30 13:47:21 2010
@@ -55,52 +55,30 @@
BUILT_SOURCES = rrclass.h rrtype.h rrparamregistry.cc
#TODO: check this###BUILT_SOURCES = rdataclass.h rdataclass.cc
-lib_LTLIBRARIES = libdns.la
+lib_LTLIBRARIES = libdns++.la
-libdns_la_SOURCES = base32.h base32.cc
-libdns_la_SOURCES += base64.h base64.cc
-libdns_la_SOURCES += buffer.h
-libdns_la_SOURCES += dnssectime.h dnssectime.cc
-libdns_la_SOURCES += exceptions.h exceptions.cc
-libdns_la_SOURCES += hex.h hex.cc
-libdns_la_SOURCES += message.h message.cc
-libdns_la_SOURCES += messagerenderer.h messagerenderer.cc
-libdns_la_SOURCES += name.h name.cc
-libdns_la_SOURCES += rdata.h rdata.cc
-libdns_la_SOURCES += rrclass.cc
-libdns_la_SOURCES += rrparamregistry.h
-libdns_la_SOURCES += rrset.h rrset.cc
-libdns_la_SOURCES += rrsetlist.h rrsetlist.cc
-libdns_la_SOURCES += rrttl.h rrttl.cc
-libdns_la_SOURCES += rrtype.cc
-libdns_la_SOURCES += question.h question.cc
-libdns_la_SOURCES += sha1.h sha1.cc
-libdns_la_SOURCES += tsig.h tsig.cc
+libdns___la_SOURCES = base32.h base32.cc
+libdns___la_SOURCES += base64.h base64.cc
+libdns___la_SOURCES += buffer.h
+libdns___la_SOURCES += dnssectime.h dnssectime.cc
+libdns___la_SOURCES += exceptions.h exceptions.cc
+libdns___la_SOURCES += hex.h hex.cc
+libdns___la_SOURCES += message.h message.cc
+libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
+libdns___la_SOURCES += name.h name.cc
+libdns___la_SOURCES += rdata.h rdata.cc
+libdns___la_SOURCES += rrclass.cc
+libdns___la_SOURCES += rrparamregistry.h
+libdns___la_SOURCES += rrset.h rrset.cc
+libdns___la_SOURCES += rrsetlist.h rrsetlist.cc
+libdns___la_SOURCES += rrttl.h rrttl.cc
+libdns___la_SOURCES += rrtype.cc
+libdns___la_SOURCES += question.h question.cc
+libdns___la_SOURCES += sha1.h sha1.cc
+libdns___la_SOURCES += tsig.h tsig.cc
-
-#if HAVE_BOOST_PYTHON
-## This is a loadable module for python scripts, so we use the prefix "pyexec"
-## to make sure the object files will be installed in the appropriate place
-## for this purpose.
-#pyexec_LTLIBRARIES = bind10_dns.la
-#bind10_dns_la_SOURCES = python_dns.cc
-#bind10_dns_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-#bind10_dns_la_CXXFLAGS = $(AM_CXXFLAGS) $(B10_CXXFLAGS)
-#if GCC_WERROR_OK
-## XXX: Boost.Python triggers strict aliasing violation, so if we use -Werror
-## we need to suppress the warnings.
-#bind10_dns_la_CXXFLAGS += -fno-strict-aliasing
-#endif
-#bind10_dns_la_LDFLAGS = $(BOOST_LDFLAGS) $(PYTHON_LDFLAGS)
-## Python prefers .so, while some OSes (specifically MacOS) use a different
-## suffix for dynamic objects. -module is necessary to work this around.
-#bind10_dns_la_LDFLAGS += -module
-#bind10_dns_la_LIBADD = $(top_builddir)/src/lib/dns/libdns.la
-#bind10_dns_la_LIBADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-#bind10_dns_la_LIBADD += $(BOOST_PYTHON_LIB) $(PYTHON_LIB)
-#endif
-
-nodist_libdns_la_SOURCES = rdataclass.cc rrclass.h rrtype.h rrparamregistry.cc
+nodist_libdns___la_SOURCES = rdataclass.cc rrclass.h rrtype.h
+nodist_libdns___la_SOURCES += rrparamregistry.cc
rrclass.h: rrclass-placeholder.h
rrtype.h: rrtype-placeholder.h
@@ -108,8 +86,8 @@
rrclass.h rrtype.h rrparamregistry.cc rdataclass.h rdataclass.cc: Makefile
./gen-rdatacode.py
-libdns_includedir = $(includedir)/dns
-libdns_include_HEADERS = \
+libdns++_includedir = $(includedir)/dns
+libdns++_include_HEADERS = \
buffer.h \
dnssectime.h \
exceptions.h \
Modified: experiments/python-binding/src/lib/dns/message.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/message.cc (original)
+++ experiments/python-binding/src/lib/dns/message.cc Wed Jun 30 13:47:21 2010
@@ -923,7 +923,7 @@
template <typename T>
const T*
SectionIterator<T>::operator->() const {
- return (impl_->it_.operator->());
+ return (&(operator*()));
}
template <typename T>
Modified: experiments/python-binding/src/lib/dns/name.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/name.cc (original)
+++ experiments/python-binding/src/lib/dns/name.cc Wed Jun 30 13:47:21 2010
@@ -267,7 +267,7 @@
if (state == ft_ordinary) {
assert(count != 0);
ndata.at(offsets.back()) = count;
-
+
offsets.push_back(ndata.size());
// add a trailing \0
ndata.push_back('\0');
Modified: experiments/python-binding/src/lib/dns/python/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/dns/python/Makefile.am (original)
+++ experiments/python-binding/src/lib/dns/python/Makefile.am Wed Jun 30 13:47:21 2010
@@ -13,17 +13,22 @@
libdns_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
libdns_python_la_LDFLAGS = $(PYTHON_LDFLAGS)
-#libdns_python_rrset_la_SOURCES = rrset_python.cc
-#libdns_python_rrset_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-#libdns_python_rrset_la_LDFLAGS = $(PYTHON_LDFLAGS) libdns_python_name.la
-
-#libdns_python_rrset_la_SOURCES = rrset_python.cc
-#libdns_python_rrset_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-#libdns_python_rrset_la_LDFLAGS = $(PYTHON_LDFLAGS)
+# directly included from source files, so these don't have their own
+# rules
+EXTRA_DIST = libdns_python_common.h
+EXTRA_DIST += messagerenderer_python.cc
+EXTRA_DIST += message_python.cc
+EXTRA_DIST += rrclass_python.cc
+EXTRA_DIST += name_python.cc
+EXTRA_DIST += rrset_python.cc
+EXTRA_DIST += question_python.cc
+EXTRA_DIST += rrttl_python.cc
+EXTRA_DIST += rdata_python.cc
+EXTRA_DIST += rrtype_python.cc
# Python prefers .so, while some OSes (specifically MacOS) use a different
# suffix for dynamic objects. -module is necessary to work this around.
libdns_python_la_LDFLAGS += -module
-libdns_python_la_LIBADD = $(top_builddir)/src/lib/dns/libdns.la
+libdns_python_la_LIBADD = $(top_builddir)/src/lib/dns/libdns++.la
libdns_python_la_LIBADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
libdns_python_la_LIBADD += $(PYTHON_LIB)
Modified: experiments/python-binding/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/dns/python/tests/Makefile.am (original)
+++ experiments/python-binding/src/lib/dns/python/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -16,7 +16,7 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_srcdir)/src/lib/dns/python/.libs \
+ env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs \
TESTDATA_PATH=$(abs_top_srcdir)/src/lib/dns/tests/testdata \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
done
Modified: experiments/python-binding/src/lib/dns/rrsetlist.cc
==============================================================================
--- experiments/python-binding/src/lib/dns/rrsetlist.cc (original)
+++ experiments/python-binding/src/lib/dns/rrsetlist.cc Wed Jun 30 13:47:21 2010
@@ -29,8 +29,7 @@
namespace dns {
void
-RRsetList::addRRset(RRsetPtr rrsetptr)
-{
+RRsetList::addRRset(RRsetPtr rrsetptr) {
ConstRRsetPtr rrset_found = findRRset(rrsetptr->getType(),
rrsetptr->getClass());
if (rrset_found != NULL) {
@@ -42,8 +41,7 @@
}
RRsetPtr
-RRsetList::findRRset(const RRType& rrtype, const RRClass& rrclass)
-{
+RRsetList::findRRset(const RRType& rrtype, const RRClass& rrclass) {
BOOST_FOREACH(RRsetPtr rrsetptr, rrsets_) {
if ((rrsetptr->getClass() == rrclass) &&
(rrsetptr->getType() == rrtype)) {
Modified: experiments/python-binding/src/lib/dns/rrsetlist.h
==============================================================================
--- experiments/python-binding/src/lib/dns/rrsetlist.h (original)
+++ experiments/python-binding/src/lib/dns/rrsetlist.h Wed Jun 30 13:47:21 2010
@@ -60,7 +60,7 @@
}
P operator->() const
{
- return (it_.operator->());
+ return (&(operator*()));
}
bool operator==(const RRsetListIterator& other)
{
Modified: experiments/python-binding/src/lib/dns/tests/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/dns/tests/Makefile.am (original)
+++ experiments/python-binding/src/lib/dns/tests/Makefile.am Wed Jun 30 13:47:21 2010
@@ -40,7 +40,7 @@
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
-run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns++.a
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
endif
Modified: experiments/python-binding/src/lib/python/isc/Makefile.am
==============================================================================
--- experiments/python-binding/src/lib/python/isc/Makefile.am (original)
+++ experiments/python-binding/src/lib/python/isc/Makefile.am Wed Jun 30 13:47:21 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config # Util
+SUBDIRS = datasrc cc config log # Util
python_PYTHON = __init__.py
Modified: experiments/python-binding/src/lib/python/isc/__init__.py
==============================================================================
--- experiments/python-binding/src/lib/python/isc/__init__.py (original)
+++ experiments/python-binding/src/lib/python/isc/__init__.py Wed Jun 30 13:47:21 2010
@@ -2,3 +2,4 @@
import isc.cc
import isc.config
#import isc.dns
+import isc.log
Modified: experiments/python-binding/src/lib/python/isc/datasrc/master.py
==============================================================================
--- experiments/python-binding/src/lib/python/isc/datasrc/master.py (original)
+++ experiments/python-binding/src/lib/python/isc/datasrc/master.py Wed Jun 30 13:47:21 2010
@@ -16,7 +16,8 @@
# $Id$
import sys, re, string
-
+import time
+import os
#########################################################################
# define exceptions
#########################################################################
@@ -102,7 +103,7 @@
# isttl: check whether a string is a valid TTL specifier.
# returns: boolean
#########################################################################
-ttl_regex = re.compile('[0-9]+[wdhms]?', re.I)
+ttl_regex = re.compile('([0-9]+[wdhms]?)+', re.I)
def isttl(s):
global ttl_regex
if ttl_regex.match(s):
@@ -121,19 +122,26 @@
# MasterFileError
#########################################################################
def parse_ttl(s):
- m = re.match('([0-9]+)(.*)', s)
- if not m:
+ sum = 0
+ if not isttl(s):
raise MasterFileError('Invalid TTL: ' + s)
- ttl, suffix = int(m.group(1)), m.group(2)
- if suffix.lower() == 'w':
- ttl *= 604800
- elif suffix.lower() == 'd':
- ttl *= 86400
- elif suffix.lower() == 'h':
- ttl *= 3600
- elif suffix.lower() == 'm':
- ttl *= 60
- return str(ttl)
+ for ttl_expr in re.findall('\d+[wdhms]?', s, re.I):
+ if ttl_expr.isdigit():
+ ttl = int(ttl_expr)
+ sum += ttl
+ continue
+ ttl = int(ttl_expr[:-1])
+ suffix = ttl_expr[-1].lower()
+ if suffix == 'w':
+ ttl *= 604800
+ elif suffix == 'd':
+ ttl *= 86400
+ elif suffix == 'h':
+ ttl *= 3600
+ elif suffix == 'm':
+ ttl *= 60
+ sum += ttl
+ return str(sum)
#########################################################################
# records: generator function to return complete RRs from the zone file,
@@ -147,7 +155,9 @@
record = []
complete = True
paren = 0
+ size = 0
for line in input:
+ size += len(line)
list = cleanup(line).split()
for word in list:
if paren == 0:
@@ -169,10 +179,12 @@
if paren == 1 or not record:
continue
-
+
ret = ' '.join(record)
record = []
- yield ret
+ oldsize = size
+ size = 0
+ yield ret, oldsize
#########################################################################
# define the MasterFile class for reading zone master files
@@ -181,24 +193,62 @@
__rrclass = 'IN'
__maxttl = 0x7fffffff
__ttl = ''
+ __lastttl = ''
__zonefile = ''
__name = ''
-
- def __init__(self, filename, initial_origin = ''):
- if initial_origin == '.':
- initial_origin = ''
+ __file_level = 0
+ __file_type = ""
+ __init_time = time.time()
+ __records_num = 0
+
+ def __init__(self, filename, initial_origin = '', verbose = False):
self.__initial_origin = initial_origin
self.__origin = initial_origin
+ self.__datafile = filename
+
try:
self.__zonefile = open(filename, 'r')
except:
raise MasterFileError("Could not open " + filename)
+ self.__filesize = os.fstat(self.__zonefile.fileno()).st_size
+
+ self.__cur = 0
+ self.__numback = 0
+ self.__verbose = verbose
+ try:
+ self.__zonefile = open(filename, 'r')
+ except:
+ raise MasterFileError("Could not open " + filename)
+
+ def __status(self):
+ interval = time.time() - MasterFile.__init_time
+ if self.__filesize == 0:
+ percent = 100
+ else:
+ percent = (self.__cur * 100)/self.__filesize
+
+ sys.stdout.write("\r" + (80 * " "))
+ sys.stdout.write("\r%d RR(s) loaded in %d second(s) (%.2f%% of %s%s)"\
+ % (MasterFile.__records_num, interval, percent, MasterFile.__file_type, self.__datafile))
def __del__(self):
if self.__zonefile:
self.__zonefile.close()
-
- #########################################################################
+ ########################################################################
+ # check if the zonename is relative
+ # no then return
+ # yes , sets the relative domain name to the stated name
+ #######################################################################
+ def __statedname(self, name, record):
+ if name[-1] != '.':
+ if not self.__origin:
+ raise MasterFileError("Cannot parse RR, No $ORIGIN: " + record)
+ elif self.__origin == '.':
+ name += '.'
+ else:
+ name += '.' + self.__origin
+ return name
+ #####################################################################
# handle $ORIGIN, $TTL and $GENERATE directives
# (currently only $ORIGIN and $TTL are implemented)
# input:
@@ -216,20 +266,22 @@
raise MasterFileError('Invalid $ORIGIN')
if more:
raise MasterFileError('Invalid $ORIGIN')
- if second == '.':
- self.__origin = ''
- elif second[-1] == '.':
+ if second[-1] == '.':
self.__origin = second
+ elif not self.__origin:
+ raise MasterFileError("$ORIGIN is not absolute in record:%s" % s)
+ elif self.__origin != '.':
+ self.__origin = second + '.' + self.__origin
else:
- self.__origin = second + '.' + self.__origin
+ self.__origin = second + '.'
return True
elif re.match('\$ttl', first, re.I):
if not second or not isttl(second):
raise MasterFileError('Invalid TTL: "' + second + '"')
if more:
raise MasterFileError('Invalid $TTL statement')
- self.__ttl = parse_ttl(second)
- if int(self.__ttl) > self.__maxttl:
+ MasterFile.__ttl = parse_ttl(second)
+ if int(MasterFile.__ttl) > self.__maxttl:
raise MasterFileError('TTL too high: ' + second)
return True
elif re.match('\$generate', first, re.I):
@@ -246,14 +298,28 @@
# throws:
# MasterFileError
#########################################################################
- __filename = re.compile('[\"\']*([^\'\"]+)[\"\']*')
+ __include_syntax1 = re.compile('\s+(\S+)(?:\s+(\S+))?$', re.I)
+ __include_syntax2 = re.compile('\s+"([^"]+)"(?:\s+(\S+))?$', re.I)
+ __include_syntax3 = re.compile("\s+'([^']+)'(?:\s+(\S+))?$", re.I)
def __include(self, s):
- first, rest = pop(s)
- if re.match('\$include', first, re.I):
- m = self.__filename.match(rest)
- if m:
- file = m.group(1)
- return file
+ if not s.lower().startswith('$include'):
+ return "", ""
+ s = s[len('$include'):]
+ m = self.__include_syntax1.match(s)
+ if not m:
+ m = self.__include_syntax2.match(s)
+ if not m:
+ m = self.__include_syntax3.match(s)
+ if not m:
+ raise MasterFileError('Invalid $include format')
+ file = m.group(1)
+ if m.group(2):
+ if not isname(m.group(2)):
+ raise MasterFileError('Invalid $include format (invalid origin)')
+ origin = self.__statedname(m.group(2), s)
+ else:
+ origin = self.__origin
+ return file, origin
#########################################################################
# try parsing an RR on the assumption that the type is specified in
@@ -272,6 +338,14 @@
if istype(list[3]):
if isclass(list[2]) and isttl(list[1]) and isname(list[0]):
name, ttl, rrclass, rrtype = list[0:4]
+ ttl = parse_ttl(ttl)
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
+ rdata = ' '.join(list[4:])
+ ret = name, ttl, rrclass, rrtype, rdata
+ elif isclass(list[1]) and isttl(list[2]) and isname(list[0]):
+ name, rrclass, ttl, rrtype = list[0:4]
+ ttl = parse_ttl(ttl)
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
rdata = ' '.join(list[4:])
ret = name, ttl, rrclass, rrtype, rdata
return ret
@@ -284,6 +358,9 @@
# returns:
# empty list if parse failed, else name, ttl, class, type, rdata
#########################################################################
+ def __getttl(self):
+ return MasterFile.__ttl or MasterFile.__lastttl
+
def __three(self, record, curname):
ret = ''
list = record.split()
@@ -292,19 +369,25 @@
if istype(list[2]) and not istype(list[1]):
if isclass(list[1]) and not isttl(list[0]) and isname(list[0]):
rrclass = list[1]
- ttl = self.__ttl
+ ttl = self.__getttl()
name = list[0]
- elif not isclass(list[1]) and isttl(list[1]) and isname(list[0]):
+ elif not isclass(list[1]) and isttl(list[1]) and not isclass(list[0]) and isname(list[0]):
rrclass = self.__rrclass
ttl = parse_ttl(list[1])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
name = list[0]
elif curname and isclass(list[1]) and isttl(list[0]):
- rrclass = self.__rrclass
+ rrclass = list[1]
ttl = parse_ttl(list[0])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
+ name = curname
+ elif curname and isttl(list[1]) and isclass(list[0]):
+ rrclass = list[0]
+ ttl = parse_ttl(list[1])
+ MasterFile.__lastttl = ttl or MasterFile.__lastttl
name = curname
else:
return ret
-
rrtype = list[2]
rdata = ' '.join(list[3:])
ret = name, ttl, rrclass, rrtype, rdata
@@ -325,29 +408,37 @@
list = record.split()
if len(list) <= 2:
return ret
-
if istype(list[1]):
rrclass = self.__rrclass
rrtype = list[1]
if list[0].lower() == 'rrsig':
name = curname
- ttl = self.__ttl
+ ttl = self.__getttl()
rrtype = list[0]
rdata = ' '.join(list[1:])
elif isttl(list[0]):
ttl = parse_ttl(list[0])
name = curname
rdata = ' '.join(list[2:])
+ elif isclass(list[0]):
+ ttl = self.__getttl()
+ name = curname
+ rdata = ' '.join(list[2:])
elif isname(list[0]):
name = list[0]
- ttl = self.__ttl
+ ttl = self.__getttl()
rdata = ' '.join(list[2:])
else:
raise MasterFileError("Cannot parse RR: " + record)
ret = name, ttl, rrclass, rrtype, rdata
-
return ret
+
+ ########################################################################
+ #close verbose
+ ######################################################################
+ def closeverbose(self):
+ self.__status()
#########################################################################
# zonedata: generator function to parse a zone master file and return
@@ -355,16 +446,43 @@
#########################################################################
def zonedata(self):
name = ''
-
- for record in records(self.__zonefile):
+ last_status = 0.0
+ flag = 1
+
+ for record, size in records(self.__zonefile):
+ if self.__verbose:
+ now = time.time()
+ if flag == 1:
+ self.__status()
+ flag = 0
+ if now - last_status >= 1.0:
+ self.__status()
+ last_status = now
+
+ self.__cur += size
if self.__directive(record):
continue
- incl = self.__include(record)
+ incl, suborigin = self.__include(record)
if incl:
- sub = MasterFile(incl, self.__origin)
- for name, ttl, rrclass, rrtype, rdata in sub.zonedata():
- yield (name, ttl, rrclass, rrtype, rdata)
+ if self.__filesize == 0:
+ percent = 100
+ else:
+ percent = (self.__cur * 100)/self.__filesize
+ if self.__verbose:
+ sys.stdout.write("\r" + (80 * " "))
+ sys.stdout.write("\rIncluding \"%s\" from \"%s\"\n" % (incl, self.__datafile))
+ MasterFile.__file_level += 1
+ MasterFile.__file_type = "included "
+ sub = MasterFile(incl, suborigin, self.__verbose)
+
+ for rrname, ttl, rrclass, rrtype, rdata in sub.zonedata():
+ yield (rrname, ttl, rrclass, rrtype, rdata)
+ if self.__verbose:
+ sub.closeverbose()
+ MasterFile.__file_level -= 1
+ if MasterFile.__file_level == 0:
+ MasterFile.__file_type = ""
del sub
continue
@@ -373,7 +491,7 @@
if rl[0] == '@':
rl[0] = self.__origin
if not self.__origin:
- rl[0] = '.'
+ raise MasterFileError("Cannot parse RR, No $ORIGIN: " + record)
record = ' '.join(rl)
result = self.__four(record, name)
@@ -387,36 +505,43 @@
if not result:
first, rdata = pop(record)
if istype(first):
- result = name, self.__ttl, self.__rrclass, first, rdata
+ result = name, self.__getttl(), self.__rrclass, first, rdata
if not result:
raise MasterFileError("Cannot parse RR: " + record)
name, ttl, rrclass, rrtype, rdata = result
- if name[-1] != '.':
- name += '.' + self.__origin
+ name = self.__statedname(name, record)
if rrclass.lower() != 'in':
raise MasterFileError("CH and HS zones not supported")
-
- if not ttl:
- raise MasterFileError("No TTL specified; zone rejected")
# add origin to rdata containing names, if necessary
if rrtype.lower() in ('cname', 'dname', 'ns', 'ptr'):
if not isname(rdata):
raise MasterFileError("Invalid " + rrtype + ": " + rdata)
- if rdata[-1] != '.':
- rdata += '.' + self.__origin
+ rdata = self.__statedname(rdata, record)
+
if rrtype.lower() == 'soa':
soa = rdata.split()
if len(soa) < 2 or not isname(soa[0]) or not isname(soa[1]):
raise MasterFileError("Invalid " + rrtype + ": " + rdata)
- if soa[0][-1] != '.':
- soa[0] += '.' + self.__origin
- if soa[1][-1] != '.':
- soa[1] += '.' + self.__origin
+ soa[0] = self.__statedname(soa[0], record)
+ soa[1] = self.__statedname(soa[1], record)
+ if not MasterFile.__ttl and not ttl:
+ MasterFile.__ttl = MasterFile.__ttl or parse_ttl(soa[-1])
+ ttl = MasterFile.__ttl
+
+ for index in range(3, len(soa)):
+ if isttl(soa[index]):
+ soa[index] = parse_ttl(soa[index])
+ else :
+ raise MasterFileError("No TTL specified; in soa record!")
rdata = ' '.join(soa)
+
+ if not ttl:
+ raise MasterFileError("No TTL specified; zone rejected")
+
if rrtype.lower() == 'mx':
mx = rdata.split()
if len(mx) != 2 or not isname(mx[1]):
@@ -424,7 +549,7 @@
if mx[1][-1] != '.':
mx[1] += '.' + self.__origin
rdata = ' '.join(mx)
-
+ MasterFile.__records_num += 1
yield (name, ttl, rrclass, rrtype, rdata)
#########################################################################
@@ -436,16 +561,22 @@
return self.__name
old_origin = self.__origin
self.__origin = self.__initial_origin
+ cur_value = self.__cur
old_location = self.__zonefile.tell()
+ old_verbose = self.__verbose
+ self.__verbose = False
self.__zonefile.seek(0)
+
for name, ttl, rrclass, rrtype, rdata in self.zonedata():
if rrtype.lower() == 'soa':
break
self.__zonefile.seek(old_location)
self.__origin = old_origin
+ self.__cur = cur_value
if rrtype.lower() != 'soa':
raise MasterFileError("No SOA found")
self.__name = name
+ self.__verbose = old_verbose
return name
#########################################################################
@@ -454,7 +585,8 @@
def reset(self):
self.__zonefile.seek(0)
self.__origin = self.__initial_origin
- self.__ttl = ''
+ MasterFile.__ttl = ''
+ MasterFile.__lastttl = ''
#########################################################################
# main: used for testing; parse a zone file and print out each record
More information about the bind10-changes
mailing list