[svn] commit: r3143 - in /branches/trac232: ./ doc/guide/ src/bin/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/bind10/tests/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/host/ src/bin/loadzone/ src/bin/msgq/ src/bin/tests/ src/bin/usermgr/ src/bin/xfrin/ src/bin/xfrin/tests/ src/bin/xfrout/ src/bin/xfrout/tests/ src/bin/zonemgr/ src/lib/bench/ src/lib/bench/tests/ src/lib/cc/tests/ src/lib/config/ src/lib/config/testdata/ src/lib/config/tests/ src/lib/config/tests/testdata/ src/lib/datasrc/ src/lib/datasrc/python/ src/lib/datasrc/python/tests/ src/lib/datasrc/tests/ src/lib/dns/ src/lib/dns/python/ src/lib/dns/python/tests/ src/lib/dns/tests/ src/lib/dns/tests/testdata/ src/lib/exceptions/ src/lib/python/isc/ src/lib/python/isc/cc/ src/lib/python/isc/cc/tests/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/dns/ src/lib/python/isc/log/ src/lib/python/isc/notify/ src/lib/python/isc/utils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Oct 8 09:51:10 UTC 2010
Author: jelte
Date: Fri Oct 8 09:51:09 2010
New Revision: 3143
Log:
sync with trunk
Added:
branches/trac232/src/bin/auth/benchmarks/
- copied from r3135, trunk/src/bin/auth/benchmarks/
branches/trac232/src/bin/auth/tests/testdata/Makefile.am
- copied unchanged from r3135, trunk/src/bin/auth/tests/testdata/Makefile.am
branches/trac232/src/bin/tests/
- copied from r3135, trunk/src/bin/tests/
branches/trac232/src/bin/zonemgr/b10-zonemgr.8
- copied unchanged from r3135, trunk/src/bin/zonemgr/b10-zonemgr.8
branches/trac232/src/bin/zonemgr/b10-zonemgr.xml
- copied unchanged from r3135, trunk/src/bin/zonemgr/b10-zonemgr.xml
branches/trac232/src/lib/config/tests/testdata/
- copied from r3135, trunk/src/lib/config/tests/testdata/
branches/trac232/src/lib/dns/edns.cc
- copied unchanged from r3135, trunk/src/lib/dns/edns.cc
branches/trac232/src/lib/dns/edns.h
- copied unchanged from r3135, trunk/src/lib/dns/edns.h
branches/trac232/src/lib/dns/opcode.cc
- copied unchanged from r3135, trunk/src/lib/dns/opcode.cc
branches/trac232/src/lib/dns/opcode.h
- copied unchanged from r3135, trunk/src/lib/dns/opcode.h
branches/trac232/src/lib/dns/python/edns_python.cc
- copied unchanged from r3135, trunk/src/lib/dns/python/edns_python.cc
branches/trac232/src/lib/dns/python/opcode_python.cc
- copied unchanged from r3135, trunk/src/lib/dns/python/opcode_python.cc
branches/trac232/src/lib/dns/python/pydnspp.cc
- copied unchanged from r3135, trunk/src/lib/dns/python/pydnspp.cc
branches/trac232/src/lib/dns/python/pydnspp_common.cc
- copied unchanged from r3135, trunk/src/lib/dns/python/pydnspp_common.cc
branches/trac232/src/lib/dns/python/pydnspp_common.h
- copied unchanged from r3135, trunk/src/lib/dns/python/pydnspp_common.h
branches/trac232/src/lib/dns/python/rcode_python.cc
- copied unchanged from r3135, trunk/src/lib/dns/python/rcode_python.cc
branches/trac232/src/lib/dns/python/tests/edns_python_test.py
- copied unchanged from r3135, trunk/src/lib/dns/python/tests/edns_python_test.py
branches/trac232/src/lib/dns/python/tests/opcode_python_test.py
- copied unchanged from r3135, trunk/src/lib/dns/python/tests/opcode_python_test.py
branches/trac232/src/lib/dns/python/tests/rcode_python_test.py
- copied unchanged from r3135, trunk/src/lib/dns/python/tests/rcode_python_test.py
branches/trac232/src/lib/dns/python/tests/testutil.py
- copied unchanged from r3135, trunk/src/lib/dns/python/tests/testutil.py
branches/trac232/src/lib/dns/rcode.cc
- copied unchanged from r3135, trunk/src/lib/dns/rcode.cc
branches/trac232/src/lib/dns/rcode.h
- copied unchanged from r3135, trunk/src/lib/dns/rcode.h
branches/trac232/src/lib/dns/tests/edns_unittest.cc
- copied unchanged from r3135, trunk/src/lib/dns/tests/edns_unittest.cc
branches/trac232/src/lib/dns/tests/opcode_unittest.cc
- copied unchanged from r3135, trunk/src/lib/dns/tests/opcode_unittest.cc
branches/trac232/src/lib/dns/tests/rcode_unittest.cc
- copied unchanged from r3135, trunk/src/lib/dns/tests/rcode_unittest.cc
branches/trac232/src/lib/dns/tests/testdata/Makefile.am
- copied unchanged from r3135, trunk/src/lib/dns/tests/testdata/Makefile.am
branches/trac232/src/lib/dns/tests/testdata/edns_toWire1.spec
- copied unchanged from r3135, trunk/src/lib/dns/tests/testdata/edns_toWire1.spec
branches/trac232/src/lib/dns/tests/testdata/edns_toWire2.spec
- copied unchanged from r3135, trunk/src/lib/dns/tests/testdata/edns_toWire2.spec
branches/trac232/src/lib/dns/tests/testdata/edns_toWire3.spec
- copied unchanged from r3135, trunk/src/lib/dns/tests/testdata/edns_toWire3.spec
branches/trac232/src/lib/dns/tests/testdata/edns_toWire4.spec
- copied unchanged from r3135, trunk/src/lib/dns/tests/testdata/edns_toWire4.spec
branches/trac232/src/lib/python/isc/utils/
- copied from r3135, trunk/src/lib/python/isc/utils/
Removed:
branches/trac232/src/bin/auth/tests/testdata/badExampleQuery_fromWire
branches/trac232/src/bin/auth/tests/testdata/examplequery_fromWire
branches/trac232/src/bin/auth/tests/testdata/iqueryresponse_fromWire
branches/trac232/src/bin/auth/tests/testdata/multiquestion_fromWire
branches/trac232/src/bin/auth/tests/testdata/queryBadEDNS_fromWire
branches/trac232/src/bin/auth/tests/testdata/shortanswer_fromWire
branches/trac232/src/bin/auth/tests/testdata/simplequery_fromWire
branches/trac232/src/bin/auth/tests/testdata/simpleresponse_fromWire
branches/trac232/src/lib/config/testdata/Makefile.am
branches/trac232/src/lib/config/testdata/b10-config-bad1.db
branches/trac232/src/lib/config/testdata/b10-config-bad2.db
branches/trac232/src/lib/config/testdata/b10-config-bad3.db
branches/trac232/src/lib/config/testdata/b10-config-bad4.db
branches/trac232/src/lib/config/testdata/b10-config.db.master
branches/trac232/src/lib/config/testdata/data22_1.data
branches/trac232/src/lib/config/testdata/data22_2.data
branches/trac232/src/lib/config/testdata/data22_3.data
branches/trac232/src/lib/config/testdata/data22_4.data
branches/trac232/src/lib/config/testdata/data22_5.data
branches/trac232/src/lib/config/testdata/data22_6.data
branches/trac232/src/lib/config/testdata/data22_7.data
branches/trac232/src/lib/config/testdata/data22_8.data
branches/trac232/src/lib/config/testdata/spec1.spec
branches/trac232/src/lib/config/testdata/spec10.spec
branches/trac232/src/lib/config/testdata/spec11.spec
branches/trac232/src/lib/config/testdata/spec12.spec
branches/trac232/src/lib/config/testdata/spec13.spec
branches/trac232/src/lib/config/testdata/spec14.spec
branches/trac232/src/lib/config/testdata/spec15.spec
branches/trac232/src/lib/config/testdata/spec16.spec
branches/trac232/src/lib/config/testdata/spec17.spec
branches/trac232/src/lib/config/testdata/spec18.spec
branches/trac232/src/lib/config/testdata/spec19.spec
branches/trac232/src/lib/config/testdata/spec2.spec
branches/trac232/src/lib/config/testdata/spec20.spec
branches/trac232/src/lib/config/testdata/spec21.spec
branches/trac232/src/lib/config/testdata/spec22.spec
branches/trac232/src/lib/config/testdata/spec23.spec
branches/trac232/src/lib/config/testdata/spec24.spec
branches/trac232/src/lib/config/testdata/spec25.spec
branches/trac232/src/lib/config/testdata/spec26.spec
branches/trac232/src/lib/config/testdata/spec27.spec
branches/trac232/src/lib/config/testdata/spec28.spec
branches/trac232/src/lib/config/testdata/spec3.spec
branches/trac232/src/lib/config/testdata/spec4.spec
branches/trac232/src/lib/config/testdata/spec5.spec
branches/trac232/src/lib/config/testdata/spec6.spec
branches/trac232/src/lib/config/testdata/spec7.spec
branches/trac232/src/lib/config/testdata/spec8.spec
branches/trac232/src/lib/config/testdata/spec9.spec
branches/trac232/src/lib/dns/message_test.py
branches/trac232/src/lib/dns/python/libdns_python.cc
branches/trac232/src/lib/dns/python/libdns_python_common.cc
branches/trac232/src/lib/dns/python/libdns_python_common.h
branches/trac232/src/lib/dns/python/tests/test.py
branches/trac232/src/lib/dns/tests/testdata/message_fromWire10
branches/trac232/src/lib/dns/tests/testdata/message_fromWire11
branches/trac232/src/lib/dns/tests/testdata/name_toWire5
branches/trac232/src/lib/dns/tests/testdata/name_toWire6
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire10
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire4
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire5
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire6
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire7
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire8
branches/trac232/src/lib/dns/tests/testdata/rdata_nsec_fromWire9
branches/trac232/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2
branches/trac232/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed
branches/trac232/src/lib/dns/tests/testdata/rdata_txt_fromWire2
branches/trac232/src/lib/dns/tests/testdata/rdata_txt_fromWire3
branches/trac232/src/lib/dns/tests/testdata/rdata_txt_fromWire4
branches/trac232/src/lib/dns/tests/testdata/rdata_txt_fromWire5
Modified:
branches/trac232/ (props changed)
branches/trac232/ChangeLog
branches/trac232/README
branches/trac232/configure.ac
branches/trac232/doc/guide/bind10-guide.html
branches/trac232/doc/guide/bind10-guide.xml
branches/trac232/src/bin/Makefile.am
branches/trac232/src/bin/auth/Makefile.am
branches/trac232/src/bin/auth/asio_link.cc
branches/trac232/src/bin/auth/auth_srv.cc
branches/trac232/src/bin/auth/auth_srv.h
branches/trac232/src/bin/auth/b10-auth.8
branches/trac232/src/bin/auth/b10-auth.xml
branches/trac232/src/bin/auth/tests/Makefile.am
branches/trac232/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac232/src/bin/auth/tests/run_unittests.cc
branches/trac232/src/bin/bind10/Makefile.am
branches/trac232/src/bin/bind10/bind10.8
branches/trac232/src/bin/bind10/bind10.py.in
branches/trac232/src/bin/bind10/bind10.xml
branches/trac232/src/bin/bind10/tests/args_test.py
branches/trac232/src/bin/bindctl/Makefile.am
branches/trac232/src/bin/bindctl/bindctl-source.py.in
branches/trac232/src/bin/cfgmgr/Makefile.am
branches/trac232/src/bin/cfgmgr/b10-cfgmgr.py.in
branches/trac232/src/bin/cmdctl/Makefile.am
branches/trac232/src/bin/cmdctl/cmdctl.py.in
branches/trac232/src/bin/host/host.cc
branches/trac232/src/bin/loadzone/Makefile.am
branches/trac232/src/bin/loadzone/b10-loadzone.py.in
branches/trac232/src/bin/msgq/Makefile.am
branches/trac232/src/bin/msgq/msgq.py.in
branches/trac232/src/bin/usermgr/b10-cmdctl-usermgr.py.in
branches/trac232/src/bin/xfrin/Makefile.am
branches/trac232/src/bin/xfrin/TODO
branches/trac232/src/bin/xfrin/b10-xfrin.8
branches/trac232/src/bin/xfrin/b10-xfrin.xml
branches/trac232/src/bin/xfrin/tests/xfrin_test.py
branches/trac232/src/bin/xfrin/xfrin.py.in
branches/trac232/src/bin/xfrout/Makefile.am
branches/trac232/src/bin/xfrout/TODO
branches/trac232/src/bin/xfrout/b10-xfrout.8
branches/trac232/src/bin/xfrout/b10-xfrout.xml
branches/trac232/src/bin/xfrout/tests/xfrout_test.py
branches/trac232/src/bin/xfrout/xfrout.py.in
branches/trac232/src/bin/zonemgr/Makefile.am
branches/trac232/src/bin/zonemgr/TODO
branches/trac232/src/bin/zonemgr/zonemgr.py.in
branches/trac232/src/lib/bench/benchmark_util.cc
branches/trac232/src/lib/bench/tests/benchmark_unittest.cc
branches/trac232/src/lib/bench/tests/loadquery_unittest.cc
branches/trac232/src/lib/cc/tests/Makefile.am
branches/trac232/src/lib/config/Makefile.am
branches/trac232/src/lib/config/tests/Makefile.am
branches/trac232/src/lib/config/tests/data_def_unittests_config.h.in
branches/trac232/src/lib/datasrc/data_source.cc
branches/trac232/src/lib/datasrc/python/libdata_source_python.cc
branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py
branches/trac232/src/lib/datasrc/tests/datasrc_unittest.cc
branches/trac232/src/lib/datasrc/tests/query_unittest.cc
branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc
branches/trac232/src/lib/dns/Makefile.am
branches/trac232/src/lib/dns/exceptions.cc
branches/trac232/src/lib/dns/message.cc
branches/trac232/src/lib/dns/message.h
branches/trac232/src/lib/dns/name.cc
branches/trac232/src/lib/dns/python/Makefile.am
branches/trac232/src/lib/dns/python/README
branches/trac232/src/lib/dns/python/message_python.cc
branches/trac232/src/lib/dns/python/messagerenderer_python.cc
branches/trac232/src/lib/dns/python/name_python.cc
branches/trac232/src/lib/dns/python/question_python.cc
branches/trac232/src/lib/dns/python/rdata_python.cc
branches/trac232/src/lib/dns/python/rrclass_python.cc
branches/trac232/src/lib/dns/python/rrset_python.cc
branches/trac232/src/lib/dns/python/rrttl_python.cc
branches/trac232/src/lib/dns/python/rrtype_python.cc
branches/trac232/src/lib/dns/python/tests/Makefile.am
branches/trac232/src/lib/dns/python/tests/message_python_test.py
branches/trac232/src/lib/dns/python/tests/messagerenderer_python_test.py
branches/trac232/src/lib/dns/python/tests/name_python_test.py
branches/trac232/src/lib/dns/python/tests/question_python_test.py
branches/trac232/src/lib/dns/python/tests/rdata_python_test.py
branches/trac232/src/lib/dns/python/tests/rrclass_python_test.py
branches/trac232/src/lib/dns/python/tests/rrset_python_test.py
branches/trac232/src/lib/dns/python/tests/rrttl_python_test.py
branches/trac232/src/lib/dns/python/tests/rrtype_python_test.py
branches/trac232/src/lib/dns/rrclass-placeholder.h
branches/trac232/src/lib/dns/rrset.h
branches/trac232/src/lib/dns/rrtype-placeholder.h
branches/trac232/src/lib/dns/tests/Makefile.am
branches/trac232/src/lib/dns/tests/message_unittest.cc
branches/trac232/src/lib/dns/tests/messagerenderer_unittest.cc
branches/trac232/src/lib/dns/tests/rdata_nsec_unittest.cc
branches/trac232/src/lib/dns/tests/rdata_rrsig_unittest.cc
branches/trac232/src/lib/dns/tests/rdata_soa_unittest.cc
branches/trac232/src/lib/dns/tests/rdata_txt_unittest.cc
branches/trac232/src/lib/dns/tests/run_unittests.cc
branches/trac232/src/lib/dns/tests/testdata/gen-wiredata.py.in
branches/trac232/src/lib/exceptions/exceptions.h
branches/trac232/src/lib/python/isc/Makefile.am
branches/trac232/src/lib/python/isc/cc/Makefile.am
branches/trac232/src/lib/python/isc/cc/session.py
branches/trac232/src/lib/python/isc/cc/tests/session_test.py
branches/trac232/src/lib/python/isc/config/Makefile.am
branches/trac232/src/lib/python/isc/config/ccsession.py
branches/trac232/src/lib/python/isc/config/cfgmgr.py
branches/trac232/src/lib/python/isc/config/tests/Makefile.am
branches/trac232/src/lib/python/isc/config/tests/unittest_fakesession.py
branches/trac232/src/lib/python/isc/dns/__init__.py
branches/trac232/src/lib/python/isc/log/Makefile.am
branches/trac232/src/lib/python/isc/notify/Makefile.am
branches/trac232/src/lib/python/isc/notify/notify_out.py
Modified: branches/trac232/ChangeLog
==============================================================================
--- branches/trac232/ChangeLog (original)
+++ branches/trac232/ChangeLog Fri Oct 8 09:51:09 2010
@@ -1,6 +1,66 @@
+ 102. [build] jinmei
+ Disable threads in ASIO to minimize build time dependency.
+ (Trac #345, r3100)
+
+ 101. [func] jinmei
+ src/lib/dns: Completed Opcode and Rcode implementation with more
+ tests and documentation. API is mostly the same but the
+ validation was a bit tightened. (Trac #351, svn r3056)
+
+ 100. [func] Michal Vaner
+ Python processes: support naming of python processes so
+ they're not all called python3.
+ (Trac #322, svn r3052)
+
+ 99. [func]* jinmei
+ Introduced a separate EDNS class to encapsulate EDNS related
+ information more cleanly. The related APIs are changed a bit,
+ although it won't affect most of higher level applications.
+ (Trac #311, svn r3020)
+
+ 98. [build] jinmei
+ The ./configure script now tries to search some common include
+ paths for boost header files to minimize the need for explicit
+ configuration with --with-boost-include. (Trac #323, svn r3006)
+
+ 97. [func] jinmei
+ Added a micro benchmark test for query processing of b10-auth.
+ (Trac #308, svn r2982)
+
+ 96. [bug] jinmei
+ Fixed two small issues with configure: Do not set CXXFLAGS so that
+ it can be customized; Make sure --disable-static works.
+ (Trac #325, r2976)
+
+bind10-devel-20100917 released on September 17, 2010
+
+ 95. [doc] jreed
+ Add b10-zonemgr manual page. Update other docs to introduce
+ this secondary manager. (Trac #341, svn r2951)
+
+ 95. [bug] jreed
+ bin/xfrout and bin/zonemgr: Fixed some stderr output.
+ (Trac #342, svn r2949)
+
+ 94. [bug] jelte
+ bin/xfrout: Fixed a problem in xfrout where only 2 or 3 RRs
+ were used per DNS message in the xfrout stream.
+ (Trac #334, r2931)
+
+ 93. [bug] jinmei
+ lib/datasrc: A DS query could crash the library (and therefore,
+ e.g. the authoritative server) if some RR of the same apex name
+ is stored in the hot spot cache. (Trac #307, svn r2923)
+
+ 92. [func]* jelte
+ libdns_python (the python wrappers for libdns++) has been renamed
+ to pydnspp (Python DNS++). Programs and libraries that used
+ 'import libdns_python' now need to use 'import pydnspp'.
+ (Trac #314, r2902)
+
91. [func]* jinmei
lib/cc: Use const pointers and const member functions for the API
- as much as possible for safer operations. Basically this does
+ as much as possible for safer operations. Basically this does not
change the observable behavior, but some of the API were changed
in a backward incompatible manner. This change also involves more
copies, but at this moment the overhead is deemed acceptable.
Modified: branches/trac232/README
==============================================================================
--- branches/trac232/README (original)
+++ branches/trac232/README Fri Oct 8 09:51:09 2010
@@ -17,7 +17,8 @@
bus, b10-auth authoritative DNS server (with SQLite3 backend),
b10-cmdctl remote control daemon, b10-cfgmgr configuration manager,
b10-xfrin AXFR inbound service, b10-xfrout outgoing AXFR service,
-and a new libdns++ library for C++ with a python wrapper.
+b10-zonemgr secondary manager, and a new libdns++ library for C++
+with a python wrapper.
Documentation is included and also available via the BIND 10
website at http://bind10.isc.org/
Modified: branches/trac232/configure.ac
==============================================================================
--- branches/trac232/configure.ac (original)
+++ branches/trac232/configure.ac Fri Oct 8 09:51:09 2010
@@ -39,6 +39,20 @@
[build programs with static link [[default=no]]]),
[enable_static_link=yes], [enable_static_link=no])
AM_CONDITIONAL(USE_STATIC_LINK, test $enable_static_link = yes)
+
+# Check validity about some libtool options
+if test $enable_static_link = yes -a $enable_static = no; then
+ AC_MSG_ERROR([--enable-static-link requires --enable-static])
+fi
+if test $enable_shared = no; then
+ AC_MSG_ERROR([BIND 10 requires shared libraries to be built])
+fi
+
+# allow configuring without setproctitle.
+AC_ARG_ENABLE(setproctitle-check,
+AC_HELP_STRING([--disable-setproctitle-check],
+ [do not check for python setproctitle module (used to give nice names to python processes)]),
+ setproctitle_check=$enableval, setproctitle_check=yes)
# OS dependent configuration
SET_ENV_LIBRARY_PATH=no
@@ -154,6 +168,18 @@
AC_SUBST(PYTHON_LIB)
LDFLAGS=$LDFLAGS_SAVED
+# Check for the setproctitle module
+if test "$setproctitle_check" = "yes" ; then
+ AC_MSG_CHECKING(for setproctitle module)
+ if "$PYTHON" -c 'import setproctitle' 2>/dev/null ; then
+ AC_MSG_RESULT(ok)
+ else
+ AC_MSG_RESULT(missing)
+ AC_MSG_ERROR([Missing setproctitle module. Either install it or provide --disable-setproctitle-check.
+In that case we will continue, but naming of python processes will not work.])
+ fi
+fi
+
# TODO: check for _sqlite3.py module
# Compiler dependent settings: define some mandatory CXXFLAGS here.
@@ -167,7 +193,6 @@
# specify the default warning flags in CXXFLAGS and let specific modules
# "override" the default.
-CXXFLAGS=-g
werror_ok=0
# SunStudio compiler requires special compiler options for boost
@@ -270,14 +295,31 @@
fi
AC_SUBST(USE_LCOV)
+#
+# Configure Boost header path
+#
+# If explicitly specified, use it.
AC_ARG_WITH([boost-include],
AC_HELP_STRING([--with-boost-include=PATH],
[specify exact directory for Boost headers]),
[boost_include_path="$withval"])
+# If not specified, try some common paths.
+if test -z "$with_boost_include"; then
+ boostdirs="/usr/local /usr/pkg /opt /opt/local"
+ for d in $boostdirs
+ do
+ if test -f $d/include/boost/shared_ptr.hpp; then
+ boost_include_path=$d/include
+ break
+ fi
+ done
+fi
if test "${boost_include_path}" ; then
BOOST_INCLUDES="-I${boost_include_path}"
CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES"
fi
+AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
+ AC_MSG_ERROR([Missing required header files.]))
AC_SUBST(BOOST_INCLUDES)
#
@@ -351,6 +393,9 @@
# Use local ASIO headers from ext
#
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/ext/asio"
+#
+# Disable threads: Currently we don't use them.
+CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_THREADS=1"
#
# kqueue portability: ASIO uses kqueue by default if it's available (it's
# generally available in BSD variants). Unfortunately, some public
@@ -389,10 +434,6 @@
CPPFLAGS="$CPPFLAGS -DASIO_DISABLE_DEV_POLL=1"
fi
-# Check for headers from required devel kits.
-AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
- AC_MSG_ERROR([Missing required header files.]))
-
AC_ARG_ENABLE(man, [AC_HELP_STRING([--enable-man],
[regenerate man pages [default=no]])] ,enable_man=yes, enable_man=no)
@@ -423,6 +464,8 @@
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
+ src/bin/auth/tests/testdata/Makefile
+ src/bin/auth/benchmarks/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
@@ -430,6 +473,7 @@
src/bin/zonemgr/Makefile
src/bin/zonemgr/tests/Makefile
src/bin/usermgr/Makefile
+ src/bin/tests/Makefile
src/lib/Makefile
src/lib/bench/Makefile
src/lib/bench/example/Makefile
@@ -438,6 +482,8 @@
src/lib/cc/tests/Makefile
src/lib/python/Makefile
src/lib/python/isc/Makefile
+ src/lib/python/isc/utils/Makefile
+ src/lib/python/isc/utils/tests/Makefile
src/lib/python/isc/datasrc/Makefile
src/lib/python/isc/cc/Makefile
src/lib/python/isc/cc/tests/Makefile
@@ -449,9 +495,10 @@
src/lib/python/isc/notify/tests/Makefile
src/lib/config/Makefile
src/lib/config/tests/Makefile
- src/lib/config/testdata/Makefile
+ src/lib/config/tests/testdata/Makefile
src/lib/dns/Makefile
src/lib/dns/tests/Makefile
+ src/lib/dns/tests/testdata/Makefile
src/lib/dns/python/Makefile
src/lib/dns/python/tests/Makefile
src/lib/exceptions/Makefile
@@ -497,6 +544,7 @@
src/bin/msgq/run_msgq.sh
src/bin/auth/auth.spec.pre
src/bin/auth/spec_config.h.pre
+ src/bin/tests/process_rename_test.py
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
@@ -545,7 +593,6 @@
Flags:
DEFS: $DEFS
CPPFLAGS: $CPPFLAGS
- CFLAGS: $CFLAGS
CXXFLAGS: $CXXFLAGS
B10_CXXFLAGS: $B10_CXXFLAGS
dnl includes too
Modified: branches/trac232/doc/guide/bind10-guide.html
==============================================================================
--- branches/trac232/doc/guide/bind10-guide.html (original)
+++ branches/trac232/doc/guide/bind10-guide.html Fri Oct 8 09:51:09 2010
@@ -1,8 +1,8 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230342594"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Guide</title><link rel="stylesheet" href="bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="This is the reference guide for BIND 10. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Guide"><div class="titlepage"><div><div><h1 class="title"><a name="id1168230298903"></a>BIND 10 Guide</h1></div><div><h2 class="subtitle">Administrator Reference for BIND 10</h2></div><div><p class="copyright">Copyright © 2010 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>This is the reference guide for BIND 10.</p><p>
The most up-to-date version of this document, along with other documents
for BIND 10, can be found at
<a class="ulink" href="http://bind10.isc.org/docs" target="_top">http://bind10.isc.org/docs</a>.
- </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230342718">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><s
pan class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230342718">S
upported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230342746">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
+ </p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#installation">2. Installation</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><s
pan class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install Hierarchy</a></span></dt></dl></dd></dl></dd><dt><span class="chapter"><a href="#bind10">3. Starting BIND10 with <span class="command"><strong>bind10</strong></span></a></span></dt><dd><dl><dt><span class="section"><a href="#start">Starting BIND 10</a></span></dt></dl></dd><dt><span class="chapter"><a href="#msgq">4. Command channel</a></span></dt><dt><span class="chapter"><a href="#cfgmgr">5. Configuration manager</a></span></dt><dt><span class="chapter"><a href="#cmdctl">6. Remote control daemon</a></span></dt><dd><dl><dt><span class="section"><a href="#cmdctl.spec">Configuration specifi
cation for b10-cmdctl</a></span></dt></dl></dd><dt><span class="chapter"><a href="#bindctl">7. Control and configure user interface</a></span></dt><dt><span class="chapter"><a href="#authserver">8. Authoritative Server</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></dd><dt><span class="chapter"><a href="#xfrin">9. Incoming Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#xfrout">10. Outbound Zone Transfers</a></span></dt><dt><span class="chapter"><a href="#zonemgr">11. Secondary Manager</a></span></dt></dl></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><div class="toc"><p><b>T
able of Contents</b></p><dl><dt><span class="section"><a href="#id1168230299028">Supported Platforms</a></span></dt><dt><span class="section"><a href="#id1168230299056">Required Software</a></span></dt><dt><span class="section"><a href="#starting_stopping">Starting and Stopping the Server</a></span></dt><dt><span class="section"><a href="#managing_once_running">Managing BIND 10</a></span></dt></dl></div><p>
BIND is the popular implementation of a DNS server, developer
interfaces, and DNS tools.
BIND 10 is a rewrite of BIND 9. BIND 10 is written in C++ and Python
@@ -11,10 +11,10 @@
This guide covers the experimental prototype version of
BIND 10.
</p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
- BIND 10, at this time, does not provide an recursive
+ BIND 10, at this time, does not provide a recursive
DNS server. It does provide a EDNS0- and DNSSEC-capable
authoritative DNS server.
- </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342718"></a>Supported Platforms</h2></div></div></div><p>
+ </p></div><div class="section" title="Supported Platforms"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299028"></a>Supported Platforms</h2></div></div></div><p>
BIND 10 builds have been tested on Debian GNU/Linux 5,
Ubuntu 9.10, NetBSD 5, Solaris 10, FreeBSD 7, and CentOS
Linux 5.3.
@@ -24,16 +24,16 @@
It is planned for BIND 10 to build, install and run on
Windows and standard Unix-type platforms.
- </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230342746"></a>Required Software</h2></div></div></div><p>
+ </p></div><div class="section" title="Required Software"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230299056"></a>Required Software</h2></div></div></div><p>
BIND 10 requires Python 3.1. Later versions may work, but Python
3.1 is the minimum version which will work.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
For this development prototype release, the only supported
data source backend is SQLite3. The authoritative server
requires SQLite 3.3.9 or newer.
- The <span class="command"><strong>b10-xfrin</strong></span> and <span class="command"><strong>b10-xfrout</strong></span>
- modules require the libpython3 library and the Python
- _sqlite3.so module.
+ The <span class="command"><strong>b10-xfrin</strong></span>, <span class="command"><strong>b10-xfrout</strong></span>,
+ and <span class="command"><strong>b10-zonemgr</strong></span> modules require the
+ libpython3 library and the Python _sqlite3.so module.
</p></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
Some operating systems do not provide these dependencies
in their default installation nor standard packages
@@ -83,6 +83,11 @@
This process is used to handle transfer requests to
send a local zone to a remote secondary server,
when acting as a master server.
+ </li><li class="listitem">
+ <span class="command"><strong>b10-zonemgr</strong></span> —
+ Secondary manager.
+ This process keeps track of timers and other
+ necessary information for BIND 10 to act as a slave server.
</li></ul></div><p>
</p><p>
These are ran automatically by <span class="command"><strong>bind10</strong></span>
@@ -116,7 +121,7 @@
and, of course, DNS. These include detailed developer
documentation and code examples.
- </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230328220">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230328406">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230328426">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230328486">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230328584">Build</a></span></dt><dt><span class="section"><a href="#id1168230328599">Install</a></span></dt><dt><span class="section"><a href="#id1168230328622">Install
Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230328220"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ </p></div><div class="chapter" title="Chapter 2. Installation"><div class="titlepage"><div><div><h2 class="title"><a name="installation"></a>Chapter 2. Installation</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230284542">Building Requirements</a></span></dt><dt><span class="section"><a href="#quickstart">Quick start</a></span></dt><dt><span class="section"><a href="#install">Installation from source</a></span></dt><dd><dl><dt><span class="section"><a href="#id1168230284728">Download Tar File</a></span></dt><dt><span class="section"><a href="#id1168230284748">Retrieve from Subversion</a></span></dt><dt><span class="section"><a href="#id1168230284809">Configure before the build</a></span></dt><dt><span class="section"><a href="#id1168230284906">Build</a></span></dt><dt><span class="section"><a href="#id1168230284921">Install</a></span></dt><dt><span class="section"><a href="#id1168230284946">Install
Hierarchy</a></span></dt></dl></dd></dl></div><div class="section" title="Building Requirements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230284542"></a>Building Requirements</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
Some operating systems have split their distribution packages into
a run-time and a development package. You will need to install
the development package versions, which include header files and
@@ -176,14 +181,14 @@
the Subversion code revision control system or as a downloadable
tar file. It may also be available in pre-compiled ready-to-use
packages from operating system vendors.
- </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328406"></a>Download Tar File</h3></div></div></div><p>
+ </p><div class="section" title="Download Tar File"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284728"></a>Download Tar File</h3></div></div></div><p>
Downloading a release tar file is the recommended method to
obtain the source code.
</p><p>
The BIND 10 releases are available as tar file downloads from
<a class="ulink" href="ftp://ftp.isc.org/isc/bind10/" target="_top">ftp://ftp.isc.org/isc/bind10/</a>.
Periodic development snapshots may also be available.
- </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328426"></a>Retrieve from Subversion</h3></div></div></div><p>
+ </p></div><div class="section" title="Retrieve from Subversion"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284748"></a>Retrieve from Subversion</h3></div></div></div><p>
Downloading this "bleeding edge" code is recommended only for
developers or advanced users. Using development code in a production
environment is not recommended.
@@ -215,7 +220,7 @@
<span class="command"><strong>autoheader</strong></span>,
<span class="command"><strong>automake</strong></span>,
and related commands.
- </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328486"></a>Configure before the build</h3></div></div></div><p>
+ </p></div><div class="section" title="Configure before the build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284809"></a>Configure before the build</h3></div></div></div><p>
BIND 10 uses the GNU Build System to discover build environment
details.
To generate the makefiles using the defaults, simply run:
@@ -246,16 +251,16 @@
</p><p>
If the configure fails, it may be due to missing or old
dependencies.
- </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328584"></a>Build</h3></div></div></div><p>
+ </p></div><div class="section" title="Build"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284906"></a>Build</h3></div></div></div><p>
After the configure step is complete, to build the executables
from the C++ code and prepare the Python scripts, run:
</p><pre class="screen">$ <strong class="userinput"><code>make</code></strong></pre><p>
- </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328599"></a>Install</h3></div></div></div><p>
+ </p></div><div class="section" title="Install"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284921"></a>Install</h3></div></div></div><p>
To install the BIND 10 executables, support files,
and documentation, run:
</p><pre class="screen">$ <strong class="userinput"><code>make install</code></strong></pre><p>
- </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230328622"></a>Install Hierarchy</h3></div></div></div><p>
+ </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>The install step may require superuser privileges.</p></div></div><div class="section" title="Install Hierarchy"><div class="titlepage"><div><div><h3 class="title"><a name="id1168230284946"></a>Install Hierarchy</h3></div></div></div><p>
The following is the layout of the complete BIND 10 installation:
</p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<code class="filename">bin/</code> —
@@ -307,8 +312,9 @@
The <span class="command"><strong>bind10</strong></span> master process will also start up
<span class="command"><strong>b10-cmdctl</strong></span> for admins to communicate with the
system, <span class="command"><strong>b10-auth</strong></span> for Authoritative DNS service,
- <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers.
- and <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers.
+ <span class="command"><strong>b10-xfrin</strong></span> for inbound DNS zone transfers,
+ <span class="command"><strong>b10-xfrout</strong></span> for outbound DNS zone transfers,
+ and <span class="command"><strong>b10-zonemgr</strong></span> for secondary service.
</p><div class="section" title="Starting BIND 10"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="start"></a>Starting BIND 10</h2></div></div></div><p>
To start the BIND 10 service, simply run <span class="command"><strong>bind10</strong></span>.
Run it with the <code class="option">--verbose</code> switch to
@@ -467,7 +473,7 @@
the details and relays (over a <span class="command"><strong>b10-msgq</strong></span> command
channel) the configuration on to the specified module.
</p><p>
- </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230329190">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230329255">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230329285">Loading Master Zones Files</a></span></dt></dl></div><p>
+ </p></div><div class="chapter" title="Chapter 8. Authoritative Server"><div class="titlepage"><div><div><h2 class="title"><a name="authserver"></a>Chapter 8. Authoritative Server</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#id1168230285515">Server Configurations</a></span></dt><dt><span class="section"><a href="#id1168230285580">Data Source Backends</a></span></dt><dt><span class="section"><a href="#id1168230285610">Loading Master Zones Files</a></span></dt></dl></div><p>
The <span class="command"><strong>b10-auth</strong></span> is the authoritative DNS server.
It supports EDNS0 and DNSSEC. It supports IPv6.
Normally it is started by the <span class="command"><strong>bind10</strong></span> master
@@ -475,7 +481,7 @@
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
This development prototype release listens on all interfaces
and the non-standard port 5300.
- </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329190"></a>Server Configurations</h2></div></div></div><p>
+ </p></div><div class="section" title="Server Configurations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285515"></a>Server Configurations</h2></div></div></div><p>
<span class="command"><strong>b10-auth</strong></span> is configured via the
<span class="command"><strong>b10-cfgmgr</strong></span> configuration manager.
The module name is <span class="quote">“<span class="quote">Auth</span>”</span>.
@@ -495,7 +501,7 @@
</p><div class="variablelist"><dl><dt><span class="term">shutdown</span></dt><dd>Stop the authoritative DNS server.
</dd></dl></div><p>
- </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329255"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ </p></div><div class="section" title="Data Source Backends"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285580"></a>Data Source Backends</h2></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
For the development prototype release, <span class="command"><strong>b10-auth</strong></span>
only supports the SQLite3 data source backend.
Upcoming versions will be able to use multiple different
@@ -508,7 +514,7 @@
The default is <code class="filename">/usr/local/var/</code>.)
This data file location may be changed by defining the
<span class="quote">“<span class="quote">database_file</span>”</span> configuration.
- </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230329285"></a>Loading Master Zones Files</h2></div></div></div><p>
+ </p></div><div class="section" title="Loading Master Zones Files"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1168230285610"></a>Loading Master Zones Files</h2></div></div></div><p>
RFC 1035 style DNS master zone files may imported
into a BIND 10 data source by using the
<span class="command"><strong>b10-loadzone</strong></span> utility.
@@ -544,12 +550,12 @@
transfer. When received, it is stored in the BIND 10
data store, and its records can be served by
<span class="command"><strong>b10-auth</strong></span>.
- This allows the BIND 10 server to provide
- <span class="quote">“<span class="quote">secondary</span>”</span> service.
+ In combination with <span class="command"><strong>b10-zonemgr</strong></span> (for
+ automated SOA checks), this allows the BIND 10 server to
+ provide <span class="quote">“<span class="quote">secondary</span>”</span> service.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support automated SOA checks.
</p></div><p>
To manually trigger a zone transfer to retrieve a remote zone,
you may use the <span class="command"><strong>bindctl</strong></span> utility.
@@ -564,9 +570,24 @@
sends the zone.
This is used to provide master DNS service to share zones
to secondary name servers.
+ The <span class="command"><strong>b10-xfrout</strong></span> is also used to send
+ NOTIFY messages to slaves.
</p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support NOTIFY.
Access control is not yet provided.
+ </p></div></div><div class="chapter" title="Chapter 11. Secondary Manager"><div class="titlepage"><div><div><h2 class="title"><a name="zonemgr"></a>Chapter 11. Secondary Manager</h2></div></div></div><p>
+ The <span class="command"><strong>b10-zonemgr</strong></span> process is started by
+ <span class="command"><strong>bind10</strong></span>.
+ It keeps track of SOA refresh, retry, and expire timers
+ and other details for BIND 10 to perform as a slave.
+ When the <span class="command"><strong>b10-auth</strong></span> authoritative DNS server
+ receives a NOTIFY message, <span class="command"><strong>b10-zonemgr</strong></span>
+ may tell <span class="command"><strong>b10-xfrin</strong></span> to do a refresh
+ to start an inbound zone transfer.
+ The secondary manager resets its counters when a new zone is
+ transferred in.
+ </p><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
+ Access control (such as allowing notifies) is not yet provided.
+ The primary/secondary service is not yet complete.
</p></div></div></div></body></html>
Modified: branches/trac232/doc/guide/bind10-guide.xml
==============================================================================
--- branches/trac232/doc/guide/bind10-guide.xml (original)
+++ branches/trac232/doc/guide/bind10-guide.xml Fri Oct 8 09:51:09 2010
@@ -42,7 +42,7 @@
<note>
<para>
- BIND 10, at this time, does not provide an recursive
+ BIND 10, at this time, does not provide a recursive
DNS server. It does provide a EDNS0- and DNSSEC-capable
authoritative DNS server.
</para>
@@ -74,9 +74,9 @@
For this development prototype release, the only supported
data source backend is SQLite3. The authoritative server
requires SQLite 3.3.9 or newer.
- The <command>b10-xfrin</command> and <command>b10-xfrout</command>
- modules require the libpython3 library and the Python
- _sqlite3.so module.
+ The <command>b10-xfrin</command>, <command>b10-xfrout</command>,
+ and <command>b10-zonemgr</command> modules require the
+ libpython3 library and the Python _sqlite3.so module.
</para></note>
<!-- TODO: this will change ... -->
@@ -165,6 +165,15 @@
</simpara>
</listitem>
+ <listitem>
+ <simpara>
+ <command>b10-zonemgr</command> —
+ Secondary manager.
+ This process keeps track of timers and other
+ necessary information for BIND 10 to act as a slave server.
+ </simpara>
+ </listitem>
+
</itemizedlist>
</para>
@@ -650,8 +659,9 @@
The <command>bind10</command> master process will also start up
<command>b10-cmdctl</command> for admins to communicate with the
system, <command>b10-auth</command> for Authoritative DNS service,
- <command>b10-xfrin</command> for inbound DNS zone transfers.
- and <command>b10-xfrout</command> for outbound DNS zone transfers.
+ <command>b10-xfrin</command> for inbound DNS zone transfers,
+ <command>b10-xfrout</command> for outbound DNS zone transfers,
+ and <command>b10-zonemgr</command> for secondary service.
</para>
<section id="start">
@@ -1173,14 +1183,14 @@
transfer. When received, it is stored in the BIND 10
data store, and its records can be served by
<command>b10-auth</command>.
- This allows the BIND 10 server to provide
- <quote>secondary</quote> service.
+ In combination with <command>b10-zonemgr</command> (for
+ automated SOA checks), this allows the BIND 10 server to
+ provide <quote>secondary</quote> service.
</para>
<note><simpara>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support automated SOA checks.
</simpara></note>
<para>
@@ -1204,12 +1214,13 @@
sends the zone.
This is used to provide master DNS service to share zones
to secondary name servers.
+ The <command>b10-xfrout</command> is also used to send
+ NOTIFY messages to slaves.
</para>
<note><simpara>
The current development release of BIND 10 only supports
AXFR. (IXFR is not supported.)
- It also does not yet support NOTIFY.
Access control is not yet provided.
</simpara></note>
@@ -1226,6 +1237,31 @@
</chapter>
+ <chapter id="zonemgr">
+ <title>Secondary Manager</title>
+
+ <para>
+ The <command>b10-zonemgr</command> process is started by
+ <command>bind10</command>.
+ It keeps track of SOA refresh, retry, and expire timers
+ and other details for BIND 10 to perform as a slave.
+ When the <command>b10-auth</command> authoritative DNS server
+ receives a NOTIFY message, <command>b10-zonemgr</command>
+ may tell <command>b10-xfrin</command> to do a refresh
+ to start an inbound zone transfer.
+ The secondary manager resets its counters when a new zone is
+ transferred in.
+ </para>
+
+ <note><simpara>
+ Access control (such as allowing notifies) is not yet provided.
+ The primary/secondary service is not yet complete.
+ </simpara></note>
+
+<!-- TODO: lots to describe for zonemgr -->
+
+ </chapter>
+
<!-- TODO: how to help: run unit tests, join lists, review trac tickets -->
<!-- <index> <title>Index</title> </index> -->
Modified: branches/trac232/src/bin/Makefile.am
==============================================================================
--- branches/trac232/src/bin/Makefile.am (original)
+++ branches/trac232/src/bin/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,1 +1,4 @@
-SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout usermgr zonemgr
+SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
+ usermgr zonemgr tests
+
+check-recursive: all-recursive
Modified: branches/trac232/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac232/src/bin/auth/Makefile.am (original)
+++ branches/trac232/src/bin/auth/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = . tests
+SUBDIRS = . tests benchmarks
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
Modified: branches/trac232/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac232/src/bin/auth/asio_link.cc (original)
+++ branches/trac232/src/bin/auth/asio_link.cc Fri Oct 8 09:51:09 2010
@@ -64,24 +64,50 @@
return (asio_address_.to_string());
}
-// Note: this implementation is optimized for the case where this object
-// is created from an ASIO endpoint object in a receiving code path
-// by avoiding to make a copy of the base endpoint. For TCP it may not be
-// a bug deal, but when we receive UDP packets at a high rate, the copy
-// overhead might be significant.
+/// \brief The \c TCPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a TCP connection.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOEndpoint.
+/// This design may be changed when we generalize the wrapper interface.
+///
+/// Note: this implementation is optimized for the case where this object
+/// is created from an ASIO endpoint object in a receiving code path
+/// by avoiding to make a copy of the base endpoint. For TCP it may not be
+/// a big deal, but when we receive UDP packets at a high rate, the copy
+/// overhead might be significant.
class TCPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The TCP port number of the endpoint.
TCPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new tcp::endpoint(ip::address::from_string(address.toText()),
port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO TCP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c tcp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the TCP endpoint.
TCPEndpoint(const tcp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
-
+
+ /// \brief The destructor.
~TCPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
+
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
@@ -90,18 +116,41 @@
const tcp::endpoint& asio_endpoint_;
};
+/// \brief The \c UDPEndpoint class is a concrete derived class of
+/// \c IOEndpoint that represents an endpoint of a UDP packet.
+///
+/// Other notes about \c TCPEndpoint applies to this class, too.
class UDPEndpoint : public IOEndpoint {
public:
+ ///
+ /// \name Constructors and Destructor.
+ ///
+ //@{
+ /// \brief Constructor from a pair of address and port.
+ ///
+ /// \param address The IP address of the endpoint.
+ /// \param port The UDP port number of the endpoint.
UDPEndpoint(const IOAddress& address, const unsigned short port) :
asio_endpoint_placeholder_(
new udp::endpoint(ip::address::from_string(address.toText()),
port)),
asio_endpoint_(*asio_endpoint_placeholder_)
{}
+
+ /// \brief Constructor from an ASIO UDP endpoint.
+ ///
+ /// This constructor is designed to be an efficient wrapper for the
+ /// corresponding ASIO class, \c udp::endpoint.
+ ///
+ /// \param asio_endpoint The ASIO representation of the UDP endpoint.
UDPEndpoint(const udp::endpoint& asio_endpoint) :
asio_endpoint_placeholder_(NULL), asio_endpoint_(asio_endpoint)
{}
+
+ /// \brief The destructor.
~UDPEndpoint() { delete asio_endpoint_placeholder_; }
+ //@}
+
virtual IOAddress getAddress() const {
return (asio_endpoint_.address());
}
@@ -124,37 +173,74 @@
protocol);
}
+/// \brief The \c TCPSocket class is a concrete derived class of
+/// \c IOSocket that represents a TCP socket.
+///
+/// In the current implementation, an object of this class is always
+/// instantiated within the wrapper routines. Applications are expected to
+/// get access to the object via the abstract base class, \c IOSocket.
+/// This design may be changed when we generalize the wrapper interface.
class TCPSocket : public IOSocket {
private:
TCPSocket(const TCPSocket& source);
TCPSocket& operator=(const TCPSocket& source);
public:
+ /// \brief Constructor from an ASIO TCP socket.
+ ///
+ /// \param socket The ASIO representation of the TCP socket.
TCPSocket(tcp::socket& socket) : socket_(socket) {}
+
virtual int getNative() const { return (socket_.native()); }
virtual int getProtocol() const { return (IPPROTO_TCP); }
private:
tcp::socket& socket_;
};
+/// \brief The \c UDPSocket class is a concrete derived class of
+/// \c IOSocket that represents a UDP socket.
+///
+/// Other notes about \c TCPSocket applies to this class, too.
class UDPSocket : public IOSocket {
private:
UDPSocket(const UDPSocket& source);
UDPSocket& operator=(const UDPSocket& source);
public:
+ /// \brief Constructor from an ASIO UDP socket.
+ ///
+ /// \param socket The ASIO representation of the UDP socket.
UDPSocket(udp::socket& socket) : socket_(socket) {}
+
virtual int getNative() const { return (socket_.native()); }
virtual int getProtocol() const { return (IPPROTO_UDP); }
private:
udp::socket& socket_;
};
+/// \brief The \c DummySocket class is a concrete derived class of
+/// \c IOSocket that is not associated with any real socket.
+///
+/// This main purpose of this class is tests, where it may be desirable to
+/// instantiate an \c IOSocket object without involving system resource
+/// allocation such as real network sockets.
class DummySocket : public IOSocket {
private:
DummySocket(const DummySocket& source);
DummySocket& operator=(const DummySocket& source);
public:
+ /// \brief Constructor from the protocol number.
+ ///
+ /// The protocol must validly identify a standard network protocol.
+ /// For example, to specify TCP \c protocol must be \c IPPROTO_TCP.
+ ///
+ /// \param protocol The network protocol number for the socket.
DummySocket(const int protocol) : protocol_(protocol) {}
+
+ /// \brief A dummy derived method of \c IOSocket::getNative().
+ ///
+ /// This version of method always returns -1 as the object is not
+ /// associated with a real (native) socket.
virtual int getNative() const { return (-1); }
+
virtual int getProtocol() const { return (protocol_); }
private:
const int protocol_;
@@ -197,8 +283,8 @@
void start() {
// Check for queued configuration commands
if (auth_server_ != NULL &&
- auth_server_->configSession()->hasQueuedMsgs()) {
- auth_server_->configSession()->checkCommand();
+ auth_server_->getConfigSession()->hasQueuedMsgs()) {
+ auth_server_->getConfigSession()->checkCommand();
}
async_read(socket_, asio::buffer(data_, TCP_MESSAGE_LENGTHSIZE),
boost::bind(&TCPClient::headerRead, this,
@@ -385,8 +471,8 @@
{
// Check for queued configuration commands
if (auth_server_ != NULL &&
- auth_server_->configSession()->hasQueuedMsgs()) {
- auth_server_->configSession()->checkCommand();
+ auth_server_->getConfigSession()->hasQueuedMsgs()) {
+ auth_server_->getConfigSession()->checkCommand();
}
if (!error && bytes_recvd > 0) {
const UDPEndpoint remote_endpoint(sender_endpoint_);
Modified: branches/trac232/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac232/src/bin/auth/auth_srv.cc (original)
+++ branches/trac232/src/bin/auth/auth_srv.cc Fri Oct 8 09:51:09 2010
@@ -24,10 +24,13 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrset.h>
#include <dns/rrsetlist.h>
#include <dns/rrttl.h>
@@ -169,7 +172,6 @@
message.setQid(qid);
message.setOpcode(opcode);
message.setHeaderFlag(MessageFlag::QR());
- message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
if (rd) {
message.setHeaderFlag(MessageFlag::RD());
}
@@ -198,6 +200,16 @@
}
void
+AuthSrv::setCacheSlots(const size_t slots) {
+ impl_->cache_.setSlots(slots);
+}
+
+size_t
+AuthSrv::getCacheSlots() const {
+ return (impl_->cache_.getSlots());
+}
+
+void
AuthSrv::setXfrinSession(AbstractSession* xfrin_session) {
impl_->xfrin_session_ = xfrin_session;
}
@@ -208,7 +220,7 @@
}
ModuleCCSession*
-AuthSrv::configSession() const {
+AuthSrv::getConfigSession() const {
return (impl_->config_session_);
}
@@ -297,14 +309,21 @@
AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
MessageRenderer& response_renderer)
{
- const bool dnssec_ok = message.isDNSSECSupported();
- const uint16_t remote_bufsize = message.getUDPSize();
+ ConstEDNSPtr remote_edns = message.getEDNS();
+ const bool dnssec_ok = remote_edns && remote_edns->getDNSSECAwareness();
+ const uint16_t remote_bufsize = remote_edns ? remote_edns->getUDPSize() :
+ Message::DEFAULT_MAX_UDPSIZE;
message.makeResponse();
message.setHeaderFlag(MessageFlag::AA());
message.setRcode(Rcode::NOERROR());
- message.setDNSSECSupported(dnssec_ok);
- message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+
+ if (remote_edns) {
+ EDNSPtr local_edns = EDNSPtr(new EDNS());
+ local_edns->setDNSSECAwareness(dnssec_ok);
+ local_edns->setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
+ message.setEDNS(local_edns);
+ }
try {
Query query(message, cache_, dnssec_ok);
Modified: branches/trac232/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac232/src/bin/auth/auth_srv.h (original)
+++ branches/trac232/src/bin/auth/auth_srv.h Fri Oct 8 09:51:09 2010
@@ -38,8 +38,30 @@
class IOMessage;
}
+/// \brief The implementation class for the \c AuthSrv class using the pimpl
+/// idiom.
class AuthSrvImpl;
+/// \brief The authoritative nameserver class.
+///
+/// \c AuthSrv is a concrete class that implements authoritative DNS server
+/// protocol processing.
+/// An \c AuthSrv object is primarily responsible for handling incoming DNS
+/// requests: It parses the request and dispatches subsequent processing to
+/// the corresponding module (which may be an internal library or a separate
+/// process) depending on the request type. For normal queries, the
+/// \c AuthSrv object searches configured data sources for the answer to the
+/// query, and builds a response containing the answer.
+///
+/// This class uses the "pimpl" idiom, and hides detailed implementation
+/// through the \c impl_ pointer (which points to an instance of the
+/// \c AuthSrvImpl class). An \c AuthSrv object is supposed to exist for quite
+/// a long period, and only a few \c AuthSrv objects will be created (in fact,
+/// in this current implementation there will only be one object), so the
+/// construction overhead of this approach should be acceptable.
+///
+/// The design of this class is still in flux. It's quite likely to change
+/// in future versions.
class AuthSrv {
///
/// \name Constructors, Assignment Operator and Destructor.
@@ -67,12 +89,101 @@
bool processMessage(const asio_link::IOMessage& io_message,
isc::dns::Message& message,
isc::dns::MessageRenderer& response_renderer);
- void setVerbose(bool on);
+
+ /// \brief Enable or disable verbose logging.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param on \c true to enable verbose logging; \c false to disable
+ /// verbose logging.
+ void setVerbose(const bool on);
+
+ /// \brief Returns the logging verbosity of the \c AuthSrv object.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return \c true if verbose logging is enabled; otherwise \c false.
bool getVerbose() const;
+
+ /// \brief Updates the data source for the \c AuthSrv object.
+ ///
+ /// This method installs or replaces the data source that the \c AuthSrv
+ /// object refers to for query processing.
+ /// Although the method name is generic, the only thing it does is to
+ /// update the data source information.
+ /// If there is a data source installed, it will be replaced with the
+ /// new one.
+ ///
+ /// In the current implementation, the SQLite data source is assumed.
+ /// The \c config parameter will simply be passed to the initialization
+ /// routine of the \c Sqlite3DataSrc class.
+ ///
+ /// On success this method returns a data \c Element (in the form of a
+ /// pointer like object) indicating the successful result,
+ /// i.e., {"result": [0]}.
+ /// Otherwise, it returns a data \c Element explaining the error:
+ /// {"result": [1, <error-description>]}.
+ ///
+ /// This method is mostly exception free (error conditions are represented
+ /// via the return value). But it may still throw a standard exception
+ /// if memory allocation fails inside the method.
+ /// When a standard exception is thrown or an implementation specific
+ /// exception is triggered and caught internally, this function provides
+ /// the strong exception guarantee: Unless everything succeeds, currently
+ /// installed data source (if any) won't be replaced.
+ ///
+ /// \param config An immutable pointer-like object to a data \c Element,
+ /// possibly containing the data source information to be used.
+ /// \return An immutable pointer-like object to a data \c Element
+ /// containing the result of the update operation.
isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr config);
- isc::config::ModuleCCSession* configSession() const;
+
+ /// \param Returns the command and configuration session for the
+ /// \c AuthSrv.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return A pointer to \c ModuleCCSession object stored in the
+ /// \c AuthSrv object. In this implementation it could be NULL.
+ isc::config::ModuleCCSession* getConfigSession() const;
+
+ /// \brief Set the command and configuration session for the \c AuthSrv.
+ ///
+ /// Note: this interface is tentative. We'll revisit the ASIO and session
+ /// frameworks, at which point the session will probably be passed on
+ /// construction of the server.
+ /// In the current implementation, this method is expected to be called
+ /// exactly once as part of initialization. If this method is called
+ /// multiple times, previously specified session is silently overridden.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param config_session A pointer to \c ModuleCCSession object to receive
+ /// control commands and configuration updates.
void setConfigSession(isc::config::ModuleCCSession* config_session);
+ /// \brief Set or update the size (number of slots) of hot spot cache.
+ ///
+ /// If the specified size is 0, it means the size will be unlimited.
+ /// The specified size is recorded even if the cache is disabled; the
+ /// new size will be effective when the cache is enabled.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \param slots The number of cache slots.
+ void setCacheSlots(const size_t slots);
+
+ /// \brief Get the current size (number of slots) of hot spot cache.
+ ///
+ /// It always returns the recorded size regardless of the cache is enabled.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return The current number of cache slots.
+ size_t getCacheSlots() const;
+
+ /// \brief Set the communication session with a separate process for
+ /// outgoing zone transfers.
///
/// Note: this interface is tentative. We'll revisit the ASIO and session
/// frameworks, at which point the session will probably be passed on
@@ -85,6 +196,7 @@
/// Ownership isn't transferred: the caller is responsible for keeping
/// this object to be valid while the server object is working and for
/// disconnecting the session and destroying the object when the server
+ /// is shutdown.
///
void setXfrinSession(isc::cc::AbstractSession* xfrin_session);
// temporarily added for manual testing of writable data sources
Modified: branches/trac232/src/bin/auth/b10-auth.8
==============================================================================
--- branches/trac232/src/bin/auth/b10-auth.8 (original)
+++ branches/trac232/src/bin/auth/b10-auth.8 Fri Oct 8 09:51:09 2010
@@ -137,6 +137,7 @@
\fBb10-cmdctl\fR(8),
\fBb10-loadzone\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
Modified: branches/trac232/src/bin/auth/b10-auth.xml
==============================================================================
--- branches/trac232/src/bin/auth/b10-auth.xml (original)
+++ branches/trac232/src/bin/auth/b10-auth.xml Fri Oct 8 09:51:09 2010
@@ -201,6 +201,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
Modified: branches/trac232/src/bin/auth/tests/Makefile.am
==============================================================================
--- branches/trac232/src/bin/auth/tests/Makefile.am (original)
+++ branches/trac232/src/bin/auth/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,7 +1,10 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(top_builddir)/src/bin/auth/tests/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -36,25 +39,3 @@
endif
noinst_PROGRAMS = $(TESTS)
-
-EXTRA_DIST = testdata/badExampleQuery_fromWire
-EXTRA_DIST += testdata/badExampleQuery_fromWire.spec
-EXTRA_DIST += testdata/example.com
-EXTRA_DIST += testdata/examplequery_fromWire
-EXTRA_DIST += testdata/examplequery_fromWire.spec
-EXTRA_DIST += testdata/example.sqlite3
-EXTRA_DIST += testdata/iqueryresponse_fromWire
-EXTRA_DIST += testdata/iqueryresponse_fromWire.spec
-EXTRA_DIST += testdata/multiquestion_fromWire
-EXTRA_DIST += testdata/multiquestion_fromWire.spec
-EXTRA_DIST += testdata/queryBadEDNS_fromWire
-EXTRA_DIST += testdata/queryBadEDNS_fromWire.spec
-EXTRA_DIST += testdata/shortanswer_fromWire
-EXTRA_DIST += testdata/shortanswer_fromWire.spec
-EXTRA_DIST += testdata/shortmessage_fromWire
-EXTRA_DIST += testdata/shortquestion_fromWire
-EXTRA_DIST += testdata/shortresponse_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire
-EXTRA_DIST += testdata/simplequery_fromWire.spec
-EXTRA_DIST += testdata/simpleresponse_fromWire
-EXTRA_DIST += testdata/simpleresponse_fromWire.spec
Modified: branches/trac232/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac232/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac232/src/bin/auth/tests/auth_srv_unittest.cc Fri Oct 8 09:51:09 2010
@@ -22,6 +22,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
@@ -114,7 +116,7 @@
AuthSrvTest() : server(true, xfrout),
request_message(Message::RENDER),
parse_message(Message::PARSE), default_qid(0x1035),
- opcode(Opcode(Opcode::QUERY())), qname("www.example.com"),
+ opcode(Opcode::QUERY()), qname("www.example.com"),
qclass(RRClass::IN()), qtype(RRType::A()),
io_message(NULL), endpoint(NULL), request_obuffer(0),
request_renderer(request_obuffer),
@@ -280,6 +282,7 @@
{
request_message.clear(Message::RENDER);
request_message.setOpcode(opcode);
+ request_message.setRcode(Rcode::NOERROR());
request_message.setQid(default_qid);
request_message.addQuestion(Question(request_name, rrclass, rrtype));
}
@@ -341,7 +344,7 @@
i == Opcode::NOTIFY().getCode()) {
continue;
}
- createDataFromFile("simplequery_fromWire");
+ createDataFromFile("simplequery_fromWire.wire");
data[2] = ((i << 3) & 0xff);
parse_message.clear(Message::PARSE);
@@ -363,7 +366,7 @@
// Multiple questions. Should result in FORMERR.
TEST_F(AuthSrvTest, multiQuestion) {
- createDataFromFile("multiquestion_fromWire");
+ createDataFromFile("multiquestion_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -393,7 +396,7 @@
// or malformed or could otherwise cause a protocol error.
TEST_F(AuthSrvTest, response) {
// A valid (although unusual) response
- createDataFromFile("simpleresponse_fromWire");
+ createDataFromFile("simpleresponse_fromWire.wire");
EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
response_renderer));
@@ -404,7 +407,7 @@
response_renderer));
// A response to iquery. must be dropped rather than returning NOTIMP.
- createDataFromFile("iqueryresponse_fromWire");
+ createDataFromFile("iqueryresponse_fromWire.wire");
EXPECT_EQ(false, server.processMessage(*io_message, parse_message,
response_renderer));
}
@@ -422,7 +425,7 @@
// Query with a broken answer section
TEST_F(AuthSrvTest, shortAnswer) {
- createDataFromFile("shortanswer_fromWire");
+ createDataFromFile("shortanswer_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
@@ -441,17 +444,24 @@
// Query with unsupported version of EDNS.
TEST_F(AuthSrvTest, ednsBadVers) {
- createDataFromFile("queryBadEDNS_fromWire");
- EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
- response_renderer));
-
- // The response must have an EDNS OPT RR in the additional section.
+ createDataFromFile("queryBadEDNS_fromWire.wire");
+ EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
+ response_renderer));
+
+ // The response must have an EDNS OPT RR in the additional section, but
+ // it will be added automatically at the render time.
// Note that the DNSSEC DO bit is cleared even if this bit in the query
// is set. This is a limitation of the current implementation.
headerCheck(parse_message, default_qid, Rcode::BADVERS(), opcode.getCode(),
QR_FLAG, 1, 0, 0, 1);
- EXPECT_EQ(4096, parse_message.getUDPSize());
- EXPECT_FALSE(parse_message.isDNSSECSupported());
+ EXPECT_FALSE(parse_message.getEDNS()); // EDNS isn't added at this point
+
+ parse_message.clear(Message::PARSE);
+ InputBuffer ib(response_renderer.getData(), response_renderer.getLength());
+ parse_message.fromWire(ib);
+ EXPECT_EQ(Rcode::BADVERS(), parse_message.getRcode());
+ EXPECT_TRUE(parse_message.getEDNS());
+ EXPECT_FALSE(parse_message.getEDNS()->getDNSSECAwareness());
}
TEST_F(AuthSrvTest, AXFROverUDP) {
@@ -577,6 +587,7 @@
TEST_F(AuthSrvTest, notifyEmptyQuestion) {
request_message.clear(Message::RENDER);
request_message.setOpcode(Opcode::NOTIFY());
+ request_message.setRcode(Rcode::NOERROR());
request_message.setHeaderFlag(MessageFlag::AA());
request_message.setQid(default_qid);
request_message.toWire(request_renderer);
@@ -715,7 +726,7 @@
// query for existent data in the installed data source. The resulting
// response should have the AA flag on, and have an RR in each answer
// and authority section.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
@@ -729,7 +740,7 @@
// tool and the data source itself naively accept it). This will result
// in a SERVFAIL response, and the answer and authority sections should
// be empty.
- createDataFromFile("badExampleQuery_fromWire");
+ createDataFromFile("badExampleQuery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::SERVFAIL(),
@@ -744,10 +755,20 @@
updateConfig(&server, BADCONFIG_TESTDB, false);
// The original data source should still exist.
- createDataFromFile("examplequery_fromWire");
+ createDataFromFile("examplequery_fromWire.wire");
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
QR_FLAG | AA_FLAG, 1, 1, 1, 0);
}
-}
+
+TEST_F(AuthSrvTest, cacheSlots) {
+ // simple check for the get/set operations
+ server.setCacheSlots(10); // 10 = arbitrary choice
+ EXPECT_EQ(10, server.getCacheSlots());
+
+ // 0 is a valid size
+ server.setCacheSlots(0);
+ EXPECT_EQ(00, server.getCacheSlots());
+}
+}
Modified: branches/trac232/src/bin/auth/tests/run_unittests.cc
==============================================================================
--- branches/trac232/src/bin/auth/tests/run_unittests.cc (original)
+++ branches/trac232/src/bin/auth/tests/run_unittests.cc Fri Oct 8 09:51:09 2010
@@ -23,6 +23,7 @@
{
::testing::InitGoogleTest(&argc, argv);
isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac232/src/bin/bind10/Makefile.am
==============================================================================
--- branches/trac232/src/bin/bind10/Makefile.am (original)
+++ branches/trac232/src/bin/bind10/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
sbin_SCRIPTS = bind10
CLEANFILES = bind10 bind10.pyc
Modified: branches/trac232/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac232/src/bin/bind10/bind10.8 (original)
+++ branches/trac232/src/bin/bind10/bind10.8 Fri Oct 8 09:51:09 2010
@@ -1,13 +1,22 @@
'\" t
.\" Title: bind10
.\" Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
+.\" Generator: DocBook XSL Stylesheets v1.76.0 <http://docbook.sf.net/>
.\" Date: July 29, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
.TH "BIND10" "8" "July 29, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -22,7 +31,7 @@
bind10 \- BIND 10 boss process
.SH "SYNOPSIS"
.HP \w'\fBbind10\fR\ 'u
-\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-verbose\fR]
+\fBbind10\fR [\fB\-a\ \fR\fB\fIaddress\fR\fR] [\fB\-m\ \fR\fB\fIfile\fR\fR] [\fB\-n\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-u\ \fR\fB\fIuser\fR\fR] [\fB\-v\fR] [\fB\-\-address\ \fR\fB\fIaddress\fR\fR] [\fB\-\-msgq\-socket\-file\ \fR\fB\fIfile\fR\fR] [\fB\-\-no\-cache\fR] [\fB\-\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-user\ \fR\fB\fIuser\fR\fR] [\fB\-\-pretty\-name\ \fR\fB\fIname\fR\fR] [\fB\-\-verbose\fR]
.SH "DESCRIPTION"
.PP
The
@@ -86,6 +95,15 @@
must be initially ran as the root user to use this option\&. The default is to run as the current user\&.
.RE
.PP
+\fB\-\-pretty\-name \fR\fB\fIname\fR\fR
+.RS 4
+The name this process should have in tools like
+\fBps\fR
+or
+\fBtop\fR\&. This is handy if you have multiple versions/installations of
+\fBbind10\fR\&.
+.RE
+.PP
\fB\-v\fR, \fB\-\-verbose\fR
.RS 4
Display more about what is going on for
@@ -101,6 +119,8 @@
\fBb10-cmdctl\fR(8),
\fBb10-msgq\fR(8),
\fBb10-xfrin\fR(8),
+\fBb10-xfrout\fR(8),
+\fBb10-zonemgr\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
.PP
Modified: branches/trac232/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac232/src/bin/bind10/bind10.py.in (original)
+++ branches/trac232/src/bin/bind10/bind10.py.in Fri Oct 8 09:51:09 2010
@@ -63,9 +63,15 @@
import posix
import isc.cc
+import isc.utils.process
+
+# Assign this process some longer name
+isc.utils.process.rename(sys.argv[0])
# This is the version that gets displayed to the user.
-__version__ = "v20100531"
+# The VERSION string consists of the module name, the module version
+# number, and the overall BIND 10 version number (set in configure.ac).
+VERSION = "bind10 20100916 (BIND 10 @PACKAGE_VERSION@)"
class RestartSchedule:
"""
@@ -618,7 +624,11 @@
parser.values.address = value
else:
raise OptionValueError("Unknown option " + opt_str)
-
+
+def process_rename(option, opt_str, value, parser):
+ """Function that renames the process if it is requested by a option."""
+ isc.utils.process.rename(value)
+
def main():
global options
global boss_of_bind
@@ -627,7 +637,7 @@
# Parse any command-line options.
- parser = OptionParser(version=__version__)
+ parser = OptionParser(version=VERSION)
parser.add_option("-a", "--address", dest="address", type="string",
action="callback", callback=check_addr, default='',
help="address the b10-auth daemon will use (default: listen on all addresses)")
@@ -644,6 +654,9 @@
help="Change user after startup (must run as root)")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
help="display more about what is going on")
+ parser.add_option("--pretty-name", type="string", action="callback",
+ callback=process_rename,
+ help="Set the process name (displayed in ps, top, ...)")
(options, args) = parser.parse_args()
if args:
parser.print_help()
@@ -680,7 +693,7 @@
# Announce startup.
if options.verbose:
- sys.stdout.write("BIND 10 %s\n" % __version__)
+ sys.stdout.write("%s\n" % VERSION)
# TODO: set process name, perhaps by:
# http://code.google.com/p/procname/
@@ -735,7 +748,12 @@
for fd in rlist + xlist:
if fd == ccs_fd:
- boss_of_bind.ccs.check_command()
+ try:
+ boss_of_bind.ccs.check_command()
+ except isc.cc.session.ProtocolError:
+ if options.verbose:
+ sys.stderr.write("[bind10] msgq channel disappeared.\n")
+ break
elif fd == wakeup_fd:
os.read(wakeup_fd, 32)
Modified: branches/trac232/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac232/src/bin/bind10/bind10.xml (original)
+++ branches/trac232/src/bin/bind10/bind10.xml Fri Oct 8 09:51:09 2010
@@ -56,6 +56,7 @@
<arg><option>--no-cache</option></arg>
<arg><option>--port <replaceable>number</replaceable></option></arg>
<arg><option>--user <replaceable>user</replaceable></option></arg>
+ <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
<arg><option>--verbose</option></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -149,6 +150,17 @@
</varlistentry>
<varlistentry>
+ <term><option>--pretty-name <replaceable>name</replaceable></option></term>
+
+ <listitem>
+ <para>The name this process should have in tools like
+ <command>ps</command> or <command>top</command>. This
+ is handy if you have multiple versions/installations
+ of <command>bind10</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>-v</option>, <option>--verbose</option></term>
<listitem>
<para>Display more about what is going on for
@@ -188,6 +200,12 @@
</citerefentry>,
<citerefentry>
<refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>b10-xfrout</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
</para>
Modified: branches/trac232/src/bin/bind10/tests/args_test.py
==============================================================================
--- branches/trac232/src/bin/bind10/tests/args_test.py (original)
+++ branches/trac232/src/bin/bind10/tests/args_test.py Fri Oct 8 09:51:09 2010
@@ -130,5 +130,28 @@
x = bob.wait()
self.assertTrue(bob.wait() == 0)
+ def testPrettyName(self):
+ """Try the --pretty-name option."""
+ CMD_PRETTY_NAME = b'bob-name-test'
+ bob = subprocess.Popen(args=(BIND10_EXE, '--pretty-name',
+ CMD_PRETTY_NAME), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ started_ok = self._waitForString(bob, '[bind10] BIND 10 started')
+ self.assertTrue(started_ok)
+ ps = subprocess.Popen(args=("ps", "axo", "pid,comm"),
+ stdout=subprocess.PIPE)
+ s = ps.stdout.readline()
+ command = None
+ while True:
+ s = ps.stdout.readline()
+ if s == '': break
+ (pid,comm) = s.split(None, 1)
+ if int(pid) == bob.pid:
+ command = comm
+ break
+ self.assertEqual(command, CMD_PRETTY_NAME + b'\n')
+ time.sleep(0.1)
+ bob.terminate()
+ bob.wait()
+
if __name__ == '__main__':
unittest.main()
Modified: branches/trac232/src/bin/bindctl/Makefile.am
==============================================================================
--- branches/trac232/src/bin/bindctl/Makefile.am (original)
+++ branches/trac232/src/bin/bindctl/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
bin_SCRIPTS = bindctl
man_MANS = bindctl.1
Modified: branches/trac232/src/bin/bindctl/bindctl-source.py.in
==============================================================================
--- branches/trac232/src/bin/bindctl/bindctl-source.py.in (original)
+++ branches/trac232/src/bin/bindctl/bindctl-source.py.in Fri Oct 8 09:51:09 2010
@@ -24,6 +24,9 @@
from bindctl.bindcmd import *
import pprint
from optparse import OptionParser, OptionValueError
+import isc.utils.process
+
+isc.utils.process.rename()
__version__ = 'Bindctl'
Modified: branches/trac232/src/bin/cfgmgr/Makefile.am
==============================================================================
--- branches/trac232/src/bin/cfgmgr/Makefile.am (original)
+++ branches/trac232/src/bin/cfgmgr/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac232/src/bin/cfgmgr/b10-cfgmgr.py.in
==============================================================================
--- branches/trac232/src/bin/cfgmgr/b10-cfgmgr.py.in (original)
+++ branches/trac232/src/bin/cfgmgr/b10-cfgmgr.py.in Fri Oct 8 09:51:09 2010
@@ -21,8 +21,11 @@
from isc.config.cfgmgr import ConfigManager, ConfigManagerDataReadError
from isc.cc import SessionError
+import isc.utils.process
import signal
import os
+
+isc.utils.process.rename()
# If B10_FROM_SOURCE is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
Modified: branches/trac232/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac232/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac232/src/bin/cmdctl/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac232/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac232/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac232/src/bin/cmdctl/cmdctl.py.in Fri Oct 8 09:51:09 2010
@@ -42,12 +42,15 @@
import time
import signal
from isc.config import ccsession
+import isc.utils.process
from optparse import OptionParser, OptionValueError
from hashlib import sha1
try:
import threading
except ImportError:
import dummy_threading as threading
+
+isc.utils.process.rename()
__version__ = 'BIND10'
URL_PATTERN = re.compile('/([\w]+)(?:/([\w]+))?/?')
@@ -380,6 +383,7 @@
def send_command(self, module_name, command_name, params = None):
'''Send the command from bindctl to proper module. '''
errstr = 'unknown error'
+ answer = None
if self._verbose:
self.log_info("Begin send command '%s' to module '%s'" %(command_name, module_name))
@@ -390,7 +394,10 @@
msg = ccsession.create_command(command_name, params)
seq = self._cc.group_sendmsg(msg, module_name)
#TODO, it may be blocked, msqg need to add a new interface waiting in timeout.
- answer, env = self._cc.group_recvmsg(False, seq)
+ try:
+ answer, env = self._cc.group_recvmsg(False, seq)
+ except isc.cc.session.SessionTimeout:
+ errstr = "Module '%s' not responding" % module_name
if self._verbose:
self.log_info("Finish send command '%s' to module '%s'" % (command_name, module_name))
@@ -410,7 +417,6 @@
except ccsession.ModuleCCSessionError as mcse:
errstr = str("Error in ccsession answer:") + str(mcse)
self.log_info(errstr)
-
return 1, {'error': errstr}
def log_info(self, msg):
@@ -602,6 +608,9 @@
except isc.cc.SessionError as err:
sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
"is the command channel daemon running?\n")
+ except isc.cc.SessionTimeout:
+ sys.stderr.write("[b10-cmdctl] Error creating b10-cmdctl, "
+ "is the configuration manager running?\n")
except KeyboardInterrupt:
sys.stderr.write("[b10-cmdctl] exit from Cmdctl\n")
except CmdctlException as err:
Modified: branches/trac232/src/bin/host/host.cc
==============================================================================
--- branches/trac232/src/bin/host/host.cc (original)
+++ branches/trac232/src/bin/host/host.cc Fri Oct 8 09:51:09 2010
@@ -28,6 +28,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rrset.h>
Modified: branches/trac232/src/bin/loadzone/Makefile.am
==============================================================================
--- branches/trac232/src/bin/loadzone/Makefile.am (original)
+++ branches/trac232/src/bin/loadzone/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,5 +1,4 @@
-SUBDIRS = tests/correct
-SUBDIRS += tests/error
+SUBDIRS = . tests/correct tests/error
bin_SCRIPTS = b10-loadzone
CLEANFILES = b10-loadzone
Modified: branches/trac232/src/bin/loadzone/b10-loadzone.py.in
==============================================================================
--- branches/trac232/src/bin/loadzone/b10-loadzone.py.in (original)
+++ branches/trac232/src/bin/loadzone/b10-loadzone.py.in Fri Oct 8 09:51:09 2010
@@ -18,9 +18,13 @@
import sys; sys.path.append ('@@PYTHONPATH@@')
import re, getopt
import isc.datasrc
+import isc.utils.process
from isc.datasrc.master import MasterFile
import time
import os
+
+isc.utils.process.rename()
+
#########################################################################
# usage: print usage note and exit
#########################################################################
Modified: branches/trac232/src/bin/msgq/Makefile.am
==============================================================================
--- branches/trac232/src/bin/msgq/Makefile.am (original)
+++ branches/trac232/src/bin/msgq/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac232/src/bin/msgq/msgq.py.in
==============================================================================
--- branches/trac232/src/bin/msgq/msgq.py.in (original)
+++ branches/trac232/src/bin/msgq/msgq.py.in Fri Oct 8 09:51:09 2010
@@ -31,8 +31,11 @@
import pprint
import random
from optparse import OptionParser, OptionValueError
+import isc.utils.process
import isc.cc
+
+isc.utils.process.rename()
# This is the version that gets displayed to the user.
__version__ = "v20091030 (Paving the DNS Parking Lot)"
@@ -139,6 +142,10 @@
def setup_listener(self):
"""Set up the listener socket. Internal function."""
+ if self.verbose:
+ sys.stdout.write("[b10-msgq] Setting up socket at %s\n" %
+ self.socket_file)
+
self.listen_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
if os.path.exists(self.socket_file):
Modified: branches/trac232/src/bin/usermgr/b10-cmdctl-usermgr.py.in
==============================================================================
--- branches/trac232/src/bin/usermgr/b10-cmdctl-usermgr.py.in (original)
+++ branches/trac232/src/bin/usermgr/b10-cmdctl-usermgr.py.in Fri Oct 8 09:51:09 2010
@@ -25,6 +25,9 @@
import getpass
import getopt
import sys
+import isc.utils.process
+
+isc.utils.process.rename()
VERSION_NUMBER = 'bind10'
DEFAULT_FILE = 'cmdctl-accounts.csv'
Modified: branches/trac232/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac232/src/bin/xfrin/Makefile.am (original)
+++ branches/trac232/src/bin/xfrin/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac232/src/bin/xfrin/TODO
==============================================================================
--- branches/trac232/src/bin/xfrin/TODO (original)
+++ branches/trac232/src/bin/xfrin/TODO Fri Oct 8 09:51:09 2010
@@ -63,3 +63,8 @@
which a shutdown notification would be sent to the child. With
this approach each thread needs to watch at least two channels,
and then it would need some asynchronous communication mechanism.
+17. Do zone transfer from notifyfrom address first, if it's one master of the zone.
+18. Check soa serial first when doing zone refreshment.
+19. Add configuration items to seperate zone, including ACL, multiple masters, etc.
+20. Be able to cancel the ongoing zone transfer, and be able to disable zone transfer.
+
Modified: branches/trac232/src/bin/xfrin/b10-xfrin.8
==============================================================================
--- branches/trac232/src/bin/xfrin/b10-xfrin.8 (original)
+++ branches/trac232/src/bin/xfrin/b10-xfrin.8 Fri Oct 8 09:51:09 2010
@@ -2,12 +2,12 @@
.\" Title: b10-xfrin
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: March 17, 2010
+.\" Date: September 8, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-XFRIN" "8" "March 17, 2010" "BIND10" "BIND10"
+.TH "B10\-XFRIN" "8" "September 8, 2010" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -47,7 +47,6 @@
.sp .5v
.RE
.PP
-
This daemon communicates with BIND 10 over a
\fBb10-msgq\fR(8)
C\-Channel connection\&. If this connection is not established,
@@ -60,24 +59,59 @@
\fBb10-cfgmgr\fR(8)\&.
.SH "CONFIGURATION AND COMMANDS"
.PP
-The configurable setting is
+The configurable settings are:
+.PP
+\fImaster_addr\fR
+The default is 127\&.0\&.0\&.1\&.
+.PP
+\fImaster_port\fR
+The default is 53\&.
+.PP
\fItransfers\-in\fR
-which defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
+defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
.PP
The configuration commands are:
+.PP
+
+\fBnotify\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+when a DNS NOTIFY message is received to initiate a zone transfer\&.
+This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBrefresh\fR
+triggers the transfer in for a single zone\&. It is the same as
+\fBretransfer\fR
+except it checks the SOA serial first\&.
+This is an internal command and not exposed to the administrator\&.
+
+.PP
+
+\fBrefresh_from_zonemgr\fR
+is sent by
+\fBb10-zonemgr\fR(8)
+according to the SOA\'s REFRESH time to tell
+\fBb10\-xfrin\fR
+that the zone needs to do a zone refresh\&. This is an internal command and not exposed to the administrator\&.
+.PP
+
+\fBretransfer\fR
+triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
+\fIzone_name\fR
+to define the zone to request,
+\fIzone_class\fR
+to define the class (defaults to
+\(lqIN\(rq),
+\fImaster\fR
+to define the IP address of the authoritative server to transfer from, and
+\fIport\fR
+to define the port number on the authoritative server (defaults to 53)\&.
.PP
\fBshutdown\fR
stops all incoming zone transfers and exits
\fBb10\-xfrin\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
-.PP
-
-\fBretransfer\fR
-triggers the transfer in for a single zone without checking the zone\'s serial number\&. It has the following arguments:
-\fIzone_name\fR
-to define the zone to request and
-\fImaster\fR
-to define the IP address of the authoritative server to transfer from\&.
.if n \{\
.sp
.\}
@@ -99,6 +133,7 @@
\fBb10-cfgmgr\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-zonemgr\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
Modified: branches/trac232/src/bin/xfrin/b10-xfrin.xml
==============================================================================
--- branches/trac232/src/bin/xfrin/b10-xfrin.xml (original)
+++ branches/trac232/src/bin/xfrin/b10-xfrin.xml Fri Oct 8 09:51:09 2010
@@ -21,7 +21,7 @@
<refentry>
<refentryinfo>
- <date>March 17, 2010</date>
+ <date>September 8, 2010</date>
</refentryinfo>
<refmeta>
@@ -68,7 +68,6 @@
</simpara></note>
<para>
-<!-- TODO: does it really use msgq? what for? -->
This daemon communicates with BIND 10 over a
<citerefentry><refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
C-Channel connection. If this connection is not established,
@@ -85,39 +84,82 @@
<refsect1>
<title>CONFIGURATION AND COMMANDS</title>
<para>
- The configurable setting is <varname>transfers-in</varname>
- which defines the maximum number of inbound zone transfers
+ The configurable settings are:
+ </para>
+
+ <para><varname>master_addr</varname>
+<!-- TODO: how can there be a single setting for this? -->
+ The default is 127.0.0.1.
+ </para>
+
+ <para><varname>master_port</varname>
+<!-- TODO: what if custom is needed per zone? -->
+ The default is 53.
+ </para>
+
+ <para><varname>transfers-in</varname>
+ defines the maximum number of inbound zone transfers
that can run concurrently. The default is 10.
</para>
<!-- TODO: formating -->
-<!-- TODO: refresh is code but not in spec -->
-<!-- schedule immediate maintenance for a zone(check soa serial ) -->
<para>
The configuration commands are:
</para>
+
+ <para>
+ <command>notify</command> is sent by
+ <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ when a DNS NOTIFY message is received to initiate a zone
+ transfer.
+<!-- TODO: document that zonemgr or xfrin checks if it needs to or not -->
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+ </para>
+
+ <para>
+ <command>refresh</command> triggers the transfer in for
+ a single zone.
+ It is the same as <command>retransfer</command> except it
+ checks the SOA serial first.
+<!-- TODO more detail -->
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+<!-- TODO: refresh is code but not in spec, see trac ticket #328 -->
+ </para>
+
+ <para>
+ <command>refresh_from_zonemgr</command> is sent by
+ <citerefentry><refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ according to the SOA's REFRESH time
+ to tell <command>b10-xfrin</command> that the zone needs to do
+ a zone refresh.
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
+ </para>
+
+ <para>
+ <command>retransfer</command> triggers the transfer in for
+ a single zone without checking the zone's serial number.
+ It has the following arguments: <varname>zone_name</varname>
+ to define the zone to request,
+ <varname>zone_class</varname> to define the class (defaults to
+ <quote>IN</quote>),
+ <varname>master</varname> to define the IP address of
+ the authoritative server to transfer from,
+ and <varname>port</varname> to define the port number on the
+ authoritative server (defaults to 53).
+<!-- TODO: note: not documenting db_file since that will be removed. -->
+ </para>
+<!-- TODO: later hostname for master? -->
+
<para>
<command>shutdown</command> stops all incoming zone transfers
and exits <command>b10-xfrin</command>. (Note that the BIND 10
boss process will restart this service.)
</para>
- <para>
- <command>retransfer</command> triggers the transfer in for
- a single zone without checking the zone's serial number.
- It has the following arguments: <varname>zone_name</varname>
- to define the zone to request and <varname>master</varname>
- to define the IP address of the authoritative server to
- transfer from.
- </para>
-<!-- TODO: later hostname for master? -->
-
<!-- TODO:
add a usage example of xfrin -->
-
-<!-- TODO:
-
-port (defaults to 53)
-db_file (defaults to zone.sqlite3) --> <!-- TODO: fix this -->
<!-- TODO:
@@ -182,6 +224,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-zonemgr</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
Modified: branches/trac232/src/bin/xfrin/tests/xfrin_test.py
==============================================================================
--- branches/trac232/src/bin/xfrin/tests/xfrin_test.py (original)
+++ branches/trac232/src/bin/xfrin/tests/xfrin_test.py Fri Oct 8 09:51:09 2010
@@ -505,12 +505,12 @@
self.args)['result'][0], 1)
def test_command_handler_retransfer_nomodule(self):
- dns_module = sys.modules['libdns_python'] # this must exist
- del sys.modules['libdns_python']
+ dns_module = sys.modules['pydnspp'] # this must exist
+ del sys.modules['pydnspp']
self.assertEqual(self.xfr.command_handler("retransfer",
self.args)['result'][0], 1)
# sys.modules is global, so we must recover it
- sys.modules['libdns_python'] = dns_module
+ sys.modules['pydnspp'] = dns_module
def test_command_handler_refresh(self):
# at this level, refresh is no different than retransfer.
Modified: branches/trac232/src/bin/xfrin/xfrin.py.in
==============================================================================
--- branches/trac232/src/bin/xfrin/xfrin.py.in (original)
+++ branches/trac232/src/bin/xfrin/xfrin.py.in Fri Oct 8 09:51:09 2010
@@ -26,17 +26,20 @@
import threading
import socket
import random
-import libdns_python
+import pydnspp
import libdata_source_python
from optparse import OptionParser, OptionValueError
from isc.config.ccsession import *
from isc.notify import notify_out
+import isc.utils.process
try:
- from libdns_python import *
+ from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed; even so the xfrin process
# must keep running, so we warn about it and move forward.
sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
+
+isc.utils.process.rename()
# If B10_FROM_BUILD is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
@@ -201,8 +204,11 @@
self.log_msg(logstr + 'succeeded')
- ret = XFRIN_OK
-
+
+ except pydnspp.MessageTooShort as mts:
+ self.log_msg(mts)
+ self.log_msg(logstr + 'failed')
+ ret = XFRIN_FAIL
except XfrinException as e:
self.log_msg(e)
self.log_msg(logstr + 'failed')
@@ -314,26 +320,14 @@
self._check_response_status(msg)
answer_section = msg.get_section(Section.ANSWER())
- #for rr in self._handle_answer_section(answer_section):
- # yield rr
- print("[XX] MESSAGE:")
- print(msg)
ds = libdata_source_python.DataSrc()
ds.init("{ \"database_file\": \"" + self._db_file +"\" }")
- print("[XX] db file: " + self._db_file)
- print("[XX] zone name: " + self._zone_name)
transaction = libdata_source_python.DataSrcTransaction(ds, Name(self._zone_name), RRClass.IN())
result = ds.start_transaction(transaction)
- print("[XX] start transaction: " + str(result))
result = ds.do_ixfr(transaction, answer_section)
- print("[XX] do ixfr: " + str(result))
result = ds.commit_transaction(transaction)
- print("[XX] commit: " + str(result))
ds.close()
-
- #if self._soa_rr_count == 2:
- # break
def handle_read(self):
'''Read query's response from socket. '''
@@ -558,8 +552,8 @@
def xfrin_start(self, zone_name, rrclass, db_file, master_addrinfo,
check_soa = True):
- if "libdns_python" not in sys.modules:
- return (1, "xfrin failed, can't load dns message python library: 'libdns_python'")
+ if "pydnspp" not in sys.modules:
+ return (1, "xfrin failed, can't load dns message python library: 'pydnspp'")
# check max_transfer_in, else return quota error
if self.recorder.count() >= self._max_transfers_in:
Modified: branches/trac232/src/bin/xfrout/Makefile.am
==============================================================================
--- branches/trac232/src/bin/xfrout/Makefile.am (original)
+++ branches/trac232/src/bin/xfrout/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac232/src/bin/xfrout/TODO
==============================================================================
--- branches/trac232/src/bin/xfrout/TODO (original)
+++ branches/trac232/src/bin/xfrout/TODO Fri Oct 8 09:51:09 2010
@@ -1,1 +1,2 @@
-Add unittest code.
+Add unittest code.
+Be able to cancel the outgoing zone transfer, and also be able to disable outgoing zone transfer.
Modified: branches/trac232/src/bin/xfrout/b10-xfrout.8
==============================================================================
--- branches/trac232/src/bin/xfrout/b10-xfrout.8 (original)
+++ branches/trac232/src/bin/xfrout/b10-xfrout.8 Fri Oct 8 09:51:09 2010
@@ -2,12 +2,12 @@
.\" Title: b10-xfrout
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\" Date: April 20, 2010
+.\" Date: September 8, 2010
.\" Manual: BIND10
.\" Source: BIND10
.\" Language: English
.\"
-.TH "B10\-XFROUT" "8" "April 20, 2010" "BIND10" "BIND10"
+.TH "B10\-XFROUT" "8" "September 8, 2010" "BIND10" "BIND10"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -27,7 +27,7 @@
.PP
The
\fBb10\-xfrout\fR
-daemon provides the BIND 10 outgoing DNS zone transfer service\&. Normally it is started by the
+daemon provides the BIND 10 outgoing DNS zone transfer service\&. It is also used to send outgoing NOTIFY messages\&. Normally it is started by the
\fBbind10\fR(8)
boss process\&. When the
\fBb10\-auth\fR
@@ -67,13 +67,13 @@
The configurable settings are:
.PP
-\fItransfers\-out\fR
-defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
-.PP
-
\fIdb_file\fR
defines the path to the SQLite3 data store file\&. The default is
/usr/local/var/bind10\-devel/zone\&.sqlite3\&.
+.PP
+
+\fItransfers_out\fR
+defines the maximum number of outgoing zone transfers that can run concurrently\&. The default is 10\&.
.if n \{\
.sp
.\}
@@ -91,25 +91,34 @@
.sp .5v
.RE
.PP
-The configuration command is:
+The configuration commands are:
.PP
\fBshutdown\fR
stops all outbound zone transfers and exits
\fBb10\-xfrout\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+.PP
+
+\fBzone_new_data_ready\fR
+is sent from
+\fBb10-xfrin\fR(8)
+to indicate that the zone transferred in successfully\&. This triggers
+\fBb10\-xfrout\fR
+to send NOTIFY message(s)\&. This is an internal command and not exposed to the administrator\&.
.SH "SEE ALSO"
.PP
\fBb10-auth\fR(8),
\fBb10-cfgmgr\fR(8),
\fBb10-msgq\fR(8),
+\fBb10-xfrin\fR(8),
\fBbind10\fR(8),
BIND 10 Guide\&.
.SH "HISTORY"
.PP
The
\fBb10\-xfrout\fR
-daemon was implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
+daemon was first implemented in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project\&.
.SH "COPYRIGHT"
.br
Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
Modified: branches/trac232/src/bin/xfrout/b10-xfrout.xml
==============================================================================
--- branches/trac232/src/bin/xfrout/b10-xfrout.xml (original)
+++ branches/trac232/src/bin/xfrout/b10-xfrout.xml Fri Oct 8 09:51:09 2010
@@ -21,7 +21,7 @@
<refentry>
<refentryinfo>
- <date>April 20, 2010</date>
+ <date>September 8, 2010</date>
</refentryinfo>
<refmeta>
@@ -54,6 +54,7 @@
<title>DESCRIPTION</title>
<para>The <command>b10-xfrout</command> daemon provides the BIND 10
outgoing DNS zone transfer service.
+ It is also used to send outgoing NOTIFY messages.
Normally it is started by the
<citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
boss process.
@@ -93,16 +94,20 @@
The configurable settings are:
</para>
<para>
- <varname>transfers-out</varname>
- defines the maximum number of outgoing zone transfers
- that can run concurrently. The default is 10.
- </para>
- <para>
<varname>db_file</varname>
defines the path to the SQLite3 data store file.
The default is
<filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>.
+<!-- TODO: db_file will be removed -->
</para>
+ <para>
+ <varname>transfers_out</varname>
+ defines the maximum number of outgoing zone transfers
+ that can run concurrently. The default is 10.
+ </para>
+
+<!-- TODO: log configurations not documented yet in here. jreed
+ has some but waiting on decisions ... -->
<note><simpara>
This prototype version uses SQLite3 as its data source backend.
@@ -112,12 +117,22 @@
<!-- TODO: formating -->
<para>
- The configuration command is:
+ The configuration commands are:
</para>
<para>
<command>shutdown</command> stops all outbound zone transfers
and exits <command>b10-xfrout</command>. (Note that the BIND 10
boss process will restart this service.)
+ </para>
+
+ <para>
+ <command>zone_new_data_ready</command> is sent from
+ <citerefentry><refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ to indicate that the zone transferred in successfully.
+ This triggers <command>b10-xfrout</command> to send NOTIFY
+ message(s).
+ This is an internal command and not exposed to the administrator.
+<!-- not defined in spec -->
</para>
</refsect1>
@@ -161,6 +176,9 @@
<refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citerefentry>
+ <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
<refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
</citerefentry>,
<citetitle>BIND 10 Guide</citetitle>.
@@ -170,8 +188,8 @@
<refsect1>
<title>HISTORY</title>
<para>
- The <command>b10-xfrout</command> daemon was implemented in March 2010
- by Zhang Likun of CNNIC for the ISC BIND 10 project.
+ The <command>b10-xfrout</command> daemon was first implemented
+ in March 2010 by Zhang Likun of CNNIC for the ISC BIND 10 project.
</para>
</refsect1>
</refentry><!--
Modified: branches/trac232/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- branches/trac232/src/bin/xfrout/tests/xfrout_test.py (original)
+++ branches/trac232/src/bin/xfrout/tests/xfrout_test.py Fri Oct 8 09:51:09 2010
@@ -19,7 +19,7 @@
import unittest
import os
from isc.cc.session import *
-from libdns_python import *
+from pydnspp import *
from xfrout import *
# our fake socket, where we can read and insert messages
@@ -40,8 +40,12 @@
return len(data)
def readsent(self):
- result = self.sendqueue[:]
- del self.sendqueue[:]
+ if len(self.sendqueue) >= 2:
+ size = 2 + struct.unpack("!H", self.sendqueue[:2])[0]
+ else:
+ size = 0
+ result = self.sendqueue[:size]
+ self.sendqueue = self.sendqueue[size:]
return result
def read_msg(self):
@@ -133,7 +137,7 @@
msg = self.getmsg()
msg.make_response()
- self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa)
+ self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 0)
get_msg = self.sock.read_msg()
self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
@@ -148,10 +152,52 @@
rdata = answer.get_rdata()
self.assertEqual(rdata[0].to_text(), self.soa_record[7])
- def test_get_message_len(self):
- msg = self.getmsg()
- msg.make_response()
- self.assertEqual(self.xfrsess._get_message_len(msg), 29)
+ def test_trigger_send_message_with_last_soa(self):
+ rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
+ rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+
+ msg = self.getmsg()
+ msg.make_response()
+
+ msg.add_rrset(Section.ANSWER(), rrset_a)
+ # give the function a value that is larger than MAX-len(rrset)
+ self.xfrsess._send_message_with_last_soa(msg, self.sock, rrset_soa, 65520)
+
+ # this should have triggered the sending of two messages
+ # (1 with the rrset we added manually, and 1 that triggered
+ # the sending in _with_last_soa)
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 1)
+ self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
+ self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
+
+ answer = get_msg.get_section(Section.ANSWER())[0]
+ self.assertEqual(answer.get_name().to_text(), "example.com.")
+ self.assertEqual(answer.get_class(), RRClass("IN"))
+ self.assertEqual(answer.get_type().to_text(), "A")
+ rdata = answer.get_rdata()
+ self.assertEqual(rdata[0].to_text(), "192.0.2.1")
+
+ get_msg = self.sock.read_msg()
+ self.assertEqual(get_msg.get_rr_count(Section.QUESTION()), 0)
+ self.assertEqual(get_msg.get_rr_count(Section.ANSWER()), 1)
+ self.assertEqual(get_msg.get_rr_count(Section.AUTHORITY()), 0)
+
+ #answer_rrset_iter = section_iter(get_msg, section.ANSWER())
+ answer = get_msg.get_section(Section.ANSWER())[0]
+ self.assertEqual(answer.get_name().to_text(), "example.com.")
+ self.assertEqual(answer.get_class(), RRClass("IN"))
+ self.assertEqual(answer.get_type().to_text(), "SOA")
+ rdata = answer.get_rdata()
+ self.assertEqual(rdata[0].to_text(), self.soa_record[7])
+
+ # and it should not have sent anything else
+ self.assertEqual(0, len(self.sock.sendqueue))
+
+ def test_get_rrset_len(self):
+ rrset_soa = self.xfrsess._create_rrset_from_db_record(self.soa_record)
+ self.assertEqual(82, get_rrset_len(rrset_soa))
def test_zone_is_empty(self):
global sqlite3_ds
Modified: branches/trac232/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac232/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac232/src/bin/xfrout/xfrout.py.in Fri Oct 8 09:51:09 2010
@@ -27,19 +27,22 @@
import os
from isc.config.ccsession import *
from isc.log.log import *
-from isc.cc import SessionError
+from isc.cc import SessionError, SessionTimeout
from isc.notify import notify_out
+import isc.utils.process
import socket
import select
import errno
from optparse import OptionParser, OptionValueError
try:
from libxfr_python import *
- from libdns_python import *
+ from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed; even so the xfrout process
# must keep running, so we warn about it and move forward.
sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+
+isc.utils.process.rename()
if "B10_FROM_BUILD" in os.environ:
SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
@@ -57,6 +60,15 @@
MAX_TRANSFERS_OUT = 10
VERBOSE_MODE = False
+XFROUT_MAX_MESSAGE_SIZE = 65535
+
+def get_rrset_len(rrset):
+ """Returns the wire length of the given RRset"""
+ bytes = bytearray()
+ rrset.to_wire(bytes)
+ return len(bytes)
+
+
class XfroutSession(BaseRequestHandler):
def __init__(self, request, client_address, server, log):
# The initializer for the superclass may call functions
@@ -121,10 +133,8 @@
def _send_message(self, sock, msg):
- #obuf = output_buffer(0)
- #render = message_render(obuf)
render = MessageRenderer()
- render.set_length_limit(65535)
+ render.set_length_limit(XFROUT_MAX_MESSAGE_SIZE)
msg.to_wire(render)
header_len = struct.pack('H', socket.htons(render.get_length()))
self._send_data(sock, header_len)
@@ -227,34 +237,20 @@
rrset_.add_rdata(rdata_)
return rrset_
- def _send_message_with_last_soa(self, msg, sock, rrset_soa):
+ def _send_message_with_last_soa(self, msg, sock, rrset_soa, message_upper_len):
'''Add the SOA record to the end of message. If it can't be
added, a new message should be created to send out the last soa .
'''
-
- render = MessageRenderer()
- msg.to_wire(render)
- old_message_len = render.get_length()
- msg.add_rrset(Section.ANSWER(), rrset_soa)
-
- msg.to_wire(render)
- message_len = render.get_length()
-
- if message_len != old_message_len:
+ rrset_len = get_rrset_len(rrset_soa)
+
+ if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+ msg.add_rrset(Section.ANSWER(), rrset_soa)
+ else:
self._send_message(sock, msg)
- else:
msg = self._clear_message(msg)
msg.add_rrset(Section.ANSWER(), rrset_soa)
- self._send_message(sock, msg)
-
- def _get_message_len(self, msg):
- '''Get message length, every time need do like this? Actually there should be
- a better way, I need check with jinmei later.
- '''
-
- render = MessageRenderer()
- msg.to_wire(render)
- return render.get_length()
+
+ self._send_message(sock, msg)
def _reply_xfrout_query(self, msg, sock, zone_name):
@@ -265,9 +261,8 @@
rrset_soa = self._create_rrset_from_db_record(soa_record)
msg.add_rrset(Section.ANSWER(), rrset_soa)
- old_message_len = 0
- # TODO, Since add_rrset() return nothing when rrset can't be added, so I have to compare
- # the message length to know if the rrset has been added sucessfully.
+ message_upper_len = get_rrset_len(rrset_soa)
+
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
self._log.log_message("error", "shutdown!")
@@ -277,19 +272,22 @@
continue
rrset_ = self._create_rrset_from_db_record(rr_data)
- msg.add_rrset(Section.ANSWER(), rrset_)
- message_len = self._get_message_len(msg)
- if message_len != old_message_len:
- old_message_len = message_len
+
+ # We calculate the maximum size of the RRset (i.e. the
+ # size without compression) and use that to see if we
+ # may have reached the limit
+ rrset_len = get_rrset_len(rrset_)
+ if message_upper_len + rrset_len < XFROUT_MAX_MESSAGE_SIZE:
+ msg.add_rrset(Section.ANSWER(), rrset_)
+ message_upper_len += rrset_len
continue
self._send_message(sock, msg)
msg = self._clear_message(msg)
msg.add_rrset(Section.ANSWER(), rrset_) # Add the rrset to the new message
- old_message_len = 0
-
- self._send_message_with_last_soa(msg, sock, rrset_soa)
-
+ message_upper_len = rrset_len
+
+ self._send_message_with_last_soa(msg, sock, rrset_soa, message_upper_len)
class UnixSockServer(ThreadingUnixStreamServer):
'''The unix domain socket server which accept xfr query sent from auth server.'''
@@ -315,8 +313,8 @@
If it's not a socket file or nobody is listening
, it will be removed. If it can't be removed, exit from python. '''
if self._sock_file_in_use(sock_file):
- print("[b10-xfrout] Fail to start xfrout process, unix socket"
- " file '%s' is being used by another xfrout process" % sock_file)
+ sys.stderr.write("[b10-xfrout] Fail to start xfrout process, unix socket"
+ " file '%s' is being used by another xfrout process\n" % sock_file)
sys.exit(0)
else:
if not os.path.exists(sock_file):
@@ -325,7 +323,7 @@
try:
os.unlink(sock_file)
except OSError as err:
- print('[b10-xfrout] Fail to remove file ' + sock_file, err)
+ sys.stderr.write('[b10-xfrout] Fail to remove file %s: %s\n' % (sock_file, err))
sys.exit(0)
def _sock_file_in_use(self, sock_file):
@@ -409,9 +407,9 @@
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._cc.add_remote_config(AUTH_SPECFILE_LOCATION);
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)
@@ -481,8 +479,8 @@
zone_name = args.get('zone_name')
zone_class = args.get('zone_class')
if zone_name and zone_class:
- self._log.log_message("info", "Receive notify command for zone:'%s/%s'" \
- % (zone_name, zone_class))
+ self._log.log_message("info", "zone '%s/%s': receive notify others command" \
+ % (zone_name, zone_class))
self.send_notify(zone_name, zone_class)
answer = create_answer(0)
else:
@@ -525,12 +523,15 @@
xfrout_server = XfroutServer()
xfrout_server.run()
except KeyboardInterrupt:
- sys.stderr.write("[b10-xfrout] exit xfrout process")
+ sys.stderr.write("[b10-xfrout] exit xfrout process\n")
except SessionError as e:
- sys.stderr.write("[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?\n")
+ except SessionTimeout as e:
+ sys.stderr.write("[b10-xfrout] Error creating xfrout, "
+ "is the configuration manager running?\n")
except ModuleCCSessionError as e:
- sys.stderr.write("info", '[b10-xfrout] exit xfrout process:', e)
+ sys.stderr.write("[b10-xfrout] exit xfrout process:%s\n" % str(e))
if xfrout_server:
xfrout_server.shutdown()
Modified: branches/trac232/src/bin/zonemgr/Makefile.am
==============================================================================
--- branches/trac232/src/bin/zonemgr/Makefile.am (original)
+++ branches/trac232/src/bin/zonemgr/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
@@ -9,6 +9,16 @@
CLEANFILES = b10-zonemgr zonemgr.pyc zonemgr.spec
+man_MANS = b10-zonemgr.8
+EXTRA_DIST = $(man_MANS) b10-zonemgr.xml
+
+if ENABLE_MAN
+
+b10-zonemgr.8: b10-zonemgr.xml
+ xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-zonemgr.xml
+
+endif
+
zonemgr.spec: zonemgr.spec.pre
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" zonemgr.spec.pre >$@
Modified: branches/trac232/src/bin/zonemgr/TODO
==============================================================================
--- branches/trac232/src/bin/zonemgr/TODO (original)
+++ branches/trac232/src/bin/zonemgr/TODO Fri Oct 8 09:51:09 2010
@@ -1,1 +1,6 @@
1. Zonemgr should support adding/deleting zones dynamically.
+2. Make zonemgr has customizable configurations for LOWERBOUND_REFRESH, LOWERBOUND_RETRY, MAX_TRANSFER_TIMEOUT, REFRESH_OFFSET, RETRY_OFFSET, EXPIRED_OFFSET, and/or jitter?
+3. There should be one way to see the current counters/timers and other data for each zone managed by zonemgr.
+4. There should be one way to turn off zonemgr.(Does user really need it? not sure what's the purpose of user)
+
+
Modified: branches/trac232/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac232/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac232/src/bin/zonemgr/zonemgr.py.in Fri Oct 8 09:51:09 2010
@@ -36,6 +36,9 @@
from isc.datasrc import sqlite3_ds
from optparse import OptionParser, OptionValueError
from isc.config.ccsession import *
+import isc.utils.process
+
+isc.utils.process.rename()
# If B10_FROM_BUILD is set in the environment, we use data files
# from a directory relative to that, otherwise we use the ones
@@ -153,8 +156,8 @@
def zone_refresh_success(self, zone_name_class):
"""Update zone info after zone refresh success"""
if (self._zone_not_exist(zone_name_class)):
- raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't \
- belong to zonemgr" % zone_name_class)
+ raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
+ "belong to zonemgr" % zone_name_class)
return
self.zonemgr_reload_zone(zone_name_class)
self._set_zone_refresh_timer(zone_name_class)
@@ -164,8 +167,8 @@
def zone_refresh_fail(self, zone_name_class):
"""Update zone info after zone refresh fail"""
if (self._zone_not_exist(zone_name_class)):
- raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't \
- belong to zonemgr" % zone_name_class)
+ raise ZonemgrException("[b10-zonemgr] Zone (%s, %s) doesn't "
+ "belong to zonemgr" % zone_name_class)
return
self._set_zone_state(zone_name_class, ZONE_OK)
self._set_zone_retry_timer(zone_name_class)
@@ -173,8 +176,8 @@
def zone_handle_notify(self, zone_name_class, master):
"""Handle zone notify"""
if (self._zone_not_exist(zone_name_class)):
- raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) doesn't \
- belong to zonemgr" % zone_name_class)
+ raise ZonemgrException("[b10-zonemgr] Notified zone (%s, %s) "
+ "doesn't belong to zonemgr" % zone_name_class)
return
self._set_zone_notifier_master(zone_name_class, master)
self._set_zone_notify_timer(zone_name_class)
@@ -261,7 +264,7 @@
try:
self._cc.group_sendmsg(msg, module_name)
except socket.error:
- sys.err.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name)
+ sys.stderr.write("[b10-zonemgr] Failed to send to module %s, the session has been closed." % module_name)
def _find_need_do_refresh_zone(self):
"""Find the first zone need do refresh, if no zone need
@@ -513,12 +516,15 @@
zonemgrd = Zonemgr()
zonemgrd.run()
except KeyboardInterrupt:
- sys.stderr.write("[b10-zonemgr] exit zonemgr process")
+ sys.stderr.write("[b10-zonemgr] exit zonemgr process\n")
except isc.cc.session.SessionError as e:
- sys.stderr.write("[b10-zonemgr] Error creating ,zonemgr"
- "is the command channel daemon running?")
+ sys.stderr.write("[b10-zonemgr] Error creating zonemgr, "
+ "is the command channel daemon running?\n")
+ except isc.cc.session.SessionTimeout as e:
+ sys.stderr.write("[b10-zonemgr] Error creating zonemgr, "
+ "is the configuration manager running?\n")
except isc.config.ModuleCCSessionError as e:
- sys.stderr.write("info", "[b10-zonemgr] exit zonemgr process:", e)
+ sys.stderr.write("[b10-zonemgr] exit zonemgr process: %s\n" % str(e))
if zonemgrd:
zonemgrd.shutdown()
Modified: branches/trac232/src/lib/bench/benchmark_util.cc
==============================================================================
--- branches/trac232/src/lib/bench/benchmark_util.cc (original)
+++ branches/trac232/src/lib/bench/benchmark_util.cc Fri Oct 8 09:51:09 2010
@@ -26,6 +26,8 @@
#include <dns/name.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrtype.h>
#include <dns/rrclass.h>
#include <dns/question.h>
Modified: branches/trac232/src/lib/bench/tests/benchmark_unittest.cc
==============================================================================
--- branches/trac232/src/lib/bench/tests/benchmark_unittest.cc (original)
+++ branches/trac232/src/lib/bench/tests/benchmark_unittest.cc Fri Oct 8 09:51:09 2010
@@ -58,7 +58,7 @@
};
// XXX: some compilers cannot find class static constants used in
-// EXPECT_xxx macross, for which we need an explicit definition.
+// EXPECT_xxx macros, for which we need an explicit definition.
template <typename T>
const int BenchMark<T>::TIME_FAILURE;
}
Modified: branches/trac232/src/lib/bench/tests/loadquery_unittest.cc
==============================================================================
--- branches/trac232/src/lib/bench/tests/loadquery_unittest.cc (original)
+++ branches/trac232/src/lib/bench/tests/loadquery_unittest.cc Fri Oct 8 09:51:09 2010
@@ -22,6 +22,8 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
@@ -79,7 +81,6 @@
// Check if the header part indicates an expected standard query.
EXPECT_EQ(0, message.getQid());
EXPECT_EQ(Opcode::QUERY(), message.getOpcode());
- EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
EXPECT_EQ(Rcode::NOERROR(), message.getRcode());
EXPECT_FALSE(message.getHeaderFlag(MessageFlag::QR()));
EXPECT_FALSE(message.getHeaderFlag(MessageFlag::AA()));
Modified: branches/trac232/src/lib/cc/tests/Makefile.am
==============================================================================
--- branches/trac232/src/lib/cc/tests/Makefile.am (original)
+++ branches/trac232/src/lib/cc/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -18,8 +18,7 @@
# (TODO: these need to be completed and moved to tests/)
run_unittests_SOURCES = data_unittests.cc session_unittests.cc run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-# TODO: remove PTHREAD_LDFLAGS (and from configure too)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_LDFLAGS)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
Modified: branches/trac232/src/lib/config/Makefile.am
==============================================================================
--- branches/trac232/src/lib/config/Makefile.am (original)
+++ branches/trac232/src/lib/config/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = . testdata tests
+SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
@@ -8,45 +8,3 @@
libcfgclient_la_SOURCES = config_data.h config_data.cc module_spec.h module_spec.cc ccsession.cc ccsession.h
CLEANFILES = *.gcno *.gcda
-
-EXTRA_DIST = testdata/b10-config-bad1.db
-EXTRA_DIST += testdata/b10-config-bad2.db
-EXTRA_DIST += testdata/b10-config-bad3.db
-EXTRA_DIST += testdata/b10-config-bad4.db
-EXTRA_DIST += testdata/b10-config.db.master #.db will be auto-generated
-EXTRA_DIST += testdata/data22_1.data
-EXTRA_DIST += testdata/data22_2.data
-EXTRA_DIST += testdata/data22_3.data
-EXTRA_DIST += testdata/data22_4.data
-EXTRA_DIST += testdata/data22_5.data
-EXTRA_DIST += testdata/data22_6.data
-EXTRA_DIST += testdata/data22_7.data
-EXTRA_DIST += testdata/data22_8.data
-EXTRA_DIST += testdata/spec1.spec
-EXTRA_DIST += testdata/spec2.spec
-EXTRA_DIST += testdata/spec3.spec
-EXTRA_DIST += testdata/spec4.spec
-EXTRA_DIST += testdata/spec5.spec
-EXTRA_DIST += testdata/spec6.spec
-EXTRA_DIST += testdata/spec7.spec
-EXTRA_DIST += testdata/spec8.spec
-EXTRA_DIST += testdata/spec9.spec
-EXTRA_DIST += testdata/spec10.spec
-EXTRA_DIST += testdata/spec11.spec
-EXTRA_DIST += testdata/spec12.spec
-EXTRA_DIST += testdata/spec13.spec
-EXTRA_DIST += testdata/spec14.spec
-EXTRA_DIST += testdata/spec15.spec
-EXTRA_DIST += testdata/spec16.spec
-EXTRA_DIST += testdata/spec17.spec
-EXTRA_DIST += testdata/spec18.spec
-EXTRA_DIST += testdata/spec19.spec
-EXTRA_DIST += testdata/spec20.spec
-EXTRA_DIST += testdata/spec21.spec
-EXTRA_DIST += testdata/spec22.spec
-EXTRA_DIST += testdata/spec23.spec
-EXTRA_DIST += testdata/spec24.spec
-EXTRA_DIST += testdata/spec25.spec
-EXTRA_DIST += testdata/spec26.spec
-EXTRA_DIST += testdata/spec27.spec
-EXTRA_DIST += testdata/spec28.spec
Modified: branches/trac232/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac232/src/lib/config/tests/Makefile.am (original)
+++ branches/trac232/src/lib/config/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,3 +1,5 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -24,12 +26,9 @@
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.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: branches/trac232/src/lib/config/tests/data_def_unittests_config.h.in
==============================================================================
--- branches/trac232/src/lib/config/tests/data_def_unittests_config.h.in (original)
+++ branches/trac232/src/lib/config/tests/data_def_unittests_config.h.in Fri Oct 8 09:51:09 2010
@@ -12,4 +12,4 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
-#define TEST_DATA_PATH "@abs_srcdir@/../testdata"
+#define TEST_DATA_PATH "@abs_srcdir@/testdata"
Modified: branches/trac232/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/data_source.cc (original)
+++ branches/trac232/src/lib/datasrc/data_source.cc Fri Oct 8 09:51:09 2010
@@ -32,6 +32,8 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rrset.h>
#include <dns/rrsetlist.h>
@@ -206,6 +208,11 @@
if (!hit || !rrset || (flags & DataSrc::CNAME_FOUND) != 0) {
hit = cache.retrieve(task.qname, task.qclass, RRType::CNAME(),
rrset, flags);
+ if (!rrset) {
+ // If we don't have a positive cache, forget it; otherwise the
+ // intermediate result may confuse the subsequent processing.
+ hit = false;
+ }
}
if (hit) {
Modified: branches/trac232/src/lib/datasrc/python/libdata_source_python.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/python/libdata_source_python.cc (original)
+++ branches/trac232/src/lib/datasrc/python/libdata_source_python.cc Fri Oct 8 09:51:09 2010
@@ -22,6 +22,7 @@
#include <datasrc/data_source.h>
#include <datasrc/sqlite3_datasrc.h>
+#include <dns/rcode.h>
#include <dns/rrsetlist.h>
#include <dns/rrset.h>
@@ -1139,7 +1140,7 @@
// import dns module for converting types
// TODO: if lib not in path this raises 'unreported exception'
- po_DNS_module = PyImport_ImportModule("libdns_python");
+ po_DNS_module = PyImport_ImportModule("pydnspp");
//std::cout << dns_mod << std::endl;
return (mod);
}
Modified: branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py
==============================================================================
--- branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py (original)
+++ branches/trac232/src/lib/datasrc/python/tests/data_source_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,14 +14,14 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the message part of the libdns_python module
+# Tests for the message part of the libdata_source_python module
#
import unittest
import sys
import os
from libdata_source_python import *
-from libdns_python import *
+from pydnspp import *
class DataSourceTest(unittest.TestCase):
def setUp(self):
Modified: branches/trac232/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac232/src/lib/datasrc/tests/datasrc_unittest.cc Fri Oct 8 09:51:09 2010
@@ -26,6 +26,8 @@
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rdata.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
@@ -915,6 +917,24 @@
headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
}
+TEST_F(DataSrcTest, DSQueryFromCache) {
+ // explicitly enable hot spot cache
+ cache.setEnabled(true);
+
+ // The first query will create a negative cache for example.org/CNAME
+ createAndProcessQuery(Name("example.org"), RRClass::IN(), RRType::SOA());
+
+ // the cached CNAME shouldn't confuse subsequent query.
+ // there may be several different possible cases that could trigger a bug,
+ // but DS query is the only known example.
+ msg.clear(Message::PARSE);
+ createAndProcessQuery(Name("example.org"), RRClass::IN(), RRType::DS());
+
+ // returning refused is probably a bad behavior, but it's a different
+ // issue -- see Trac Ticket #306.
+ headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
+}
+
// Non-existent name in the "static" data source. The purpose of this test
// is to check a corner case behavior when atypical RRClass (CH in this case)
// is specified.
Modified: branches/trac232/src/lib/datasrc/tests/query_unittest.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/tests/query_unittest.cc (original)
+++ branches/trac232/src/lib/datasrc/tests/query_unittest.cc Fri Oct 8 09:51:09 2010
@@ -19,6 +19,7 @@
#include <dns/buffer.h>
#include <dns/message.h>
#include <dns/name.h>
+#include <dns/opcode.h>
#include <dns/rrtype.h>
#include <dns/rrclass.h>
Modified: branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc
==============================================================================
--- branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc (original)
+++ branches/trac232/src/lib/datasrc/tests/sqlite3_unittest.cc Fri Oct 8 09:51:09 2010
@@ -26,7 +26,9 @@
#include <dns/name.h>
#include <dns/message.h>
+#include <dns/opcode.h>
#include <dns/rdata.h>
+#include <dns/rcode.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
#include <dns/rdataclass.h>
Modified: branches/trac232/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac232/src/lib/dns/Makefile.am (original)
+++ branches/trac232/src/lib/dns/Makefile.am Fri Oct 8 09:51:09 2010
@@ -63,11 +63,14 @@
libdns___la_SOURCES += util/base16_from_binary.h util/binary_from_base16.h
libdns___la_SOURCES += buffer.h
libdns___la_SOURCES += dnssectime.h dnssectime.cc
+libdns___la_SOURCES += edns.h edns.cc
libdns___la_SOURCES += exceptions.h exceptions.cc
libdns___la_SOURCES += util/hex.h
libdns___la_SOURCES += message.h message.cc
libdns___la_SOURCES += messagerenderer.h messagerenderer.cc
libdns___la_SOURCES += name.h name.cc
+libdns___la_SOURCES += opcode.h opcode.cc
+libdns___la_SOURCES += rcode.h rcode.cc
libdns___la_SOURCES += rdata.h rdata.cc
libdns___la_SOURCES += rrclass.cc
libdns___la_SOURCES += rrparamregistry.h
@@ -88,8 +91,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: branches/trac232/src/lib/dns/exceptions.cc
==============================================================================
--- branches/trac232/src/lib/dns/exceptions.cc (original)
+++ branches/trac232/src/lib/dns/exceptions.cc Fri Oct 8 09:51:09 2010
@@ -15,7 +15,7 @@
// $Id$
#include <dns/exceptions.h>
-#include <dns/message.h>
+#include <dns/rcode.h>
namespace isc {
namespace dns {
Modified: branches/trac232/src/lib/dns/message.cc
==============================================================================
--- branches/trac232/src/lib/dns/message.cc (original)
+++ branches/trac232/src/lib/dns/message.cc Fri Oct 8 09:51:09 2010
@@ -28,10 +28,13 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/question.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
@@ -61,98 +64,12 @@
const flags_t FLAG_AD = 0x0020;
const flags_t FLAG_CD = 0x0010;
-//
-// EDNS related constants
-//
-const flags_t EXTFLAG_MASK = 0xffff;
-const flags_t EXTFLAG_DO = 0x8000;
-const uint32_t EXTRCODE_MASK = 0xff000000;
-const uint32_t EDNSVERSION_MASK = 0x00ff0000;
-
const unsigned int OPCODE_MASK = 0x7800;
const unsigned int OPCODE_SHIFT = 11;
const unsigned int RCODE_MASK = 0x000f;
const unsigned int FLAG_MASK = 0x8ff0;
const unsigned int MESSAGE_REPLYPRESERVE = (FLAG_RD | FLAG_CD);
-
-const Rcode rcodes[] = {
- Rcode::NOERROR(),
- Rcode::FORMERR(),
- Rcode::SERVFAIL(),
- Rcode::NXDOMAIN(),
- Rcode::NOTIMP(),
- Rcode::REFUSED(),
- Rcode::YXDOMAIN(),
- Rcode::YXRRSET(),
- Rcode::NXRRSET(),
- Rcode::NOTAUTH(),
- Rcode::NOTZONE(),
- Rcode::RESERVED11(),
- Rcode::RESERVED12(),
- Rcode::RESERVED13(),
- Rcode::RESERVED14(),
- Rcode::RESERVED15(),
- Rcode::BADVERS()
-};
-
-const char *rcodetext[] = {
- "NOERROR",
- "FORMERR",
- "SERVFAIL",
- "NXDOMAIN",
- "NOTIMP",
- "REFUSED",
- "YXDOMAIN",
- "YXRRSET",
- "NXRRSET",
- "NOTAUTH",
- "NOTZONE",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15",
- "BADVERS"
-};
-
-const Opcode* opcodes[] = {
- &Opcode::QUERY(),
- &Opcode::IQUERY(),
- &Opcode::STATUS(),
- &Opcode::RESERVED3(),
- &Opcode::NOTIFY(),
- &Opcode::UPDATE(),
- &Opcode::RESERVED6(),
- &Opcode::RESERVED7(),
- &Opcode::RESERVED8(),
- &Opcode::RESERVED9(),
- &Opcode::RESERVED10(),
- &Opcode::RESERVED11(),
- &Opcode::RESERVED12(),
- &Opcode::RESERVED13(),
- &Opcode::RESERVED14(),
- &Opcode::RESERVED15()
-};
-
-const char *opcodetext[] = {
- "QUERY",
- "IQUERY",
- "STATUS",
- "RESERVED3",
- "NOTIFY",
- "UPDATE",
- "RESERVED6",
- "RESERVED7",
- "RESERVED8",
- "RESERVED9",
- "RESERVED10",
- "RESERVED11",
- "RESERVED12",
- "RESERVED13",
- "RESERVED14",
- "RESERVED15"
-};
const char *sectiontext[] = {
"QUESTION",
@@ -160,28 +77,6 @@
"AUTHORITY",
"ADDITIONAL"
};
-}
-
-string
-Opcode::toText() const {
- return (opcodetext[code_]);
-}
-
-Rcode::Rcode(uint16_t code) : code_(code) {
- if (code_ > MAX_RCODE) {
- isc_throw(OutOfRange, "Rcode is too large to construct");
- }
-}
-
-string
-Rcode::toText() const {
- if (code_ < sizeof(rcodetext) / sizeof (const char *)) {
- return (rcodetext[code_]);
- }
-
- ostringstream oss;
- oss << code_;
- return (oss.str());
}
namespace {
@@ -200,20 +95,24 @@
// for efficiency?
Message::Mode mode_;
qid_t qid_;
- Rcode rcode_;
+
+ // We want to use NULL for [op,r]code_ to mean the code being not
+ // correctly parsed or set. We store the real code object in
+ // xxcode_placeholder_ and have xxcode_ refer to it when the object
+ // is valid.
+ const Rcode* rcode_;
+ Rcode rcode_placeholder_;
const Opcode* opcode_;
+ Opcode opcode_placeholder_;
+
flags_t flags_;
- bool dnssec_ok_;
bool header_parsed_;
static const unsigned int SECTION_MAX = 4; // TODO: revisit this design
int counts_[SECTION_MAX]; // TODO: revisit this definition
vector<QuestionPtr> questions_;
vector<RRsetPtr> rrsets_[SECTION_MAX];
- RRsetPtr remote_edns_;
- uint16_t remote_udpsize_;
- RRsetPtr local_edns_;
- uint16_t udpsize_;
+ ConstEDNSPtr edns_;
#ifdef notyet
// tsig/sig0: TODO
@@ -221,12 +120,16 @@
#endif
void init();
+ void setOpcode(const Opcode& opcode);
+ void setRcode(const Rcode& rcode);
int parseQuestion(InputBuffer& buffer);
int parseSection(const Section& section, InputBuffer& buffer);
};
MessageImpl::MessageImpl(Message::Mode mode) :
- mode_(mode), rcode_(Rcode::NOERROR())
+ mode_(mode),
+ rcode_placeholder_(Rcode(0)), // as a placeholder the value doesn't matter
+ opcode_placeholder_(Opcode(0)) // ditto
{
init();
}
@@ -235,13 +138,9 @@
MessageImpl::init() {
flags_ = 0;
qid_ = 0;
- rcode_ = Rcode::NOERROR(); // XXX
+ rcode_ = NULL;
opcode_ = NULL;
- dnssec_ok_ = false;
- remote_edns_ = RRsetPtr();
- remote_udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
- local_edns_ = RRsetPtr();
- udpsize_ = Message::DEFAULT_MAX_UDPSIZE;
+ edns_ = EDNSPtr();
for (int i = 0; i < SECTION_MAX; ++i) {
counts_[i] = 0;
@@ -254,6 +153,18 @@
rrsets_[sectionCodeToId(Section::ADDITIONAL())].clear();
}
+void
+MessageImpl::setOpcode(const Opcode& opcode) {
+ opcode_placeholder_ = opcode;
+ opcode_ = &opcode_placeholder_;
+}
+
+void
+MessageImpl::setRcode(const Rcode& rcode) {
+ rcode_placeholder_ = rcode;
+ rcode_ = &rcode_placeholder_;
+}
+
Message::Message(Mode mode) :
impl_(new MessageImpl(mode))
{}
@@ -285,38 +196,6 @@
impl_->flags_ &= ~flag.getBit();
}
-bool
-Message::isDNSSECSupported() const {
- return (impl_->dnssec_ok_);
-}
-
-void
-Message::setDNSSECSupported(bool on) {
- if (impl_->mode_ != Message::RENDER) {
- isc_throw(InvalidMessageOperation,
- "setDNSSECSupported performed in non-render mode");
- }
- impl_->dnssec_ok_ = on;
-}
-
-uint16_t
-Message::getUDPSize() const {
- return (impl_->udpsize_);
-}
-
-void
-Message::setUDPSize(uint16_t size) {
- if (impl_->mode_ != Message::RENDER) {
- isc_throw(InvalidMessageOperation,
- "setUDPSize performed in non-render mode");
- }
- if (size < DEFAULT_MAX_UDPSIZE) {
- isc_throw(InvalidMessageUDPSize,
- "Specified UDP message size is too small");
- }
- impl_->udpsize_ = size;
-}
-
qid_t
Message::getQid() const {
return (impl_->qid_);
@@ -333,7 +212,10 @@
const Rcode&
Message::getRcode() const {
- return (impl_->rcode_);
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation, "getRcode attempted before set");
+ }
+ return (*impl_->rcode_);
}
void
@@ -342,11 +224,14 @@
isc_throw(InvalidMessageOperation,
"setRcode performed in non-render mode");
}
- impl_->rcode_ = rcode;
+ impl_->setRcode(rcode);
}
const Opcode&
Message::getOpcode() const {
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation, "getOpcode attempted before set");
+ }
return (*impl_->opcode_);
}
@@ -356,7 +241,21 @@
isc_throw(InvalidMessageOperation,
"setOpcode performed in non-render mode");
}
- impl_->opcode_ = &opcode;
+ impl_->setOpcode(opcode);
+}
+
+ConstEDNSPtr
+Message::getEDNS() const {
+ return (impl_->edns_);
+}
+
+void
+Message::setEDNS(ConstEDNSPtr edns) {
+ if (impl_->mode_ != Message::RENDER) {
+ isc_throw(InvalidMessageOperation,
+ "setEDNS performed in non-render mode");
+ }
+ impl_->edns_ = edns;
}
unsigned int
@@ -441,59 +340,19 @@
};
}
-namespace {
-bool
-addEDNS(MessageImpl* mimpl, MessageRenderer& renderer) {
- const bool is_query = ((mimpl->flags_ & MessageFlag::QR().getBit()) == 0);
-
- // If this is a reply, add EDNS either when the request had it, or
- // if the Rcode is BADVERS, which is EDNS specific.
- // XXX: this logic is tricky. We should revisit this later.
- if (!is_query) {
- if (mimpl->remote_edns_ == NULL && mimpl->rcode_ != Rcode::BADVERS()) {
- return (false);
- }
- } else {
- // For queries, we add EDNS only when necessary:
- // Local UDP size is not the default value, or
- // DNSSEC DO bit is to be set, or
- // Extended Rcode is to be specified.
- if (mimpl->udpsize_ == Message::DEFAULT_MAX_UDPSIZE &&
- !mimpl->dnssec_ok_ &&
- mimpl->rcode_.getCode() < 0x10) {
- return (false);
- }
- }
-
- // If adding the OPT RR would exceed the size limit, don't do it.
- // 11 = len(".") + type(2byte) + class(2byte) + TTL(4byte) + RDLEN(2byte)
- // (RDATA is empty in this simple implementation)
- if (renderer.getLength() + 11 > renderer.getLengthLimit()) {
- return (false);
- }
-
- // Render EDNS OPT RR
- uint32_t extrcode_flags = ((mimpl->rcode_.getCode() & 0xff0) << 24);
- if (mimpl->dnssec_ok_) {
- extrcode_flags |= 0x8000; // set DO bit
- }
- mimpl->local_edns_ = RRsetPtr(new RRset(Name::ROOT_NAME(),
- RRClass(mimpl->udpsize_),
- RRType::OPT(),
- RRTTL(extrcode_flags)));
- // We don't support any options in this simple implementation
- mimpl->local_edns_->addRdata(ConstRdataPtr(new generic::OPT()));
- mimpl->local_edns_->toWire(renderer);
-
- return (true);
-}
-}
-
void
Message::toWire(MessageRenderer& renderer) {
if (impl_->mode_ != Message::RENDER) {
isc_throw(InvalidMessageOperation,
"Message rendering attempted in non render mode");
+ }
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message rendering attempted without Rcode set");
+ }
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message rendering attempted without Opcode set");
}
// reserve room for the header
@@ -528,12 +387,20 @@
RenderSection<RRsetPtr>(renderer, false)).getTotalCount();
}
- // Added EDNS OPT RR if necessary (we want to avoid hardcoding specialized
- // logic, see the parser case)
- if (!renderer.isTruncated() && addEDNS(this->impl_, renderer)) {
- ++arcount;
- }
-
+ // Add EDNS OPT RR if necessary. Basically, we add it only when EDNS
+ // has been explicitly set. However, if the RCODE would require it and
+ // no EDNS has been set we generate a temporary local EDNS and use it.
+ if (!renderer.isTruncated()) {
+ ConstEDNSPtr local_edns = impl_->edns_;
+ if (!local_edns && impl_->rcode_->getExtendedCode() != 0) {
+ local_edns = ConstEDNSPtr(new EDNS());
+ }
+ if (local_edns) {
+ arcount += local_edns->toWire(renderer,
+ impl_->rcode_->getExtendedCode());
+ }
+ }
+
// Adjust the counter buffer.
// XXX: these may not be equal to the number of corresponding entries
// in rrsets_[] or questions_ if truncation occurred or an EDNS OPT RR
@@ -553,7 +420,7 @@
uint16_t codes_and_flags =
(impl_->opcode_->getCode() << OPCODE_SHIFT) & OPCODE_MASK;
- codes_and_flags |= (impl_->rcode_.getCode() & RCODE_MASK);
+ codes_and_flags |= (impl_->rcode_->getCode() & RCODE_MASK);
codes_and_flags |= (impl_->flags_ & FLAG_MASK);
renderer.writeUint16At(codes_and_flags, header_pos);
header_pos += sizeof(uint16_t);
@@ -582,8 +449,8 @@
impl_->qid_ = buffer.readUint16();
const uint16_t codes_and_flags = buffer.readUint16();
- impl_->opcode_ = opcodes[((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT)];
- impl_->rcode_ = rcodes[(codes_and_flags & RCODE_MASK)];
+ impl_->setOpcode(Opcode((codes_and_flags & OPCODE_MASK) >> OPCODE_SHIFT));
+ impl_->setRcode(Rcode(codes_and_flags & RCODE_MASK));
impl_->flags_ = (codes_and_flags & FLAG_MASK);
impl_->counts_[Section::QUESTION().getCode()] = buffer.readUint16();
impl_->counts_[Section::ANSWER().getCode()] = buffer.readUint16();
@@ -657,6 +524,34 @@
};
}
+// Note about design decision:
+// we need some type specific processing here, including EDNS and TSIG.
+// how much we should generalize/hardcode the special logic is subject
+// to discussion. In terms of modularity it would be ideal to introduce
+// an abstract class (say "MessageAttribute") and let other such
+// concrete notions as EDNS or TSIG inherit from it. Then we would
+// just do:
+// message->addAttribute(rrtype, rrclass, buffer);
+// to create and attach type-specific concrete object to the message.
+//
+// A major downside of this approach is, as usual, complexity due to
+// indirection and performance penalty. Also, it may not be so easy
+// to separate the processing logic because in many cases we'll need
+// parse context for which the message class is responsible (e.g.
+// to check the EDNS OPT RR only appears in the additional section,
+// and appears only once).
+//
+// Another point to consider is that we may not need so many special
+// types other than EDNS and TSIG (and when and if we implement it,
+// SIG(0)); newer optional attributes of the message would more likely
+// be standardized as new flags or options of EDNS. If that's the case,
+// introducing an abstract class with all the overhead and complexity
+// may not make much sense.
+//
+// Conclusion: don't over-generalize type-specific logic for now.
+// introduce separate concrete classes, and move context-independent
+// logic to that class; processing logic dependent on parse context
+// is hardcoded here.
int
MessageImpl::parseSection(const Section& section, InputBuffer& buffer) {
unsigned int added = 0;
@@ -678,60 +573,36 @@
const size_t rdlen = buffer.readUint16();
ConstRdataPtr rdata = createRdata(rrtype, rrclass, buffer, rdlen);
- // XXX: we wanted to avoid hardcoding type-specific logic here,
- // but this would be the fastest way for a proof-of-concept
- // implementation. We'll revisit this part later.
if (rrtype == RRType::OPT()) {
if (section != Section::ADDITIONAL()) {
isc_throw(DNSMessageFORMERR,
"EDNS OPT RR found in an invalid section");
}
- if (remote_edns_ != NULL) {
+ if (edns_) {
isc_throw(DNSMessageFORMERR, "multiple EDNS OPT RR found");
}
- if (((ttl.getValue() & EDNSVERSION_MASK) >> 16) >
- Message::EDNS_SUPPORTED_VERSION) {
- // XXX: we should probably not reject the message yet, because
- // it's better to let the requestor know the responder-side
- // highest version as indicated in Section 4.6 of RFC2671.
- // This is probably because why BIND 9 does the version check
- // in the client code.
- // This is a TODO item. Right now we simply reject it.
- const unsigned int ver =
- (ttl.getValue() & EDNSVERSION_MASK) >> 16;
- isc_throw(DNSMessageBADVERS, "unsupported EDNS version: " <<
- ver);
+
+ uint8_t extended_rcode;
+ edns_ = ConstEDNSPtr(createEDNSFromRR(name, rrclass, rrtype, ttl,
+ *rdata, extended_rcode));
+ setRcode(Rcode(rcode_->getCode(), extended_rcode));
+ continue;
+ } else {
+ vector<RRsetPtr>::iterator it =
+ find_if(rrsets_[sectionCodeToId(section)].begin(),
+ rrsets_[sectionCodeToId(section)].end(),
+ MatchRR(name, rrtype, rrclass));
+ if (it != rrsets_[sectionCodeToId(section)].end()) {
+ (*it)->setTTL(min((*it)->getTTL(), ttl));
+ (*it)->addRdata(rdata);
+ } else {
+ RRsetPtr rrset =
+ RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
+ rrset->addRdata(rdata);
+ rrsets_[sectionCodeToId(section)].push_back(rrset);
}
- if (name != Name::ROOT_NAME()) {
- isc_throw(DNSMessageFORMERR,
- "invalid owner name for EDNS OPT RR");
- }
-
- remote_edns_ = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- remote_edns_->addRdata(rdata);
-
- dnssec_ok_ = (((ttl.getValue() & EXTFLAG_MASK) & EXTFLAG_DO) != 0);
- if (rrclass.getCode() > Message::DEFAULT_MAX_UDPSIZE) {
- udpsize_ = rrclass.getCode();
- }
- rcode_ = Rcode(((ttl.getValue() & EXTRCODE_MASK) >> 20) |
- rcode_.getCode());
- continue;
+ ++added;
}
-
- vector<RRsetPtr>::iterator it =
- find_if(rrsets_[sectionCodeToId(section)].begin(),
- rrsets_[sectionCodeToId(section)].end(),
- MatchRR(name, rrtype, rrclass));
- if (it != rrsets_[sectionCodeToId(section)].end()) {
- (*it)->setTTL(min((*it)->getTTL(), ttl));
- (*it)->addRdata(rdata);
- } else {
- RRsetPtr rrset = RRsetPtr(new RRset(name, rrclass, rrtype, ttl));
- rrset->addRdata(rdata);
- rrsets_[sectionCodeToId(section)].push_back(rrset);
- }
- ++added;
}
return (added);
@@ -755,11 +626,20 @@
string
Message::toText() const {
+ if (impl_->rcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message::toText() attempted without Rcode set");
+ }
+ if (impl_->opcode_ == NULL) {
+ isc_throw(InvalidMessageOperation,
+ "Message::toText() attempted without Opcode set");
+ }
+
string s;
s += ";; ->>HEADER<<- opcode: " + impl_->opcode_->toText();
// for simplicity we don't consider extended rcode (unlike BIND9)
- s += ", status: " + impl_->rcode_.toText();
+ s += ", status: " + impl_->rcode_->toText();
s += ", id: " + boost::lexical_cast<string>(impl_->qid_);
s += "\n;; flags: ";
if (getHeaderFlag(MessageFlag::QR()))
@@ -786,30 +666,14 @@
lexical_cast<string>(impl_->counts_[Section::AUTHORITY().getCode()]);
unsigned int arcount = impl_->counts_[Section::ADDITIONAL().getCode()];
- RRsetPtr edns_rrset;
- if (!getHeaderFlag(MessageFlag::QR()) && impl_->remote_edns_ != NULL) {
- edns_rrset = impl_->remote_edns_;
+ if (impl_->edns_ != NULL) {
++arcount;
}
s += ", ADDITIONAL: " + lexical_cast<string>(arcount) + "\n";
- if (edns_rrset != NULL) {
+ if (impl_->edns_ != NULL) {
s += "\n;; OPT PSEUDOSECTION:\n";
- s += "; EDNS: version: ";
- s += lexical_cast<string>(
- (edns_rrset->getTTL().getValue() & 0x00ff0000) >> 16);
- s += ", flags:";
- if ((edns_rrset->getTTL().getValue() & 0x8000) != 0) {
- s += " do";
- }
- const uint32_t mbz = edns_rrset->getTTL().getValue() & ~0x8000 & 0xffff;
- if (mbz != 0) {
- s += "; MBZ: " + lexical_cast<string>(mbz) + ", udp: ";
- } else {
- s += "; udp: " +
- lexical_cast<string>(edns_rrset->getClass().getCode());
- }
- s += "\n";
+ s += impl_->edns_->toText();
}
if (!impl_->questions_.empty()) {
@@ -860,11 +724,7 @@
impl_->mode_ = Message::RENDER;
- impl_->dnssec_ok_ = false;
- impl_->remote_udpsize_ = impl_->udpsize_;
- impl_->local_edns_ = RRsetPtr();
- impl_->udpsize_ = DEFAULT_MAX_UDPSIZE;
-
+ impl_->edns_ = EDNSPtr();
impl_->flags_ &= MESSAGE_REPLYPRESERVE;
setHeaderFlag(MessageFlag::QR());
@@ -1005,16 +865,6 @@
}
ostream&
-operator<<(ostream& os, const Opcode& opcode) {
- return (os << opcode.toText());
-}
-
-ostream&
-operator<<(ostream& os, const Rcode& rcode) {
- return (os << rcode.toText());
-}
-
-ostream&
operator<<(ostream& os, const Message& message) {
return (os << message.toText());
}
Modified: branches/trac232/src/lib/dns/message.h
==============================================================================
--- branches/trac232/src/lib/dns/message.h (original)
+++ branches/trac232/src/lib/dns/message.h Fri Oct 8 09:51:09 2010
@@ -25,6 +25,7 @@
#include <exceptions/exceptions.h>
+#include <dns/edns.h>
#include <dns/question.h>
#include <dns/rrset.h>
@@ -81,6 +82,8 @@
class MessageRenderer;
class Message;
class MessageImpl;
+class Opcode;
+class Rcode;
template <typename T>
struct SectionIteratorImpl;
@@ -159,310 +162,6 @@
return (f);
}
-/// \brief The \c Opcode class objects represent standard OPCODEs
-/// of the header section of DNS messages.
-///
-/// Note: since there are only 15 possible values, it may make more sense to
-/// simply define an enum type to represent these values.
-///
-/// Constant objects are defined for standard flags.
-class Opcode {
-public:
- uint16_t getCode() const { return (code_); }
- bool operator==(const Opcode& other) const
- { return (code_ == other.code_); }
- bool operator!=(const Opcode& other) const
- { return (code_ != other.code_); }
- std::string toText() const;
- static const Opcode& QUERY();
- static const Opcode& IQUERY();
- static const Opcode& STATUS();
- static const Opcode& RESERVED3();
- static const Opcode& NOTIFY();
- static const Opcode& UPDATE();
- static const Opcode& RESERVED6();
- static const Opcode& RESERVED7();
- static const Opcode& RESERVED8();
- static const Opcode& RESERVED9();
- static const Opcode& RESERVED10();
- static const Opcode& RESERVED11();
- static const Opcode& RESERVED12();
- static const Opcode& RESERVED13();
- static const Opcode& RESERVED14();
- static const Opcode& RESERVED15();
-private:
- Opcode(uint16_t code) : code_(code) {}
- uint16_t code_;
-};
-
-inline const Opcode&
-Opcode::QUERY()
-{
- static Opcode c(0);
- return (c);
-}
-
-inline const Opcode&
-Opcode::IQUERY()
-{
- static Opcode c(1);
- return (c);
-}
-
-inline const Opcode&
-Opcode::STATUS()
-{
- static Opcode c(2);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED3()
-{
- static Opcode c(3);
- return (c);
-}
-
-inline const Opcode&
-Opcode::NOTIFY()
-{
- static Opcode c(4);
- return (c);
-}
-
-inline const Opcode&
-Opcode::UPDATE()
-{
- static Opcode c(5);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED6()
-{
- static Opcode c(6);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED7()
-{
- static Opcode c(7);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED8()
-{
- static Opcode c(8);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED9()
-{
- static Opcode c(9);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED10()
-{
- static Opcode c(10);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED11()
-{
- static Opcode c(11);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED12()
-{
- static Opcode c(12);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED13()
-{
- static Opcode c(13);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED14()
-{
- static Opcode c(14);
- return (c);
-}
-
-inline const Opcode&
-Opcode::RESERVED15()
-{
- static Opcode c(15);
- return (c);
-}
-
-/// \brief The \c Rcode class objects represent standard Response Codes
-/// (RCODEs) of the header section of DNS messages, and extended response
-/// codes as defined in the EDNS specification.
-///
-/// Constant objects are defined for standard flags.
-class Rcode {
-public:
- Rcode(uint16_t code);
- uint16_t getCode() const { return (code_); }
- bool operator==(const Rcode& other) const { return (code_ == other.code_); }
- bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
- std::string toText() const;
- static const Rcode& NOERROR();
- static const Rcode& FORMERR();
- static const Rcode& SERVFAIL();
- static const Rcode& NXDOMAIN();
- static const Rcode& NOTIMP();
- static const Rcode& REFUSED();
- static const Rcode& YXDOMAIN();
- static const Rcode& YXRRSET();
- static const Rcode& NXRRSET();
- static const Rcode& NOTAUTH();
- static const Rcode& NOTZONE();
- static const Rcode& RESERVED11();
- static const Rcode& RESERVED12();
- static const Rcode& RESERVED13();
- static const Rcode& RESERVED14();
- static const Rcode& RESERVED15();
- // Extended Rcodes follow (EDNS required):
- static const Rcode& BADVERS();
-private:
- uint16_t code_;
-
- // EDNS-extended RCODEs are 12-bit unsigned integers.
- static const uint16_t MAX_RCODE = 0xfff;
-};
-
-inline const Rcode&
-Rcode::NOERROR()
-{
- static Rcode c(0);
- return (c);
-}
-
-inline const Rcode&
-Rcode::FORMERR()
-{
- static Rcode c(1);
- return (c);
-}
-
-inline const Rcode&
-Rcode::SERVFAIL()
-{
- static Rcode c(2);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NXDOMAIN()
-{
- static Rcode c(3);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTIMP()
-{
- static Rcode c(4);
- return (c);
-}
-
-inline const Rcode&
-Rcode::REFUSED()
-{
- static Rcode c(5);
- return (c);
-}
-
-inline const Rcode&
-Rcode::YXDOMAIN()
-{
- static Rcode c(6);
- return (c);
-}
-
-inline const Rcode&
-Rcode::YXRRSET()
-{
- static Rcode c(7);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NXRRSET()
-{
- static Rcode c(8);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTAUTH()
-{
- static Rcode c(9);
- return (c);
-}
-
-inline const Rcode&
-Rcode::NOTZONE()
-{
- static Rcode c(10);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED11()
-{
- static Rcode c(11);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED12()
-{
- static Rcode c(12);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED13()
-{
- static Rcode c(13);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED14()
-{
- static Rcode c(14);
- return (c);
-}
-
-inline const Rcode&
-Rcode::RESERVED15()
-{
- static Rcode c(15);
- return (c);
-}
-
-inline const Rcode&
-Rcode::BADVERS()
-{
- static Rcode c(16);
- return (c);
-}
-
/// \brief The \c Section class objects represent DNS message sections such
/// as the header, question, or answer.
///
@@ -627,45 +326,6 @@
/// \c setHeaderFlag() with an additional argument.
void clearHeaderFlag(const MessageFlag& flag);
- /// \brief Return whether the message sender indicates DNSSEC is supported.
- /// If EDNS is included, this corresponds to the value of the DO bit.
- /// Otherwise, DNSSEC is considered not supported.
- bool isDNSSECSupported() const;
-
- /// \brief Specify whether DNSSEC is supported in the message.
- ///
- /// Only allowed in the \c RENDER mode.
- /// If EDNS is included in the message, the DO bit is set or cleared
- /// according to the specified value of this method.
- void setDNSSECSupported(bool on);
-
- /// \brief Return the maximum buffer size of UDP messages for the sender
- /// of the message.
- ///
- /// The semantics of this value is different based on the mode:
- /// In the \c PARSE mode, it means the buffer size of the remote node;
- /// in the \c RENDER mode, it means the buffer size of the local node.
- ///
- /// In either case, its value is the value of the UDP payload size field
- /// of EDNS (when it's included) or \c DEFAULT_MAX_UDPSIZE.
- ///
- /// Note: this interface may be confusing and may have to be revisited.
- uint16_t getUDPSize() const;
-
- /// \brief Specify the maximum buffer size of UDP messages of the local
- /// node.
- ///
- /// Only allowed in the \c RENDER mode.
- /// If EDNS OPT RR is included in the message, its UDP payload size field
- /// will be set to the specified value.
- ///
- /// Unless explicitly specified, \c DEFAULT_MAX_UDPSIZE will be assumed
- /// for the maximum buffer size, regardless of whether EDNS OPT RR is
- /// included or not. This means if an application wants to send a message
- /// with an EDNS OPT RR for specifying a larger UDP size, it must explicitly
- /// specify the value using this method.
- void setUDPSize(uint16_t size);
-
/// \brief Return the query ID given in the header section of the message.
qid_t getQid() const;
@@ -680,22 +340,50 @@
/// included). In the \c PARSE mode, if the received message contains
/// an EDNS OPT RR, the corresponding extended code is identified and
/// returned.
+ ///
+ /// The message must have been properly parsed (in the case of the
+ /// \c PARSE mode) or an \c Rcode has been set (in the case of the
+ /// \c RENDER mode) beforehand. Otherwise, an exception of class
+ /// \c InvalidMessageOperation will be thrown.
const Rcode& getRcode() const;
- /// \brief Return the Response Code of the message.
- ///
- /// Only allowed in the \c RENDER mode.
+ /// \brief Set the Response Code of the message.
+ ///
+ /// Only allowed in the \c RENDER mode.
+ ///
/// If the specified code is an EDNS extended RCODE, an EDNS OPT RR will be
/// included in the message.
void setRcode(const Rcode& rcode);
/// \brief Return the OPCODE given in the header section of the message.
+ ///
+ /// The message must have been properly parsed (in the case of the
+ /// \c PARSE mode) or an \c Opcode has been set (in the case of the
+ /// \c RENDER mode) beforehand. Otherwise, an exception of class
+ /// \c InvalidMessageOperation will be thrown.
const Opcode& getOpcode() const;
/// \brief Set the OPCODE of the header section of the message.
///
/// Only allowed in the \c RENDER mode.
void setOpcode(const Opcode& opcode);
+
+ /// \brief Return, if any, the EDNS associated with the message.
+ ///
+ /// This method never throws an exception.
+ ///
+ /// \return A shared pointer to the EDNS. This will be a null shared
+ /// pointer if the message is not associated with EDNS.
+ ConstEDNSPtr getEDNS() const;
+
+ /// \brief Set EDNS for the message.
+ ///
+ /// Only allowed in the \c RENDER mode; otherwise an exception of class
+ /// \c InvalidMessageOperation will be thrown.
+ ///
+ /// \param edns A shared pointer to an \c EDNS object to be set in
+ /// \c Message.
+ void setEDNS(ConstEDNSPtr edns);
/// \brief Returns the number of RRs contained in the given section.
unsigned int getRRCount(const Section& section) const;
@@ -768,10 +456,19 @@
void makeResponse();
/// \brief Convert the Message to a string.
+ ///
+ /// At least \c Opcode and \c Rcode must be validly set in the \c Message
+ /// (as a result of parse in the \c PARSE mode or by explicitly setting
+ /// in the \c RENDER mode); otherwise, an exception of
+ /// class \c InvalidMessageOperation will be thrown.
std::string toText() const;
/// \brief Render the message in wire formant into a \c MessageRenderer
/// object.
+ ///
+ /// This \c Message must be in the \c RENDER mode and both \c Opcode and
+ /// \c Rcode must have been set beforehand; otherwise, an exception of
+ /// class \c InvalidMessageOperation will be thrown.
void toWire(MessageRenderer& renderer);
/// \brief Parse the header section of the \c Message.
@@ -798,8 +495,6 @@
MessageImpl* impl_;
};
-std::ostream& operator<<(std::ostream& os, const Opcode& opcode);
-std::ostream& operator<<(std::ostream& os, const Rcode& rcode);
std::ostream& operator<<(std::ostream& os, const Message& message);
}
}
Modified: branches/trac232/src/lib/dns/name.cc
==============================================================================
--- branches/trac232/src/lib/dns/name.cc (original)
+++ branches/trac232/src/lib/dns/name.cc Fri Oct 8 09:51:09 2010
@@ -601,17 +601,17 @@
Name
Name::concatenate(const Name& suffix) const {
- assert(this->length_ > 0 && suffix.length_ > 0);
- assert(this->labelcount_ > 0 && suffix.labelcount_ > 0);
-
- unsigned int length = this->length_ + suffix.length_ - 1;
+ assert(length_ > 0 && suffix.length_ > 0);
+ assert(labelcount_ > 0 && suffix.labelcount_ > 0);
+
+ unsigned int length = length_ + suffix.length_ - 1;
if (length > Name::MAX_WIRE) {
isc_throw(TooLongName, "names are too long to concatenate");
}
Name retname;
retname.ndata_.reserve(length);
- retname.ndata_.assign(this->ndata_, 0, this->length_ - 1);
+ retname.ndata_.assign(ndata_, 0, length_ - 1);
retname.ndata_.insert(retname.ndata_.end(),
suffix.ndata_.begin(), suffix.ndata_.end());
assert(retname.ndata_.size() == length);
@@ -622,14 +622,13 @@
// excluding that for the trailing dot, and append the offsets of the
// suffix name with the additional offset of the length of the prefix.
//
- unsigned int labels = this->labelcount_ + suffix.labelcount_ - 1;
+ unsigned int labels = labelcount_ + suffix.labelcount_ - 1;
assert(labels <= Name::MAX_LABELS);
retname.offsets_.reserve(labels);
- retname.offsets_.assign(&this->offsets_[0],
- &this->offsets_[0] + this->labelcount_ - 1);
+ retname.offsets_.assign(&offsets_[0], &offsets_[0] + labelcount_ - 1);
transform(suffix.offsets_.begin(), suffix.offsets_.end(),
back_inserter(retname.offsets_),
- bind2nd(plus<char>(), this->length_ - 1));
+ bind2nd(plus<char>(), length_ - 1));
assert(retname.offsets_.size() == labels);
retname.labelcount_ = labels;
Modified: branches/trac232/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac232/src/lib/dns/python/Makefile.am (original)
+++ branches/trac232/src/lib/dns/python/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,26 +1,23 @@
-SUBDIRS = tests
+SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CXXFLAGS = $(B10_CXXFLAGS)
-#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
-#libdns_python_name_la_SOURCES = name_python.cc
-#libdns_python_name_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-#libdns_python_name_la_LDFLAGS = $(PYTHON_LDFLAGS)
-
-#lib_LTLIBRARIES = libdns_python_name.la libdns_python_rrset.la
-pyexec_LTLIBRARIES = libdns_python.la
-libdns_python_la_SOURCES = libdns_python.cc libdns_python_common.cc
-libdns_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-libdns_python_la_LDFLAGS = $(PYTHON_LDFLAGS)
+pyexec_LTLIBRARIES = pydnspp.la
+pydnspp_la_SOURCES = pydnspp.cc pydnspp_common.cc
+pydnspp_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
+pydnspp_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 = pydnspp_common.h
+EXTRA_DIST += edns_python.cc
EXTRA_DIST += messagerenderer_python.cc
EXTRA_DIST += message_python.cc
EXTRA_DIST += rrclass_python.cc
EXTRA_DIST += name_python.cc
+EXTRA_DIST += opcode_python.cc
+EXTRA_DIST += rcode_python.cc
EXTRA_DIST += rrset_python.cc
EXTRA_DIST += question_python.cc
EXTRA_DIST += rrttl_python.cc
@@ -29,7 +26,7 @@
# 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/exceptions/libexceptions.la
-libdns_python_la_LIBADD += $(PYTHON_LIB)
+pydnspp_la_LDFLAGS += -module
+pydnspp_la_LIBADD = $(top_builddir)/src/lib/dns/libdns++.la
+pydnspp_la_LIBADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
+pydnspp_la_LIBADD += $(PYTHON_LIB)
Modified: branches/trac232/src/lib/dns/python/README
==============================================================================
--- branches/trac232/src/lib/dns/python/README (original)
+++ branches/trac232/src/lib/dns/python/README Fri Oct 8 09:51:09 2010
@@ -1,14 +1,14 @@
This is an implementation of the python wrappers for isc::dns.
-Currently, when compiled the module is called libdns_python. If we
+When compiled the module is called pydnspp. If we
decide to always need it we can add a default import under
lib/python/isc.
To use it from the source tree, you must add src/lib/dns/python/.libs
to your PYTHONPATH environment variable. Within python you can then use
-> import libdns_python
-> rrc = libdns_python.RRClass("IN")
+> import pydnspp
+> rrc = pydnspp.RRClass("IN")
etc.
Notes:
@@ -26,8 +26,8 @@
If you have specific functionality you do need, please ask for it and we
will add it.
-The 'main' module is defined in libdns_python.cc.
-There is a libdns_python_common.[cc|h] for helper functions.
+The 'main' module is defined in pydnspp.cc.
+There is a pydnspp_common.[cc|h] for helper functions.
Implementation notes:
@@ -87,7 +87,7 @@
Finally we define the function to add the class, constants, exceptions,
and enums to the module. This function is called from the init function
-in libdns_python.cc, has the name
+in pydnspp.cc, has the name
initModulePart_<c++ class name>, returns a boolean
(true on success, false on failure), and takes the module as a
PyObject*. There is a convenience function called addClassVariable to
Modified: branches/trac232/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/message_python.cc (original)
+++ branches/trac232/src/lib/dns/python/message_python.cc Fri Oct 8 09:51:09 2010
@@ -26,7 +26,6 @@
static PyObject* po_InvalidMessageSection;
static PyObject* po_InvalidMessageOperation;
static PyObject* po_InvalidMessageUDPSize;
-static PyObject* po_DNSMessageBADVERS;
//
// Definition of the classes
@@ -71,7 +70,7 @@
static PyTypeObject messageflag_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.MessageFlag",
+ "pydnspp.MessageFlag",
sizeof(s_MessageFlag), // tp_basicsize
0, // tp_itemsize
(destructor)MessageFlag_destroy, // tp_dealloc
@@ -120,7 +119,6 @@
0 // tp_version_tag
};
-
static int
MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
PyObject* args UNUSED_PARAM)
@@ -190,585 +188,6 @@
//
// End of MessageFlag wrapper
//
-
-
-//
-// Opcode
-//
-class s_Opcode : public PyObject {
-public:
- const Opcode* opcode;
-};
-
-static int Opcode_init(s_Opcode* self, PyObject* args);
-static void Opcode_destroy(s_Opcode* self);
-
-static PyObject* Opcode_getCode(s_Opcode* self);
-static PyObject* Opcode_toText(s_Opcode* self);
-static PyObject* Opcode_str(PyObject* self);
-static PyObject* Opcode_QUERY(s_Opcode* self);
-static PyObject* Opcode_IQUERY(s_Opcode* self);
-static PyObject* Opcode_STATUS(s_Opcode* self);
-static PyObject* Opcode_RESERVED3(s_Opcode* self);
-static PyObject* Opcode_NOTIFY(s_Opcode* self);
-static PyObject* Opcode_UPDATE(s_Opcode* self);
-static PyObject* Opcode_RESERVED6(s_Opcode* self);
-static PyObject* Opcode_RESERVED7(s_Opcode* self);
-static PyObject* Opcode_RESERVED8(s_Opcode* self);
-static PyObject* Opcode_RESERVED9(s_Opcode* self);
-static PyObject* Opcode_RESERVED10(s_Opcode* self);
-static PyObject* Opcode_RESERVED11(s_Opcode* self);
-static PyObject* Opcode_RESERVED12(s_Opcode* self);
-static PyObject* Opcode_RESERVED13(s_Opcode* self);
-static PyObject* Opcode_RESERVED14(s_Opcode* self);
-static PyObject* Opcode_RESERVED15(s_Opcode* self);
-static PyObject* Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op);
-
-static PyMethodDef Opcode_methods[] = {
- { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS, "Returns the code value" },
- { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS, "Returns the text representation" },
- { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY), METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
- { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY), METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
- { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS), METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
- { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3), METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
- { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY), METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
- { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE), METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
- { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Opcode" },
- { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject opcode_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Opcode",
- sizeof(s_Opcode), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Opcode_destroy, // tp_dealloc
- NULL, // tp_print
- NULL, // tp_getattr
- NULL, // tp_setattr
- NULL, // tp_reserved
- NULL, // tp_repr
- NULL, // tp_as_number
- NULL, // tp_as_sequence
- NULL, // tp_as_mapping
- NULL, // tp_hash
- NULL, // tp_call
- Opcode_str, // tp_str
- NULL, // tp_getattro
- NULL, // tp_setattro
- NULL, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "The Opcode class objects represent standard OPCODEs "
- "of the header section of DNS messages.",
- NULL, // tp_traverse
- NULL, // tp_clear
- (richcmpfunc)Opcode_richcmp, // tp_richcompare
- 0, // tp_weaklistoffset
- NULL, // tp_iter
- NULL, // tp_iternext
- Opcode_methods, // tp_methods
- NULL, // tp_members
- NULL, // tp_getset
- NULL, // tp_base
- NULL, // tp_dict
- NULL, // tp_descr_get
- NULL, // tp_descr_set
- 0, // tp_dictoffset
- (initproc)Opcode_init, // tp_init
- NULL, // tp_alloc
- PyType_GenericNew, // tp_new
- NULL, // tp_free
- NULL, // tp_is_gc
- NULL, // tp_bases
- NULL, // tp_mro
- NULL, // tp_cache
- NULL, // tp_subclasses
- NULL, // tp_weaklist
- NULL, // tp_del
- 0 // tp_version_tag
-};
-
-
-static int
-Opcode_init(s_Opcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
- PyErr_SetString(PyExc_NotImplementedError,
- "Opcode can't be built directly");
- return (-1);
-}
-
-static void
-Opcode_destroy(s_Opcode* self) {
- // We only use the consts from Opcode, so don't
- // delete self->opcode here
- self->opcode = NULL;
- Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Opcode_getCode(s_Opcode* self) {
- return (Py_BuildValue("I", self->opcode->getCode()));
-}
-
-static PyObject*
-Opcode_toText(s_Opcode* self) {
- return (Py_BuildValue("s", self->opcode->toText().c_str()));
-}
-
-static PyObject*
-Opcode_str(PyObject* self) {
- // Simply call the to_text method we already defined
- return (PyObject_CallMethod(self,
- const_cast<char*>("to_text"),
- const_cast<char*>("")));
-}
-
-static PyObject*
-Opcode_createStatic(const Opcode& opcode) {
- s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
- if (ret != NULL) {
- ret->opcode = &opcode;
- }
- return (ret);
-}
-
-static PyObject*
-Opcode_QUERY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::QUERY()));
-}
-
-static PyObject*
-Opcode_IQUERY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::IQUERY()));
-}
-
-static PyObject*
-Opcode_STATUS(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::STATUS()));
-}
-
-static PyObject*
-Opcode_RESERVED3(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED3()));
-}
-
-static PyObject*
-Opcode_NOTIFY(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::NOTIFY()));
-}
-
-static PyObject*
-Opcode_UPDATE(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::UPDATE()));
-}
-
-static PyObject*
-Opcode_RESERVED6(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED6()));
-}
-
-static PyObject*
-Opcode_RESERVED7(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED7()));
-}
-
-static PyObject*
-Opcode_RESERVED8(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED8()));
-}
-
-static PyObject*
-Opcode_RESERVED9(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED9()));
-}
-
-static PyObject*
-Opcode_RESERVED10(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED10()));
-}
-
-static PyObject*
-Opcode_RESERVED11(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED11()));
-}
-
-static PyObject*
-Opcode_RESERVED12(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED12()));
-}
-
-static PyObject*
-Opcode_RESERVED13(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED13()));
-}
-
-static PyObject*
-Opcode_RESERVED14(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED14()));
-}
-
-static PyObject*
-Opcode_RESERVED15(s_Opcode* self UNUSED_PARAM) {
- return (Opcode_createStatic(Opcode::RESERVED15()));
-}
-
-static PyObject*
-Opcode_richcmp(s_Opcode* self, s_Opcode* other, int op) {
- bool c = false;
-
- // Check for null and if the types match. If different type,
- // simply return False
- if (!other || (self->ob_type != other->ob_type)) {
- Py_RETURN_FALSE;
- }
-
- // Only equals and not equals here, unorderable type
- switch (op) {
- case Py_LT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_LE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_EQ:
- c = (*self->opcode == *other->opcode);
- break;
- case Py_NE:
- c = (*self->opcode != *other->opcode);
- break;
- case Py_GT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- case Py_GE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Opcode");
- return (NULL);
- break;
- }
- if (c)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-//
-// End of Opcode wrapper
-//
-
-//
-// Rcode
-//
-
-// We added a helper variable static_code here
-// Since we can create Rcodes dynamically with Rcode(int), but also
-// use the static globals (Rcode::NOERROR() etc), we use this
-// variable to see if the code came from one of the latter, in which
-// case Rcode_destroy should not free it (the other option is to
-// allocate new Rcodes for every use of the static ones, but this
-// seems more efficient).
-class s_Rcode : public PyObject {
-public:
- const Rcode* rcode;
- bool static_code;
-};
-
-static int Rcode_init(s_Rcode* self, PyObject* args);
-static void Rcode_destroy(s_Rcode* self);
-
-static PyObject* Rcode_getCode(s_Rcode* self);
-static PyObject* Rcode_toText(s_Rcode* self);
-static PyObject* Rcode_str(PyObject* self);
-static PyObject* Rcode_NOERROR(s_Rcode* self);
-static PyObject* Rcode_FORMERR(s_Rcode* self);
-static PyObject* Rcode_SERVFAIL(s_Rcode* self);
-static PyObject* Rcode_NXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_NOTIMP(s_Rcode* self);
-static PyObject* Rcode_REFUSED(s_Rcode* self);
-static PyObject* Rcode_YXDOMAIN(s_Rcode* self);
-static PyObject* Rcode_YXRRSET(s_Rcode* self);
-static PyObject* Rcode_NXRRSET(s_Rcode* self);
-static PyObject* Rcode_NOTAUTH(s_Rcode* self);
-static PyObject* Rcode_NOTZONE(s_Rcode* self);
-static PyObject* Rcode_RESERVED11(s_Rcode* self);
-static PyObject* Rcode_RESERVED12(s_Rcode* self);
-static PyObject* Rcode_RESERVED13(s_Rcode* self);
-static PyObject* Rcode_RESERVED14(s_Rcode* self);
-static PyObject* Rcode_RESERVED15(s_Rcode* self);
-static PyObject* Rcode_BADVERS(s_Rcode* self);
-static PyObject* Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op);
-
-static PyMethodDef Rcode_methods[] = {
- { "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
- { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS, "Returns the text representation" },
- { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR), METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
- { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR), METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
- { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL), METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
- { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
- { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP), METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
- { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED), METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
- { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15), METH_NOARGS | METH_STATIC, "Creates a RESERVED Rcode" },
- { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS), METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
- { NULL, NULL, 0, NULL }
-};
-
-static PyTypeObject rcode_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Rcode",
- sizeof(s_Rcode), // tp_basicsize
- 0, // tp_itemsize
- (destructor)Rcode_destroy, // tp_dealloc
- NULL, // tp_print
- NULL, // tp_getattr
- NULL, // tp_setattr
- NULL, // tp_reserved
- NULL, // tp_repr
- NULL, // tp_as_number
- NULL, // tp_as_sequence
- NULL, // tp_as_mapping
- NULL, // tp_hash
- NULL, // tp_call
- Rcode_str, // tp_str
- NULL, // tp_getattro
- NULL, // tp_setattro
- NULL, // tp_as_buffer
- Py_TPFLAGS_DEFAULT, // tp_flags
- "The Rcode class objects represent standard RCODEs"
- "of the header section of DNS messages.",
- NULL, // tp_traverse
- NULL, // tp_clear
- (richcmpfunc)Rcode_richcmp, // tp_richcompare
- 0, // tp_weaklistoffset
- NULL, // tp_iter
- NULL, // tp_iternext
- Rcode_methods, // tp_methods
- NULL, // tp_members
- NULL, // tp_getset
- NULL, // tp_base
- NULL, // tp_dict
- NULL, // tp_descr_get
- NULL, // tp_descr_set
- 0, // tp_dictoffset
- (initproc)Rcode_init, // tp_init
- NULL, // tp_alloc
- PyType_GenericNew, // tp_new
- NULL, // tp_free
- NULL, // tp_is_gc
- NULL, // tp_bases
- NULL, // tp_mro
- NULL, // tp_cache
- NULL, // tp_subclasses
- NULL, // tp_weaklist
- NULL, // tp_del
- 0 // tp_version_tag
-};
-
-
-static int
-Rcode_init(s_Rcode* self UNUSED_PARAM, PyObject* args UNUSED_PARAM) {
- uint16_t code = 0;
- if (PyArg_ParseTuple(args, "h", &code)) {
- try {
- self->rcode = new Rcode(code);
- self->static_code = false;
- } catch (const isc::OutOfRange&) {
- PyErr_SetString(PyExc_OverflowError,
- "rcode out of range");
- return (-1);
- }
- return (0);
- } else {
- return (-1);
- }
-}
-
-static void
-Rcode_destroy(s_Rcode* self) {
- // Depending on whether we created the rcode or are referring
- // to a global static one, we do or do not delete self->rcode here
- if (!self->static_code) {
- delete self->rcode;
- }
- self->rcode = NULL;
- Py_TYPE(self)->tp_free(self);
-}
-
-static PyObject*
-Rcode_getCode(s_Rcode* self) {
- return (Py_BuildValue("I", self->rcode->getCode()));
-}
-
-static PyObject*
-Rcode_toText(s_Rcode* self) {
- return (Py_BuildValue("s", self->rcode->toText().c_str()));
-}
-
-static PyObject*
-Rcode_str(PyObject* self) {
- // Simply call the to_text method we already defined
- return (PyObject_CallMethod(self,
- const_cast<char*>("to_text"),
- const_cast<char*>("")));
-}
-
-static PyObject*
-Rcode_createStatic(const Rcode& rcode) {
- s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
- if (ret != NULL) {
- ret->rcode = &rcode;
- ret->static_code = true;
- }
- return (ret);
-}
-
-static PyObject*
-Rcode_NOERROR(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOERROR()));
-}
-
-static PyObject*
-Rcode_FORMERR(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::FORMERR()));
-}
-
-static PyObject*
-Rcode_SERVFAIL(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::SERVFAIL()));
-}
-
-static PyObject*
-Rcode_NXDOMAIN(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NXDOMAIN()));
-}
-
-static PyObject*
-Rcode_NOTIMP(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTIMP()));
-}
-
-static PyObject*
-Rcode_REFUSED(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::REFUSED()));
-}
-
-static PyObject*
-Rcode_YXDOMAIN(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::YXDOMAIN()));
-}
-
-static PyObject*
-Rcode_YXRRSET(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::YXRRSET()));
-}
-
-static PyObject*
-Rcode_NXRRSET(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NXRRSET()));
-}
-
-static PyObject*
-Rcode_NOTAUTH(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTAUTH()));
-}
-
-static PyObject*
-Rcode_NOTZONE(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::NOTZONE()));
-}
-
-static PyObject*
-Rcode_RESERVED11(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED11()));
-}
-
-static PyObject*
-Rcode_RESERVED12(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED12()));
-}
-
-static PyObject*
-Rcode_RESERVED13(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED13()));
-}
-
-static PyObject*
-Rcode_RESERVED14(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED14()));
-}
-
-static PyObject*
-Rcode_RESERVED15(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::RESERVED15()));
-}
-
-static PyObject*
-Rcode_BADVERS(s_Rcode* self UNUSED_PARAM) {
- return (Rcode_createStatic(Rcode::BADVERS()));
-}
-
-static PyObject*
-Rcode_richcmp(s_Rcode* self, s_Rcode* other, int op) {
- bool c = false;
-
- // Check for null and if the types match. If different type,
- // simply return False
- if (!other || (self->ob_type != other->ob_type)) {
- Py_RETURN_FALSE;
- }
-
- // Only equals and not equals here, unorderable type
- switch (op) {
- case Py_LT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_LE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_EQ:
- c = (*self->rcode == *other->rcode);
- break;
- case Py_NE:
- c = (*self->rcode != *other->rcode);
- break;
- case Py_GT:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- case Py_GE:
- PyErr_SetString(PyExc_TypeError, "Unorderable type; Rcode");
- return (NULL);
- break;
- }
- if (c)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
-}
-
-//
-// End of Rcode wrapper
-//
-
//
// Section
@@ -802,7 +221,7 @@
static PyTypeObject section_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Section",
+ "pydnspp.Section",
sizeof(s_Section), // tp_basicsize
0, // tp_itemsize
(destructor)Section_destroy, // tp_dealloc
@@ -973,16 +392,14 @@
static PyObject* Message_getHeaderFlag(s_Message* self, PyObject* args);
static PyObject* Message_setHeaderFlag(s_Message* self, PyObject* args);
static PyObject* Message_clearHeaderFlag(s_Message* self, PyObject* args);
-static PyObject* Message_isDNSSECSupported(s_Message* self);
-static PyObject* Message_setDNSSECSupported(s_Message* self, PyObject* args);
-static PyObject* Message_getUDPSize(s_Message* self);
-static PyObject* Message_setUDPSize(s_Message* self, PyObject* args);
static PyObject* Message_getQid(s_Message* self);
static PyObject* Message_setQid(s_Message* self, PyObject* args);
static PyObject* Message_getRcode(s_Message* self);
static PyObject* Message_setRcode(s_Message* self, PyObject* args);
static PyObject* Message_getOpcode(s_Message* self);
static PyObject* Message_setOpcode(s_Message* self, PyObject* args);
+static PyObject* Message_getEDNS(s_Message* self);
+static PyObject* Message_setEDNS(s_Message* self, PyObject* args);
static PyObject* Message_getRRCount(s_Message* self, PyObject* args);
// use direct iterators for these? (or simply lists for now?)
static PyObject* Message_getQuestion(s_Message* self);
@@ -1019,35 +436,6 @@
"Sets the specified header flag bit to 0. The message must be in "
"RENDER mode. If not, an InvalidMessageOperation is raised. "
"Takes a MessageFlag object as the only argument." },
- { "is_dnssec_supported", reinterpret_cast<PyCFunction>(Message_isDNSSECSupported), METH_NOARGS,
- "Returns True if the message sender indicates DNSSEC is supported. "
- "If EDNS is included, this corresponds to the value of the DO bit. "
- "Otherwise, DNSSEC is considered not supported." },
- { "set_dnssec_supported", reinterpret_cast<PyCFunction>(Message_setDNSSECSupported), METH_VARARGS,
- "Specify whether DNSSEC is supported in the message. "
- "The message must be in RENDER mode. If not, an "
- "InvalidMessageOperation is raised."
- "If EDNS is included in the message, the DO bit is set or cleared "
- "according to given argument (True or False) of this method."},
- { "get_udp_size", reinterpret_cast<PyCFunction>(Message_getUDPSize), METH_NOARGS,
- "Return the maximum buffer size of UDP messages for the sender "
- "of the message.\n\n"
- "The semantics of this value is different based on the mode:\n"
- "In the PARSE mode, it means the buffer size of the remote node;\n"
- "in the RENDER mode, it means the buffer size of the local node.\n\n"
- "In either case, its value is the value of the UDP payload size field "
- "of EDNS (when it's included) or DEFAULT_MAX_UDPSIZE." },
- { "set_udp_size", reinterpret_cast<PyCFunction>(Message_setUDPSize), METH_VARARGS,
- "Specify the maximum buffer size of UDP messages of the local "
- "node. If the message is not in RENDER mode, an "
- "InvalidMessageOperation is raised.\n\n"
- "If EDNS OPT RR is included in the message, its UDP payload size field "
- "will be set to the specified value.\n"
- "Unless explicitly specified, DEFAULT_MAX_UDPSIZE will be assumed "
- "for the maximum buffer size, regardless of whether EDNS OPT RR is "
- "included or not. This means if an application wants to send a message "
- "with an EDNS OPT RR for specifying a larger UDP size, it must explicitly "
- "specify the value using this method. "},
{ "get_qid", reinterpret_cast<PyCFunction>(Message_getQid), METH_NOARGS,
"Returns the query id" },
{ "set_qid", reinterpret_cast<PyCFunction>(Message_setQid), METH_VARARGS,
@@ -1066,6 +454,12 @@
"Sets the message opcode (an Opcode object).\n"
"If the message is not in RENDER mode, an "
"InvalidMessageOperation is raised."},
+ { "get_edns", reinterpret_cast<PyCFunction>(Message_getEDNS), METH_NOARGS,
+ "Return, if any, the EDNS associated with the message."
+ },
+ { "set_edns", reinterpret_cast<PyCFunction>(Message_setEDNS), METH_VARARGS,
+ "Set EDNS for the message."
+ },
{ "get_rr_count", reinterpret_cast<PyCFunction>(Message_getRRCount), METH_VARARGS,
"Returns the number of RRs contained in the given section." },
{ "get_question", reinterpret_cast<PyCFunction>(Message_getQuestion), METH_NOARGS,
@@ -1117,7 +511,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject message_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Message",
+ "pydnspp.Message",
sizeof(s_Message), // tp_basicsize
0, // tp_itemsize
(destructor)Message_destroy, // tp_dealloc
@@ -1248,57 +642,6 @@
}
static PyObject*
-Message_isDNSSECSupported(s_Message* self) {
- if (self->message->isDNSSECSupported()) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-static PyObject*
-Message_setDNSSECSupported(s_Message* self, PyObject* args) {
- PyObject *b;
- if (!PyArg_ParseTuple(args, "O!", &PyBool_Type, &b)) {
- return (NULL);
- }
- try {
- if (b == Py_True) {
- self->message->setDNSSECSupported(true);
- } else {
- self->message->setDNSSECSupported(false);
- }
- Py_RETURN_NONE;
- } catch (const InvalidMessageOperation& imo) {
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
- return (NULL);
- }
-}
-
-static PyObject*
-Message_getUDPSize(s_Message* self) {
- return (Py_BuildValue("I", self->message->getUDPSize()));
-}
-
-static PyObject*
-Message_setUDPSize(s_Message* self, PyObject* args) {
- uint16_t size;
- if (!PyArg_ParseTuple(args, "H", &size)) {
- return (NULL);
- }
- try {
- self->message->setUDPSize(size);
- Py_RETURN_NONE;
- } catch (const InvalidMessageUDPSize& imus) {
- PyErr_SetString(po_InvalidMessageUDPSize, imus.what());
- return (NULL);
- } catch (const InvalidMessageOperation& imo) {
- PyErr_SetString(po_InvalidMessageOperation, imo.what());
- return (NULL);
- }
-}
-
-static PyObject*
Message_getQid(s_Message* self) {
return (Py_BuildValue("I", self->message->getQid()));
}
@@ -1324,12 +667,18 @@
rcode = static_cast<s_Rcode*>(rcode_type.tp_alloc(&rcode_type, 0));
if (rcode != NULL) {
- rcode->rcode = new Rcode(self->message->getRcode());
- if (rcode->rcode == NULL)
- {
+ rcode->rcode = NULL;
+ try {
+ rcode->rcode = new Rcode(self->message->getRcode());
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ }
+ if (rcode->rcode == NULL) {
Py_DECREF(rcode);
return (NULL);
- }
+ }
}
return (rcode);
@@ -1356,15 +705,18 @@
opcode = static_cast<s_Opcode*>(opcode_type.tp_alloc(&opcode_type, 0));
if (opcode != NULL) {
- // Note that we do not new and delete for opcodes.
- // all rcodes point to the statics defined in
- // message.cc
- opcode->opcode = &self->message->getOpcode();
- if (opcode->opcode == NULL)
- {
+ opcode->opcode = NULL;
+ try {
+ opcode->opcode = new Opcode(self->message->getOpcode());
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ }
+ if (opcode->opcode == NULL) {
Py_DECREF(opcode);
return (NULL);
- }
+ }
}
return (opcode);
@@ -1378,6 +730,41 @@
}
try {
self->message->setOpcode(*opcode->opcode);
+ Py_RETURN_NONE;
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ return (NULL);
+ }
+}
+
+static PyObject*
+Message_getEDNS(s_Message* self) {
+ s_EDNS* edns;
+ EDNS* edns_body;
+ ConstEDNSPtr src = self->message->getEDNS();
+
+ if (!src) {
+ Py_RETURN_NONE;
+ }
+ if ((edns_body = new(nothrow) EDNS(*src)) == NULL) {
+ return (PyErr_NoMemory());
+ }
+ edns = static_cast<s_EDNS*>(opcode_type.tp_alloc(&edns_type, 0));
+ if (edns != NULL) {
+ edns->edns = edns_body;
+ }
+
+ return (edns);
+}
+
+static PyObject*
+Message_setEDNS(s_Message* self, PyObject* args) {
+ s_EDNS* edns;
+ if (!PyArg_ParseTuple(args, "O!", &edns_type, &edns)) {
+ return (NULL);
+ }
+ try {
+ self->message->setEDNS(EDNSPtr(new EDNS(*edns->edns)));
Py_RETURN_NONE;
} catch (const InvalidMessageOperation& imo) {
PyErr_SetString(po_InvalidMessageOperation, imo.what());
@@ -1520,7 +907,16 @@
static PyObject*
Message_toText(s_Message* self) {
// Py_BuildValue makes python objects from native data
- return (Py_BuildValue("s", self->message->toText().c_str()));
+ try {
+ return (Py_BuildValue("s", self->message->toText().c_str()));
+ } catch (const InvalidMessageOperation& imo) {
+ PyErr_Clear();
+ PyErr_SetString(po_InvalidMessageOperation, imo.what());
+ return (NULL);
+ } catch (...) {
+ PyErr_SetString(po_IscException, "Unexpected exception");
+ return (NULL);
+ }
}
static PyObject*
@@ -1535,7 +931,7 @@
Message_toWire(s_Message* self, PyObject* args) {
s_MessageRenderer* mr;
- if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
try {
self->message->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
@@ -1627,15 +1023,15 @@
addClassVariable(message_type, "DEFAULT_MAX_UDPSIZE", Py_BuildValue("I", Message::DEFAULT_MAX_UDPSIZE));
/* Class-specific exceptions */
- po_MessageTooShort = PyErr_NewException("libdns_python.MessageTooShort", NULL, NULL);
+ po_MessageTooShort = PyErr_NewException("pydnspp.MessageTooShort", NULL, NULL);
PyModule_AddObject(mod, "MessageTooShort", po_MessageTooShort);
- po_InvalidMessageSection = PyErr_NewException("libdns_python.InvalidMessageSection", NULL, NULL);
+ po_InvalidMessageSection = PyErr_NewException("pydnspp.InvalidMessageSection", NULL, NULL);
PyModule_AddObject(mod, "InvalidMessageSection", po_InvalidMessageSection);
- po_InvalidMessageOperation = PyErr_NewException("libdns_python.InvalidMessageOperation", NULL, NULL);
+ po_InvalidMessageOperation = PyErr_NewException("pydnspp.InvalidMessageOperation", NULL, NULL);
PyModule_AddObject(mod, "InvalidMessageOperation", po_InvalidMessageOperation);
- po_InvalidMessageUDPSize = PyErr_NewException("libdns_python.InvalidMessageUDPSize", NULL, NULL);
+ po_InvalidMessageUDPSize = PyErr_NewException("pydnspp.InvalidMessageUDPSize", NULL, NULL);
PyModule_AddObject(mod, "InvalidMessageUDPSize", po_InvalidMessageUDPSize);
- po_DNSMessageBADVERS = PyErr_NewException("libdns_python.DNSMessageBADVERS", NULL, NULL);
+ po_DNSMessageBADVERS = PyErr_NewException("pydnspp.DNSMessageBADVERS", NULL, NULL);
PyModule_AddObject(mod, "DNSMessageBADVERS", po_DNSMessageBADVERS);
Py_INCREF(&message_type);
Modified: branches/trac232/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac232/src/lib/dns/python/messagerenderer_python.cc Fri Oct 8 09:51:09 2010
@@ -42,7 +42,7 @@
// TODO: set/get compressmode
static PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
static PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
-
+static PyObject* MessageRenderer_clear(s_MessageRenderer* self);
static PyMethodDef MessageRenderer_methods[] = {
{ "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
@@ -57,12 +57,15 @@
"Sets truncated to true" },
{ "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
"Sets the length limit of the data to the given number" },
+ { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
+ METH_NOARGS,
+ "Clear the internal buffer and other internal resources." },
{ NULL, NULL, 0, NULL }
};
static PyTypeObject messagerenderer_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.MessageRenderer",
+ "pydnspp.MessageRenderer",
sizeof(s_MessageRenderer), // tp_basicsize
0, // tp_itemsize
(destructor)MessageRenderer_destroy,// tp_dealloc
@@ -175,6 +178,12 @@
Py_RETURN_NONE;
}
+static PyObject*
+MessageRenderer_clear(s_MessageRenderer* self) {
+ self->messagerenderer->clear();
+ Py_RETURN_NONE;
+}
+
// end of MessageRenderer
Modified: branches/trac232/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/name_python.cc (original)
+++ branches/trac232/src/lib/dns/python/name_python.cc Fri Oct 8 09:51:09 2010
@@ -68,7 +68,7 @@
static PyTypeObject name_comparison_result_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.NameComparisonResult",
+ "pydnspp.NameComparisonResult",
sizeof(s_NameComparisonResult), // tp_basicsize
0, // tp_itemsize
(destructor)NameComparisonResult_destroy, // tp_dealloc
@@ -222,7 +222,7 @@
static PyTypeObject name_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Name",
+ "pydnspp.Name",
sizeof(s_Name), // tp_basicsize
0, // tp_itemsize
(destructor)Name_destroy, // tp_dealloc
@@ -421,7 +421,7 @@
// to prevent memory leak
Py_DECREF(name_bytes);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->name->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -437,7 +437,7 @@
Name_compare(s_Name* self, PyObject* args) {
s_Name* other;
- if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+ if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
return (NULL);
s_NameComparisonResult* ret = PyObject_New(s_NameComparisonResult, &name_comparison_result_type);
@@ -452,7 +452,7 @@
Name_equals(s_Name* self, PyObject* args) {
s_Name* other;
- if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject* *) &other))
+ if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
return (NULL);
if (self->name->equals(*other->name))
@@ -565,7 +565,7 @@
Name_concatenate(s_Name* self, PyObject* args) {
s_Name* other;
- if (!PyArg_ParseTuple(args, "O!", &name_type, (PyObject**) &other))
+ if (!PyArg_ParseTuple(args, "O!", &name_type, &other))
return (NULL);
s_Name* ret = PyObject_New(s_Name, &name_type);
@@ -651,30 +651,30 @@
// Add the exceptions to the module
- po_EmptyLabel = PyErr_NewException("libdns_python.EmptyLabel", NULL, NULL);
+ po_EmptyLabel = PyErr_NewException("pydnspp.EmptyLabel", NULL, NULL);
PyModule_AddObject(mod, "EmptyLabel", po_EmptyLabel);
- po_TooLongName = PyErr_NewException("libdns_python.TooLongName", NULL, NULL);
+ po_TooLongName = PyErr_NewException("pydnspp.TooLongName", NULL, NULL);
PyModule_AddObject(mod, "TooLongName", po_TooLongName);
- po_TooLongLabel = PyErr_NewException("libdns_python.TooLongLabel", NULL, NULL);
+ po_TooLongLabel = PyErr_NewException("pydnspp.TooLongLabel", NULL, NULL);
PyModule_AddObject(mod, "TooLongLabel", po_TooLongLabel);
- po_BadLabelType = PyErr_NewException("libdns_python.BadLabelType", NULL, NULL);
+ po_BadLabelType = PyErr_NewException("pydnspp.BadLabelType", NULL, NULL);
PyModule_AddObject(mod, "BadLabelType", po_BadLabelType);
- po_BadEscape = PyErr_NewException("libdns_python.BadEscape", NULL, NULL);
+ po_BadEscape = PyErr_NewException("pydnspp.BadEscape", NULL, NULL);
PyModule_AddObject(mod, "BadEscape", po_BadEscape);
- po_IncompleteName = PyErr_NewException("libdns_python.IncompleteName", NULL, NULL);
+ po_IncompleteName = PyErr_NewException("pydnspp.IncompleteName", NULL, NULL);
PyModule_AddObject(mod, "IncompleteName", po_IncompleteName);
- po_InvalidBufferPosition = PyErr_NewException("libdns_python.InvalidBufferPosition", NULL, NULL);
+ po_InvalidBufferPosition = PyErr_NewException("pydnspp.InvalidBufferPosition", NULL, NULL);
PyModule_AddObject(mod, "InvalidBufferPosition", po_InvalidBufferPosition);
// This one could have gone into the message_python.cc file, but is
// already needed here.
- po_DNSMessageFORMERR = PyErr_NewException("libdns_python.DNSMessageFORMERR", NULL, NULL);
+ po_DNSMessageFORMERR = PyErr_NewException("pydnspp.DNSMessageFORMERR", NULL, NULL);
PyModule_AddObject(mod, "DNSMessageFORMERR", po_DNSMessageFORMERR);
return (true);
Modified: branches/trac232/src/lib/dns/python/question_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/question_python.cc (original)
+++ branches/trac232/src/lib/dns/python/question_python.cc Fri Oct 8 09:51:09 2010
@@ -76,7 +76,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject question_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Question",
+ "pydnspp.Question",
sizeof(s_Question), // tp_basicsize
0, // tp_itemsize
(destructor)Question_destroy, // tp_dealloc
@@ -254,8 +254,7 @@
// to prevent memory leak
Py_DECREF(n);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type,
- reinterpret_cast<PyObject**>(&mr))) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->question->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
Modified: branches/trac232/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac232/src/lib/dns/python/rdata_python.cc Fri Oct 8 09:51:09 2010
@@ -92,7 +92,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject rdata_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.Rdata",
+ "pydnspp.Rdata",
sizeof(s_Rdata), // tp_basicsize
0, // tp_itemsize
(destructor)Rdata_destroy, // tp_dealloc
@@ -146,11 +146,20 @@
s_RRType* rrtype;
s_RRClass* rrclass;
const char* s;
-
+ const char* data;
+ Py_ssize_t len;
+
+ // Create from string
if (PyArg_ParseTuple(args, "O!O!s", &rrtype_type, &rrtype,
&rrclass_type, &rrclass,
&s)) {
self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass, s);
+ return (0);
+ } else if (PyArg_ParseTuple(args, "O!O!y#", &rrtype_type, &rrtype,
+ &rrclass_type, &rrclass, &data, &len)) {
+ InputBuffer input_buffer(data, len);
+ self->rdata = createRdata(*rrtype->rrtype, *rrclass->rrclass,
+ input_buffer, len);
return (0);
}
@@ -195,7 +204,7 @@
// to prevent memory leak
Py_DECREF(rd_bytes);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->rdata->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -267,13 +276,13 @@
reinterpret_cast<PyObject*>(&rdata_type));
// Add the exceptions to the class
- po_InvalidRdataLength = PyErr_NewException("libdns_python.InvalidRdataLength", NULL, NULL);
+ po_InvalidRdataLength = PyErr_NewException("pydnspp.InvalidRdataLength", NULL, NULL);
PyModule_AddObject(mod, "InvalidRdataLength", po_InvalidRdataLength);
- po_InvalidRdataText = PyErr_NewException("libdns_python.InvalidRdataText", NULL, NULL);
+ po_InvalidRdataText = PyErr_NewException("pydnspp.InvalidRdataText", NULL, NULL);
PyModule_AddObject(mod, "InvalidRdataText", po_InvalidRdataText);
- po_CharStringTooLong = PyErr_NewException("libdns_python.CharStringTooLong", NULL, NULL);
+ po_CharStringTooLong = PyErr_NewException("pydnspp.CharStringTooLong", NULL, NULL);
PyModule_AddObject(mod, "CharStringTooLong", po_CharStringTooLong);
Modified: branches/trac232/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac232/src/lib/dns/python/rrclass_python.cc Fri Oct 8 09:51:09 2010
@@ -100,7 +100,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject rrclass_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.RRClass",
+ "pydnspp.RRClass",
sizeof(s_RRClass), // tp_basicsize
0, // tp_itemsize
(destructor)RRClass_destroy, // tp_dealloc
@@ -236,7 +236,7 @@
// to prevent memory leak
Py_DECREF(n);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->rrclass->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -332,10 +332,10 @@
bool
initModulePart_RRClass(PyObject* mod) {
// Add the exceptions to the module
- po_InvalidRRClass = PyErr_NewException("libdns_python.InvalidRRClass", NULL, NULL);
+ po_InvalidRRClass = PyErr_NewException("pydnspp.InvalidRRClass", NULL, NULL);
Py_INCREF(po_InvalidRRClass);
PyModule_AddObject(mod, "InvalidRRClass", po_InvalidRRClass);
- po_IncompleteRRClass = PyErr_NewException("libdns_python.IncompleteRRClass", NULL, NULL);
+ po_IncompleteRRClass = PyErr_NewException("pydnspp.IncompleteRRClass", NULL, NULL);
Py_INCREF(po_IncompleteRRClass);
PyModule_AddObject(mod, "IncompleteRRClass", po_IncompleteRRClass);
Modified: branches/trac232/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac232/src/lib/dns/python/rrset_python.cc Fri Oct 8 09:51:09 2010
@@ -94,7 +94,7 @@
static PyTypeObject rrset_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.RRset",
+ "pydnspp.RRset",
sizeof(s_RRset), // tp_basicsize
0, // tp_itemsize
(destructor)RRset_destroy, // tp_dealloc
@@ -315,7 +315,7 @@
// to prevent memory leak
Py_DECREF(n);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->rrset->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -379,7 +379,7 @@
bool
initModulePart_RRset(PyObject* mod) {
// Add the exceptions to the module
- po_EmptyRRset = PyErr_NewException("libdns_python.EmptyRRset", NULL, NULL);
+ po_EmptyRRset = PyErr_NewException("pydnspp.EmptyRRset", NULL, NULL);
PyModule_AddObject(mod, "EmptyRRset", po_EmptyRRset);
// Add the enums to the module
Modified: branches/trac232/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/rrttl_python.cc (original)
+++ branches/trac232/src/lib/dns/python/rrttl_python.cc Fri Oct 8 09:51:09 2010
@@ -91,7 +91,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject rrttl_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.RRTTL",
+ "pydnspp.RRTTL",
sizeof(s_RRTTL), // tp_basicsize
0, // tp_itemsize
(destructor)RRTTL_destroy, // tp_dealloc
@@ -235,7 +235,7 @@
// to prevent memory leak
Py_DECREF(n);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->rrttl->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -296,9 +296,9 @@
bool
initModulePart_RRTTL(PyObject* mod) {
// Add the exceptions to the module
- po_InvalidRRTTL = PyErr_NewException("libdns_python.InvalidRRTTL", NULL, NULL);
+ po_InvalidRRTTL = PyErr_NewException("pydnspp.InvalidRRTTL", NULL, NULL);
PyModule_AddObject(mod, "InvalidRRTTL", po_InvalidRRTTL);
- po_IncompleteRRTTL = PyErr_NewException("libdns_python.IncompleteRRTTL", NULL, NULL);
+ po_IncompleteRRTTL = PyErr_NewException("pydnspp.IncompleteRRTTL", NULL, NULL);
PyModule_AddObject(mod, "IncompleteRRTTL", po_IncompleteRRTTL);
// We initialize the static description object with PyType_Ready(),
Modified: branches/trac232/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac232/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac232/src/lib/dns/python/rrtype_python.cc Fri Oct 8 09:51:09 2010
@@ -130,7 +130,7 @@
// Most of the functions are not actually implemented and NULL here.
static PyTypeObject rrtype_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "libdns_python.RRType",
+ "pydnspp.RRType",
sizeof(s_RRType), // tp_basicsize
0, // tp_itemsize
(destructor)RRType_destroy, // tp_dealloc
@@ -273,7 +273,7 @@
// to prevent memory leak
Py_DECREF(n);
return (result);
- } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, (PyObject**) &mr)) {
+ } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
self->rrtype->toWire(*mr->messagerenderer);
// If we return NULL it is seen as an error, so use this for
// None returns
@@ -446,9 +446,9 @@
bool
initModulePart_RRType(PyObject* mod) {
// Add the exceptions to the module
- po_InvalidRRType = PyErr_NewException("libdns_python.InvalidRRType", NULL, NULL);
+ po_InvalidRRType = PyErr_NewException("pydnspp.InvalidRRType", NULL, NULL);
PyModule_AddObject(mod, "InvalidRRType", po_InvalidRRType);
- po_IncompleteRRType = PyErr_NewException("libdns_python.IncompleteRRType", NULL, NULL);
+ po_IncompleteRRType = PyErr_NewException("pydnspp.IncompleteRRType", NULL, NULL);
PyModule_AddObject(mod, "IncompleteRRType", po_IncompleteRRType);
// We initialize the static description object with PyType_Ready(),
Modified: branches/trac232/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac232/src/lib/dns/python/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,7 +1,10 @@
-PYTESTS = message_python_test.py
+PYTESTS = edns_python_test.py
+PYTESTS += message_python_test.py
PYTESTS += messagerenderer_python_test.py
PYTESTS += name_python_test.py
PYTESTS += question_python_test.py
+PYTESTS += opcode_python_test.py
+PYTESTS += rcode_python_test.py
PYTESTS += rdata_python_test.py
PYTESTS += rrclass_python_test.py
PYTESTS += rrset_python_test.py
@@ -9,6 +12,7 @@
PYTESTS += rrtype_python_test.py
EXTRA_DIST = $(PYTESTS)
+EXTRA_DIST += testutil.py
# If necessary (rare cases), explicitly specify paths to dynamic libraries
# required by loadable python modules.
@@ -23,8 +27,8 @@
check-local:
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
- 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 \
+ env PYTHONPATH=$(abs_top_srcdir)/src/lib/dns/.libs:$(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:$(abs_top_builddir)/src/lib/dns/tests/testdata \
$(LIBRARY_PATH_PLACEHOLDER) \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac232/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/message_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,13 +14,13 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the message part of the libdns_python module
+# Tests for the message part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
-
+from pydnspp import *
+from testutil import *
class MessageFlagTest(unittest.TestCase):
def test_init(self):
@@ -34,163 +34,6 @@
self.assertEqual(0x0080, MessageFlag.RA().get_bit())
self.assertEqual(0x0020, MessageFlag.AD().get_bit())
self.assertEqual(0x0010, MessageFlag.CD().get_bit())
-
-class OpcodeTest(unittest.TestCase):
- def test_init(self):
- self.assertRaises(NotImplementedError, Opcode)
-
- def test_get_code(self):
- self.assertEqual(0, Opcode.QUERY().get_code())
- self.assertEqual(1, Opcode.IQUERY().get_code())
- self.assertEqual(2, Opcode.STATUS().get_code())
- self.assertEqual(3, Opcode.RESERVED3().get_code())
- self.assertEqual(4, Opcode.NOTIFY().get_code())
- self.assertEqual(5, Opcode.UPDATE().get_code())
- self.assertEqual(6, Opcode.RESERVED6().get_code())
- self.assertEqual(7, Opcode.RESERVED7().get_code())
- self.assertEqual(8, Opcode.RESERVED8().get_code())
- self.assertEqual(9, Opcode.RESERVED9().get_code())
- self.assertEqual(10, Opcode.RESERVED10().get_code())
- self.assertEqual(11, Opcode.RESERVED11().get_code())
- self.assertEqual(12, Opcode.RESERVED12().get_code())
- self.assertEqual(13, Opcode.RESERVED13().get_code())
- self.assertEqual(14, Opcode.RESERVED14().get_code())
- self.assertEqual(15, Opcode.RESERVED15().get_code())
-
- def test_to_text(self):
- self.assertEqual("QUERY", Opcode.QUERY().to_text())
- self.assertEqual("QUERY", str(Opcode.QUERY()))
- self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
- self.assertEqual("STATUS", Opcode.STATUS().to_text())
- self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
- self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
- self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
- self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
- self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
- self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
- self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
- self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
- self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
- self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
- self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
- self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
- self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
-
- def test_richcmp(self):
- o1 = Opcode.QUERY()
- o2 = Opcode.NOTIFY()
- o3 = Opcode.NOTIFY()
- self.assertTrue(o2 == o3)
- self.assertFalse(o2 != o3)
- self.assertTrue(o1 != o2)
- self.assertFalse(o1 == 1)
- self.assertFalse(o1 == o2)
- # can't use assertRaises here...
- try:
- o1 < o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 <= o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 > o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- o1 >= o2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
-
-class RcodeTest(unittest.TestCase):
- def test_init(self):
- self.assertRaises(TypeError, Rcode, "wrong")
- self.assertRaises(OverflowError, Rcode, 65536)
- self.assertEqual(Rcode(0).get_code(), 0)
-
- self.assertEqual(0, Rcode(0).get_code())
- self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-
- # should fail on attempt of construction with an out of range code
- self.assertRaises(OverflowError, Rcode, 0x1000)
- self.assertRaises(OverflowError, Rcode, 0xffff)
-
- def test_get_code(self):
- self.assertEqual(0, Rcode.NOERROR().get_code())
- self.assertEqual(1, Rcode.FORMERR().get_code())
- self.assertEqual(2, Rcode.SERVFAIL().get_code())
- self.assertEqual(3, Rcode.NXDOMAIN().get_code())
- self.assertEqual(4, Rcode.NOTIMP().get_code())
- self.assertEqual(5, Rcode.REFUSED().get_code())
- self.assertEqual(6, Rcode.YXDOMAIN().get_code())
- self.assertEqual(7, Rcode.YXRRSET().get_code())
- self.assertEqual(8, Rcode.NXRRSET().get_code())
- self.assertEqual(9, Rcode.NOTAUTH().get_code())
- self.assertEqual(10, Rcode.NOTZONE().get_code())
- self.assertEqual(11, Rcode.RESERVED11().get_code())
- self.assertEqual(12, Rcode.RESERVED12().get_code())
- self.assertEqual(13, Rcode.RESERVED13().get_code())
- self.assertEqual(14, Rcode.RESERVED14().get_code())
- self.assertEqual(15, Rcode.RESERVED15().get_code())
- self.assertEqual(16, Rcode.BADVERS().get_code())
-
- def test_to_text(self):
- self.assertEqual("NOERROR", Rcode(0).to_text())
- self.assertEqual("NOERROR", str(Rcode(0)))
- self.assertEqual("FORMERR", Rcode(1).to_text())
- self.assertEqual("SERVFAIL", Rcode(2).to_text())
- self.assertEqual("NXDOMAIN", Rcode(3).to_text())
- self.assertEqual("NOTIMP", Rcode(4).to_text())
- self.assertEqual("REFUSED", Rcode(5).to_text())
- self.assertEqual("YXDOMAIN", Rcode(6).to_text())
- self.assertEqual("YXRRSET", Rcode(7).to_text())
- self.assertEqual("NXRRSET", Rcode(8).to_text())
- self.assertEqual("NOTAUTH", Rcode(9).to_text())
- self.assertEqual("NOTZONE", Rcode(10).to_text())
- self.assertEqual("RESERVED11", Rcode(11).to_text())
- self.assertEqual("RESERVED12", Rcode(12).to_text())
- self.assertEqual("RESERVED13", Rcode(13).to_text())
- self.assertEqual("RESERVED14", Rcode(14).to_text())
- self.assertEqual("RESERVED15", Rcode(15).to_text())
- self.assertEqual("BADVERS", Rcode(16).to_text())
-
- self.assertEqual("17", Rcode(Rcode.BADVERS().get_code() + 1).to_text())
- self.assertEqual("4095", Rcode(0xfff).to_text())
-
- def test_richcmp(self):
- r1 = Rcode.NOERROR()
- r2 = Rcode.FORMERR()
- r3 = Rcode.FORMERR()
- self.assertTrue(r2 == r3)
- self.assertTrue(r1 != r2)
- self.assertFalse(r1 == r2)
- self.assertFalse(r1 != 1)
- # can't use assertRaises here...
- try:
- r1 < r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 <= r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 > r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
- try:
- r1 >= r2
- self.fail("operation that should have raised an error unexpectedly succeeded")
- except Exception as err:
- self.assertEqual(TypeError, type(err))
class SectionTest(unittest.TestCase):
@@ -240,19 +83,6 @@
else:
testdata_path = "../tests/testdata"
-def read_wire_data(filename):
- data = bytes()
- file = open(testdata_path + os.sep + filename, "r")
- for line in file:
- line = line.strip()
- if line == "" or line.startswith("#"):
- pass
- else:
- cur_data = bytes.fromhex(line)
- data += cur_data
-
- return data
-
def factoryFromFile(message, file):
data = read_wire_data(file)
message.from_wire(data)
@@ -316,28 +146,6 @@
self.assertRaises(InvalidMessageOperation,
self.p.clear_header_flag, MessageFlag.AA())
- def test_set_DNSSEC_supported(self):
- self.assertRaises(TypeError, self.r.set_dnssec_supported, "wrong")
-
- self.assertFalse(self.r.is_dnssec_supported())
- self.r.set_dnssec_supported(True)
- self.assertTrue(self.r.is_dnssec_supported())
- self.r.set_dnssec_supported(False)
- self.assertFalse(self.r.is_dnssec_supported())
-
- self.assertRaises(InvalidMessageOperation,
- self.p.set_dnssec_supported, True)
- self.assertRaises(InvalidMessageOperation,
- self.p.set_dnssec_supported, False)
-
- def test_set_udp_size(self):
- self.assertRaises(TypeError, self.r.set_udp_size, "wrong")
- self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 0)
- self.assertRaises(InvalidMessageUDPSize, self.r.set_udp_size, 65536)
- self.assertRaises(InvalidMessageOperation, self.p.set_udp_size, 1024)
- self.r.set_udp_size(2048)
- self.assertEqual(2048, self.r.get_udp_size())
-
def test_set_qid(self):
self.assertRaises(TypeError, self.r.set_qid, "wrong")
self.assertRaises(InvalidMessageOperation,
@@ -355,6 +163,7 @@
self.assertRaises(InvalidMessageOperation,
self.p.set_rcode, rcode)
+ self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
def test_set_opcode(self):
self.assertRaises(TypeError, self.r.set_opcode, "wrong")
@@ -365,6 +174,26 @@
self.assertRaises(InvalidMessageOperation,
self.p.set_opcode, opcode)
+
+ self.assertRaises(InvalidMessageOperation, self.p.get_opcode)
+
+ def test_get_edns(self):
+ self.assertEqual(None, self.p.get_edns())
+
+ message_parse = Message(Message.PARSE)
+ factoryFromFile(message_parse, "message_fromWire10.wire")
+ edns = message_parse.get_edns()
+ self.assertEqual(0, edns.get_version())
+ self.assertEqual(4096, edns.get_udp_size())
+ self.assertTrue(edns.get_dnssec_awareness())
+
+ def test_set_edns(self):
+ self.assertRaises(InvalidMessageOperation, self.p.set_edns, EDNS())
+
+ edns = EDNS()
+ edns.set_udp_size(1024)
+ self.r.set_edns(edns)
+ self.assertEqual(1024, self.r.get_edns().get_udp_size())
def test_get_section(self):
self.assertRaises(TypeError, self.r.get_section, "wrong")
@@ -430,6 +259,16 @@
self.assertEqual(b'\x105\x85\x00\x00\x01\x00\x02\x00\x00\x00\x00\x04test\x07example\x03com\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x01\xc0\x0c\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x04\xc0\x00\x02\x02',
renderer.get_data())
+ def test_to_wire_without_opcode(self):
+ self.r.set_rcode(Rcode.NOERROR())
+ self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+ MessageRenderer())
+
+ def test_to_wire_without_rcode(self):
+ self.r.set_opcode(Opcode.QUERY())
+ self.assertRaises(InvalidMessageOperation, self.r.to_wire,
+ MessageRenderer())
+
def test_to_text(self):
message_render = create_message()
@@ -446,6 +285,14 @@
"""
self.assertEqual(msg_str, message_render.to_text())
self.assertEqual(msg_str, str(message_render))
+
+ def test_to_text_without_opcode(self):
+ self.r.set_rcode(Rcode.NOERROR())
+ self.assertRaises(InvalidMessageOperation, self.r.to_text)
+
+ def test_to_text_without_rcode(self):
+ self.r.set_opcode(Opcode.QUERY())
+ self.assertRaises(InvalidMessageOperation, self.r.to_text)
def test_from_wire(self):
self.assertRaises(TypeError, self.r.from_wire, 1)
@@ -487,93 +334,15 @@
self.assertEqual("192.0.2.2", rdata[1].to_text())
self.assertEqual(2, len(rdata))
- def test_GetEDNS0DOBit(self):
- message_parse = Message(Message.PARSE)
- ## Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message_parse, "message_fromWire1")
- self.assertFalse(message_parse.is_dnssec_supported())
-
- ## If DO bit is on, DNSSEC is considered to be supported.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire2")
- self.assertTrue(message_parse.is_dnssec_supported())
-
- ## If DO bit is off, DNSSEC is considered to be unsupported.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire3")
- self.assertFalse(message_parse.is_dnssec_supported())
-
- def test_SetEDNS0DOBit(self):
- # By default, it's false, and we can enable/disable it.
- message_parse = Message(Message.PARSE)
- message_render = Message(Message.RENDER)
- self.assertFalse(message_render.is_dnssec_supported())
- message_render.set_dnssec_supported(True)
- self.assertTrue(message_render.is_dnssec_supported())
- message_render.set_dnssec_supported(False)
- self.assertFalse(message_render.is_dnssec_supported())
-
- ## A message in the parse mode doesn't allow this flag to be set.
- self.assertRaises(InvalidMessageOperation,
- message_parse.set_dnssec_supported,
- True)
- ## Once converted to the render mode, it works as above
- message_parse.make_response()
- self.assertFalse(message_parse.is_dnssec_supported())
- message_parse.set_dnssec_supported(True)
- self.assertTrue(message_parse.is_dnssec_supported())
- message_parse.set_dnssec_supported(False)
- self.assertFalse(message_parse.is_dnssec_supported())
-
- def test_GetEDNS0UDPSize(self):
- # Without EDNS0, the default max UDP size is used.
- message_parse = Message(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire1")
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-
- ## If the size specified in EDNS0 > default max, use it.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire2")
- self.assertEqual(4096, message_parse.get_udp_size())
-
- ## If the size specified in EDNS0 < default max, keep using the default.
- message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire8")
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_parse.get_udp_size())
-
- def test_SetEDNS0UDPSize(self):
- # The default size if unspecified
- message_render = Message(Message.RENDER)
- message_parse = Message(Message.PARSE)
- self.assertEqual(Message.DEFAULT_MAX_UDPSIZE, message_render.get_udp_size())
- # A common buffer size with EDNS, should succeed
- message_render.set_udp_size(4096)
- self.assertEqual(4096, message_render.get_udp_size())
- # Unusual large value, but accepted
- message_render.set_udp_size(0xffff)
- self.assertEqual(0xffff, message_render.get_udp_size())
- # Too small is value is rejected
- self.assertRaises(InvalidMessageUDPSize, message_render.set_udp_size, 511)
-
- # A message in the parse mode doesn't allow the set operation.
- self.assertRaises(InvalidMessageOperation, message_parse.set_udp_size, 4096)
- ## Once converted to the render mode, it works as above.
- message_parse.make_response()
- message_parse.set_udp_size(4096)
- self.assertEqual(4096, message_parse.get_udp_size())
- message_parse.set_udp_size(0xffff)
- self.assertEqual(0xffff, message_parse.get_udp_size())
- self.assertRaises(InvalidMessageUDPSize, message_parse.set_udp_size, 511)
-
def test_EDNS0ExtCode(self):
# Extended Rcode = BADVERS
message_parse = Message(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire10")
+ factoryFromFile(message_parse, "message_fromWire10.wire")
self.assertEqual(Rcode.BADVERS(), message_parse.get_rcode())
# Maximum extended Rcode
message_parse.clear(Message.PARSE)
- factoryFromFile(message_parse, "message_fromWire11")
+ factoryFromFile(message_parse, "message_fromWire11.wire")
self.assertEqual(0xfff, message_parse.get_rcode().get_code())
def test_BadEDNS0(self):
Modified: branches/trac232/src/lib/dns/python/tests/messagerenderer_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/messagerenderer_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/messagerenderer_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the messagerenderer part of the libdns_python module
+# Tests for the messagerenderer part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class MessageRendererTest(unittest.TestCase):
@@ -32,6 +32,7 @@
message = Message(Message.RENDER)
message.set_qid(123)
message.set_opcode(Opcode.QUERY())
+ message.set_rcode(Rcode.NOERROR())
message.add_question(Question(name, c, t))
self.message1 = message
Modified: branches/trac232/src/lib/dns/python/tests/name_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/name_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/name_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the messagerenderer part of the libdns_python module
+# Tests for the messagerenderer part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class NameComparisonTest(unittest.TestCase):
def setUp(self):
Modified: branches/trac232/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/question_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,30 +14,18 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
+from testutil import *
if "TESTDATA_PATH" in os.environ:
testdata_path = os.environ["TESTDATA_PATH"]
else:
testdata_path = "../tests/testdata"
-
-def read_wire_data(filename):
- data = bytes()
- file = open(testdata_path + os.sep + filename, "r")
- for line in file:
- line = line.strip()
- if line == "" or line.startswith("#"):
- pass
- else:
- cur_data = bytes.fromhex(line)
- data += cur_data
-
- return data
def question_from_wire(file, position = 0):
data = read_wire_data(file)
@@ -102,7 +90,6 @@
wiredata = read_wire_data("question_toWire2")
self.assertEqual(renderer.get_data(), wiredata)
self.assertRaises(TypeError, self.test_question1.to_wire, 1)
-
if __name__ == '__main__':
unittest.main()
Modified: branches/trac232/src/lib/dns/python/tests/rdata_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/rdata_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/rdata_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rdata part of the libdns_python module
+# Tests for the rdata part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class RdataTest(unittest.TestCase):
def setUp(self):
Modified: branches/trac232/src/lib/dns/python/tests/rrclass_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/rrclass_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/rrclass_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rrclass part of the libdns_python module
+# Tests for the rrclass part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class RRClassTest(unittest.TestCase):
def setUp(self):
Modified: branches/trac232/src/lib/dns/python/tests/rrset_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/rrset_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/rrset_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class TestModuleSpec(unittest.TestCase):
Modified: branches/trac232/src/lib/dns/python/tests/rrttl_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/rrttl_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/rrttl_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rrttl part of the libdns_python module
+# Tests for the rrttl part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class RRTTLTest(unittest.TestCase):
def setUp(self):
Modified: branches/trac232/src/lib/dns/python/tests/rrtype_python_test.py
==============================================================================
--- branches/trac232/src/lib/dns/python/tests/rrtype_python_test.py (original)
+++ branches/trac232/src/lib/dns/python/tests/rrtype_python_test.py Fri Oct 8 09:51:09 2010
@@ -14,12 +14,12 @@
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
-# Tests for the rrtype part of the libdns_python module
+# Tests for the rrtype part of the pydnspp module
#
import unittest
import os
-from libdns_python import *
+from pydnspp import *
class TestModuleSpec(unittest.TestCase):
Modified: branches/trac232/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac232/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac232/src/lib/dns/rrclass-placeholder.h Fri Oct 8 09:51:09 2010
@@ -211,7 +211,7 @@
/// \brief Same as \c equals().
bool operator==(const RRClass& other) const { return (equals(other)); }
- /// \brief Return true iff two RRClasses are equal.
+ /// \brief Return true iff two RRClasses are not equal.
///
/// This method never throws an exception.
///
Modified: branches/trac232/src/lib/dns/rrset.h
==============================================================================
--- branches/trac232/src/lib/dns/rrset.h (original)
+++ branches/trac232/src/lib/dns/rrset.h Fri Oct 8 09:51:09 2010
@@ -692,8 +692,8 @@
/// \brief Adds an RRSIG RR to this RRset's signatures
virtual void addRRsig(const rdata::RdataPtr rdata) {
if (!rrsig_) {
- rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
- RRType::RRSIG(), this->getTTL()));
+ rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+ RRType::RRSIG(), getTTL()));
}
rrsig_->addRdata(rdata);
}
@@ -703,8 +703,8 @@
RdataIteratorPtr it = sigs.getRdataIterator();
if (!rrsig_) {
- rrsig_ = RRsetPtr(new RRset(this->getName(), this->getClass(),
- RRType::RRSIG(), this->getTTL()));
+ rrsig_ = RRsetPtr(new RRset(getName(), getClass(),
+ RRType::RRSIG(), getTTL()));
}
for (it->first(); !it->isLast(); it->next()) {
Modified: branches/trac232/src/lib/dns/rrtype-placeholder.h
==============================================================================
--- branches/trac232/src/lib/dns/rrtype-placeholder.h (original)
+++ branches/trac232/src/lib/dns/rrtype-placeholder.h Fri Oct 8 09:51:09 2010
@@ -223,7 +223,7 @@
/// \brief Same as \c equals().
bool operator==(const RRType& other) const { return (equals(other)); }
- /// \brief Return true iff two RRTypes are equal.
+ /// \brief Return true iff two RRTypes are not equal.
///
/// This method never throws an exception.
///
Modified: branches/trac232/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac232/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac232/src/lib/dns/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,6 +1,9 @@
+SUBDIRS = testdata .
+
AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(srcdir)/testdata\"
+AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(top_builddir)/src/lib/dns/tests/testdata\"
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_STATIC_LINK
@@ -14,10 +17,13 @@
TESTS += run_unittests
run_unittests_SOURCES = unittest_util.h unittest_util.cc
run_unittests_SOURCES += buffer_unittest.cc name_unittest.cc
+run_unittests_SOURCES += edns_unittest.cc
run_unittests_SOURCES += messagerenderer_unittest.cc
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
run_unittests_SOURCES += rrttl_unittest.cc
run_unittests_SOURCES += dnssectime_unittest.cc
+run_unittests_SOURCES += opcode_unittest.cc
+run_unittests_SOURCES += rcode_unittest.cc
run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc
run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc
run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc
@@ -49,99 +55,3 @@
endif
noinst_PROGRAMS = $(TESTS)
-
-# NOTE: keep this in sync with real file listing
-# so is included in tarball
-EXTRA_DIST = testdata/gen-wiredata.py.in
-EXTRA_DIST += testdata/message_fromWire1
-EXTRA_DIST += testdata/message_fromWire10
-EXTRA_DIST += testdata/message_fromWire10.spec
-EXTRA_DIST += testdata/message_fromWire11
-EXTRA_DIST += testdata/message_fromWire11.spec
-EXTRA_DIST += testdata/message_fromWire2
-EXTRA_DIST += testdata/message_fromWire3
-EXTRA_DIST += testdata/message_fromWire4
-EXTRA_DIST += testdata/message_fromWire5
-EXTRA_DIST += testdata/message_fromWire6
-EXTRA_DIST += testdata/message_fromWire7
-EXTRA_DIST += testdata/message_fromWire8
-EXTRA_DIST += testdata/message_fromWire9
-EXTRA_DIST += testdata/message_toWire1
-EXTRA_DIST += testdata/name_fromWire1
-EXTRA_DIST += testdata/name_fromWire10
-EXTRA_DIST += testdata/name_fromWire11
-EXTRA_DIST += testdata/name_fromWire12
-EXTRA_DIST += testdata/name_fromWire13
-EXTRA_DIST += testdata/name_fromWire14
-EXTRA_DIST += testdata/name_fromWire2
-EXTRA_DIST += testdata/name_fromWire3_1
-EXTRA_DIST += testdata/name_fromWire3_2
-EXTRA_DIST += testdata/name_fromWire4
-EXTRA_DIST += testdata/name_fromWire6
-EXTRA_DIST += testdata/name_fromWire7
-EXTRA_DIST += testdata/name_fromWire8
-EXTRA_DIST += testdata/name_fromWire9
-EXTRA_DIST += testdata/name_toWire1
-EXTRA_DIST += testdata/name_toWire2
-EXTRA_DIST += testdata/name_toWire3
-EXTRA_DIST += testdata/name_toWire4
-EXTRA_DIST += testdata/name_toWire5
-EXTRA_DIST += testdata/name_toWire5.spec
-EXTRA_DIST += testdata/name_toWire6
-EXTRA_DIST += testdata/name_toWire6.spec
-EXTRA_DIST += testdata/question_fromWire
-EXTRA_DIST += testdata/question_toWire1
-EXTRA_DIST += testdata/question_toWire2
-EXTRA_DIST += testdata/rdata_cname_fromWire
-EXTRA_DIST += testdata/rdata_dname_fromWire
-EXTRA_DIST += testdata/rdata_dnskey_fromWire
-EXTRA_DIST += testdata/rdata_ds_fromWire
-EXTRA_DIST += testdata/rdata_in_a_fromWire
-EXTRA_DIST += testdata/rdata_in_aaaa_fromWire
-EXTRA_DIST += testdata/rdata_mx_fromWire
-EXTRA_DIST += testdata/rdata_mx_toWire1
-EXTRA_DIST += testdata/rdata_ns_fromWire
-EXTRA_DIST += testdata/rdata_nsec3_fromWire1
-EXTRA_DIST += testdata/rdata_nsec3_fromWire2
-EXTRA_DIST += testdata/rdata_nsec3_fromWire3
-EXTRA_DIST += testdata/rdata_nsec3param_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire1
-EXTRA_DIST += testdata/rdata_nsec_fromWire10
-EXTRA_DIST += testdata/rdata_nsec_fromWire10.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire2
-EXTRA_DIST += testdata/rdata_nsec_fromWire3
-EXTRA_DIST += testdata/rdata_nsec_fromWire4
-EXTRA_DIST += testdata/rdata_nsec_fromWire4.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire5
-EXTRA_DIST += testdata/rdata_nsec_fromWire5.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire6
-EXTRA_DIST += testdata/rdata_nsec_fromWire6.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire7
-EXTRA_DIST += testdata/rdata_nsec_fromWire7.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire8
-EXTRA_DIST += testdata/rdata_nsec_fromWire8.spec
-EXTRA_DIST += testdata/rdata_nsec_fromWire9
-EXTRA_DIST += testdata/rdata_nsec_fromWire9.spec
-EXTRA_DIST += testdata/rdata_opt_fromWire
-EXTRA_DIST += testdata/rdata_rrsig_fromWire1
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2
-EXTRA_DIST += testdata/rdata_rrsig_fromWire2.spec
-EXTRA_DIST += testdata/rdata_soa_fromWire
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed
-EXTRA_DIST += testdata/rdata_soa_toWireUncompressed.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire1
-EXTRA_DIST += testdata/rdata_txt_fromWire2
-EXTRA_DIST += testdata/rdata_txt_fromWire2.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire3
-EXTRA_DIST += testdata/rdata_txt_fromWire3.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire4
-EXTRA_DIST += testdata/rdata_txt_fromWire4.spec
-EXTRA_DIST += testdata/rdata_txt_fromWire5
-EXTRA_DIST += testdata/rdata_txt_fromWire5.spec
-EXTRA_DIST += testdata/rdata_unknown_fromWire
-EXTRA_DIST += testdata/rrcode16_fromWire1
-EXTRA_DIST += testdata/rrcode16_fromWire2
-EXTRA_DIST += testdata/rrcode32_fromWire1
-EXTRA_DIST += testdata/rrcode32_fromWire2
-EXTRA_DIST += testdata/rrset_toWire1
-EXTRA_DIST += testdata/rrset_toWire2
Modified: branches/trac232/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/message_unittest.cc Fri Oct 8 09:51:09 2010
@@ -17,10 +17,13 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
#include <dns/question.h>
+#include <dns/opcode.h>
+#include <dns/rcode.h>
#include <dns/rdataclass.h>
#include <dns/rrclass.h>
#include <dns/rrttl.h>
@@ -76,23 +79,25 @@
message.fromWire(buffer);
}
-TEST_F(MessageTest, RcodeConstruct) {
- // normal cases
- EXPECT_EQ(0, Rcode(0).getCode());
- EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code
-
- // should fail on attempt of construction with an out of range code
- EXPECT_THROW(Rcode(0x1000), isc::OutOfRange);
- EXPECT_THROW(Rcode(0xffff), isc::OutOfRange);
-}
-
-TEST_F(MessageTest, RcodeToText) {
- EXPECT_EQ("NOERROR", Rcode::NOERROR().toText());
- EXPECT_EQ("BADVERS", Rcode::BADVERS().toText());
- EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText());
- EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText());
-}
-
+TEST_F(MessageTest, getEDNS) {
+ EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set
+
+ factoryFromFile(message_parse, "message_fromWire10.wire");
+ EXPECT_TRUE(message_parse.getEDNS());
+ EXPECT_EQ(0, message_parse.getEDNS()->getVersion());
+ EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize());
+ EXPECT_TRUE(message_parse.getEDNS()->getDNSSECAwareness());
+}
+
+TEST_F(MessageTest, setEDNS) {
+ // setEDNS() isn't allowed in the parse mode
+ EXPECT_THROW(message_parse.setEDNS(EDNSPtr(new EDNS())),
+ InvalidMessageOperation);
+
+ EDNSPtr edns = EDNSPtr(new EDNS());
+ message_render.setEDNS(edns);
+ EXPECT_EQ(edns, message_render.getEDNS());
+}
TEST_F(MessageTest, fromWire) {
factoryFromFile(message_parse, "message_fromWire1");
@@ -127,89 +132,14 @@
EXPECT_TRUE(it->isLast());
}
-TEST_F(MessageTest, GetEDNS0DOBit) {
- // Without EDNS0, DNSSEC is considered to be unsupported.
- factoryFromFile(message_parse, "message_fromWire1");
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-
- // If DO bit is on, DNSSEC is considered to be supported.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire2");
- EXPECT_TRUE(message_parse.isDNSSECSupported());
-
- // If DO bit is off, DNSSEC is considered to be unsupported.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire3");
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, SetEDNS0DOBit) {
- // By default, it's false, and we can enable/disable it.
- EXPECT_FALSE(message_render.isDNSSECSupported());
- message_render.setDNSSECSupported(true);
- EXPECT_TRUE(message_render.isDNSSECSupported());
- message_render.setDNSSECSupported(false);
- EXPECT_FALSE(message_render.isDNSSECSupported());
-
- // A message in the parse mode doesn't allow this flag to be set.
- EXPECT_THROW(message_parse.setDNSSECSupported(true),
- InvalidMessageOperation);
- // Once converted to the render mode, it works as above
- message_parse.makeResponse();
- EXPECT_FALSE(message_parse.isDNSSECSupported());
- message_parse.setDNSSECSupported(true);
- EXPECT_TRUE(message_parse.isDNSSECSupported());
- message_parse.setDNSSECSupported(false);
- EXPECT_FALSE(message_parse.isDNSSECSupported());
-}
-
-TEST_F(MessageTest, GetEDNS0UDPSize) {
- // Without EDNS0, the default max UDP size is used.
- factoryFromFile(message_parse, "message_fromWire1");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-
- // If the size specified in EDNS0 > default max, use it.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire2");
- EXPECT_EQ(4096, message_parse.getUDPSize());
-
- // If the size specified in EDNS0 < default max, keep using the default.
- message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire8");
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_parse.getUDPSize());
-}
-
-TEST_F(MessageTest, SetEDNS0UDPSize) {
- // The default size if unspecified
- EXPECT_EQ(Message::DEFAULT_MAX_UDPSIZE, message_render.getUDPSize());
- // A common buffer size with EDNS, should succeed
- message_render.setUDPSize(4096);
- EXPECT_EQ(4096, message_render.getUDPSize());
- // Unusual large value, but accepted
- message_render.setUDPSize(0xffff);
- EXPECT_EQ(0xffff, message_render.getUDPSize());
- // Too small is value is rejected
- EXPECT_THROW(message_render.setUDPSize(511), InvalidMessageUDPSize);
-
- // A message in the parse mode doesn't allow the set operation.
- EXPECT_THROW(message_parse.setUDPSize(4096), InvalidMessageOperation);
- // Once converted to the render mode, it works as above.
- message_parse.makeResponse();
- message_parse.setUDPSize(4096);
- EXPECT_EQ(4096, message_parse.getUDPSize());
- message_parse.setUDPSize(0xffff);
- EXPECT_EQ(0xffff, message_parse.getUDPSize());
- EXPECT_THROW(message_parse.setUDPSize(511), InvalidMessageUDPSize);
-}
-
-TEST_F(MessageTest, EDNS0ExtCode) {
+TEST_F(MessageTest, EDNS0ExtRcode) {
// Extended Rcode = BADVERS
- factoryFromFile(message_parse, "message_fromWire10");
+ factoryFromFile(message_parse, "message_fromWire10.wire");
EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
// Maximum extended Rcode
message_parse.clear(Message::PARSE);
- factoryFromFile(message_parse, "message_fromWire11");
+ factoryFromFile(message_parse, "message_fromWire11.wire");
EXPECT_EQ(0xfff, message_parse.getRcode().getCode());
}
@@ -221,19 +151,6 @@
message_parse.clear(Message::PARSE);
EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"),
DNSMessageFORMERR);
- // OPT RR of a non root name
- message_parse.clear(Message::PARSE);
- EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire6"),
- DNSMessageFORMERR);
- // Compressed owner name of OPT RR points to a root name.
- // Not necessarily bogus, but very unusual and mostly pathological.
- // We accept it, but is it okay?
- message_parse.clear(Message::PARSE);
- EXPECT_NO_THROW(factoryFromFile(message_parse, "message_fromWire7"));
- // Unsupported Version
- message_parse.clear(Message::PARSE);
- EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire9"),
- DNSMessageBADVERS);
}
TEST_F(MessageTest, toWire) {
@@ -262,4 +179,29 @@
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, obuffer.getData(),
obuffer.getLength(), &data[0], data.size());
}
-}
+
+TEST_F(MessageTest, toWireInParseMode) {
+ // toWire() isn't allowed in the parse mode.
+ EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutOpcode) {
+ message_render.setRcode(Rcode::NOERROR());
+ EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toWireWithoutRcode) {
+ message_render.setOpcode(Opcode::QUERY());
+ EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutOpcode) {
+ message_render.setRcode(Rcode::NOERROR());
+ EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+
+TEST_F(MessageTest, toTextWithoutRcode) {
+ message_render.setOpcode(Opcode::QUERY());
+ EXPECT_THROW(message_render.toText(), InvalidMessageOperation);
+}
+}
Modified: branches/trac232/src/lib/dns/tests/messagerenderer_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/messagerenderer_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/messagerenderer_unittest.cc Fri Oct 8 09:51:09 2010
@@ -130,7 +130,7 @@
// name compression in case sensitive manner. See the data file
// description for details.
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire5", data);
+ UnitTestUtil::readWireData("name_toWire5.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
renderer.writeName(Name("c.eXample.com."));
@@ -140,7 +140,7 @@
TEST_F(MessageRendererTest, writeNameMixedCaseCompress) {
renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE);
- UnitTestUtil::readWireData("name_toWire6", data);
+ UnitTestUtil::readWireData("name_toWire6.wire", data);
renderer.writeName(Name("a.example.com."));
renderer.writeName(Name("b.eXample.com."));
Modified: branches/trac232/src/lib/dns/tests/rdata_nsec_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/rdata_nsec_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/rdata_nsec_unittest.cc Fri Oct 8 09:51:09 2010
@@ -70,39 +70,39 @@
// A malformed NSEC bitmap length field that could cause overflow.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire4"),
+ "rdata_nsec_fromWire4.wire"),
DNSMessageFORMERR);
// The bitmap field is incomplete (only the first byte is included)
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire5"),
+ "rdata_nsec_fromWire5.wire"),
DNSMessageFORMERR);
// Bitmap length is 0, which is invalid.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire6"),
+ "rdata_nsec_fromWire6.wire"),
DNSMessageFORMERR);
// A boundary case: longest possible bitmaps (32 maps). This should be
// accepted.
EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire7"));
+ "rdata_nsec_fromWire7.wire"));
// Another boundary condition: 33 bitmaps, which should be rejected.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire8"),
+ "rdata_nsec_fromWire8.wire"),
DNSMessageFORMERR);
// Disordered bitmap window blocks.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire9"),
+ "rdata_nsec_fromWire9.wire"),
DNSMessageFORMERR);
// Bitmap ending with all-zero bytes. Not necessarily harmful except
// the additional overhead of parsing, but invalid according to the
// spec anyway.
EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(),
- "rdata_nsec_fromWire10"),
+ "rdata_nsec_fromWire10.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac232/src/lib/dns/tests/rdata_rrsig_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/rdata_rrsig_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/rdata_rrsig_unittest.cc Fri Oct 8 09:51:09 2010
@@ -131,7 +131,7 @@
// RDLEN is too short
EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(),
- "rdata_rrsig_fromWire2"),
+ "rdata_rrsig_fromWire2.wire"),
InvalidRdataLength);
}
}
Modified: branches/trac232/src/lib/dns/tests/rdata_soa_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/rdata_soa_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/rdata_soa_unittest.cc Fri Oct 8 09:51:09 2010
@@ -65,7 +65,7 @@
obuffer.skip(2);
rdata_soa.toWire(obuffer);
vector<unsigned char> data;
- UnitTestUtil::readWireData("rdata_soa_toWireUncompressed", data);
+ UnitTestUtil::readWireData("rdata_soa_toWireUncompressed.wire", data);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
static_cast<const uint8_t *>(obuffer.getData()) + 2,
obuffer.getLength() - 2, &data[2], data.size() - 2);
Modified: branches/trac232/src/lib/dns/tests/rdata_txt_unittest.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/rdata_txt_unittest.cc (original)
+++ branches/trac232/src/lib/dns/tests/rdata_txt_unittest.cc Fri Oct 8 09:51:09 2010
@@ -109,12 +109,12 @@
// Empty character string
EXPECT_EQ(0, rdata_txt_empty.compare(
*rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire2")));
+ "rdata_txt_fromWire2.wire")));
// Multiple character strings
obuffer.clear();
rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire3")->toWire(obuffer);
+ "rdata_txt_fromWire3.wire")->toWire(obuffer);
// the result should be 'wiredata_txt' repeated twice
vector<uint8_t> expected_data(wiredata_txt, wiredata_txt +
sizeof(wiredata_txt));
@@ -145,12 +145,12 @@
// RDATA is empty, which is invalid for TXT.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire4"),
+ "rdata_txt_fromWire4.wire"),
DNSMessageFORMERR);
// character-string length is too large, which could cause overrun.
EXPECT_THROW(rdataFactoryFromFile(RRType("TXT"), RRClass("IN"),
- "rdata_txt_fromWire5"),
+ "rdata_txt_fromWire5.wire"),
DNSMessageFORMERR);
}
Modified: branches/trac232/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac232/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac232/src/lib/dns/tests/run_unittests.cc Fri Oct 8 09:51:09 2010
@@ -21,7 +21,8 @@
int
main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
- isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR);
+ isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR);
return (RUN_ALL_TESTS());
}
Modified: branches/trac232/src/lib/dns/tests/testdata/gen-wiredata.py.in
==============================================================================
--- branches/trac232/src/lib/dns/tests/testdata/gen-wiredata.py.in (original)
+++ branches/trac232/src/lib/dns/tests/testdata/gen-wiredata.py.in Fri Oct 8 09:51:09 2010
@@ -19,9 +19,9 @@
from datetime import datetime
from optparse import OptionParser
-re_hex = re.compile('0x[0-9a-fA-F]+')
-re_decimal = re.compile('\d+$')
-re_string = re.compile("\'(.*)\'$")
+re_hex = re.compile(r'0x[0-9a-fA-F]+')
+re_decimal = re.compile(r'\d+$')
+re_string = re.compile(r"\'(.*)\'$")
dnssec_timefmt = '%Y%m%d%H%M%S'
@@ -365,9 +365,6 @@
parser.add_option('-o', '--output', action='store', dest='output',
default=None, metavar='FILE',
help='output file name [default: prefix of input_file]')
- parser.add_option('-m', '--mode', action='store', dest='mode',
- default='message', metavar='[message|custom]',
- help='specify dump mode [default: %default]')
(options, args) = parser.parse_args()
if len(args) == 0:
@@ -389,9 +386,10 @@
print_header(output, configfile)
- if options.mode == 'custom':
+ # First try the 'custom' mode; if it fails assume the standard mode.
+ try:
sections = config.get('custom', 'sections').split(':')
- else:
+ except configparser.NoSectionError:
sections = ['header', 'question', 'edns']
for s in sections:
Modified: branches/trac232/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac232/src/lib/exceptions/exceptions.h (original)
+++ branches/trac232/src/lib/exceptions/exceptions.h Fri Oct 8 09:51:09 2010
@@ -103,20 +103,25 @@
const std::string what_;
};
-///
/// \brief A generic exception that is thrown if a parameter given
/// to a method would refer to or modify out-of-range data.
-///
class OutOfRange : public Exception {
public:
OutOfRange(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
-///
+/// \brief A generic exception that is thrown if a parameter given
+/// to a method or function is considered invalid and no other specific
+/// exceptions are suitable to describe the error.
+class InvalidParameter : public Exception {
+public:
+ InvalidParameter(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
/// \brief A generic exception that is thrown if a parameter given
/// to a method is considered invalid in that context.
-///
class BadValue : public Exception {
public:
BadValue(const char* file, size_t line, const char* what) :
Modified: branches/trac232/src/lib/python/isc/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = datasrc cc config log notify # Util
+SUBDIRS = datasrc cc config log notify utils # Util
python_PYTHON = __init__.py
Modified: branches/trac232/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/cc/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/cc/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py data.py session.py message.py
Modified: branches/trac232/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac232/src/lib/python/isc/cc/session.py (original)
+++ branches/trac232/src/lib/python/isc/cc/session.py Fri Oct 8 09:51:09 2010
@@ -16,6 +16,7 @@
import sys
import socket
import struct
+import errno
import os
import threading
import bind10_config
@@ -25,21 +26,21 @@
class ProtocolError(Exception): pass
class NetworkError(Exception): pass
class SessionError(Exception): pass
+class SessionTimeout(Exception): pass
class Session:
+ MSGQ_DEFAULT_TIMEOUT = 4000
+
def __init__(self, socket_file=None):
self._socket = None
- # store the current timeout value in seconds (the way
- # settimeout() wants them, our API takes milliseconds
- # so that it is consistent with the C++ version)
- self._socket_timeout = 4;
self._lname = None
- self._recvbuffer = bytearray()
- self._recvlength = 0
self._sequence = 1
self._closed = False
self._queue = []
self._lock = threading.RLock()
+ self.set_timeout(self.MSGQ_DEFAULT_TIMEOUT);
+ self._recv_len_size = 0
+ self._recv_size = 0
if socket_file is None:
if "BIND10_MSGQ_SOCKET_FILE" in os.environ:
@@ -121,6 +122,43 @@
return isc.cc.message.from_wire(data[2:header_length+2]), None
return None, None
+ def _receive_bytes(self, size):
+ """Try to get size bytes of data from the socket.
+ Raises a ProtocolError if the size is 0.
+ Raises any error from recv().
+ Returns whatever data was available (if >0 bytes).
+ """
+ data = self._socket.recv(size)
+ if len(data) == 0: # server closed connection
+ raise ProtocolError("Read of 0 bytes: connection closed")
+ return data
+
+ def _receive_len_data(self):
+ """Reads self._recv_len_size bytes of data from the socket into
+ self._recv_len_data
+ This is done through class variables so in the case of
+ an EAGAIN we can continue on a subsequent call.
+ Raises a ProtocolError, a socket.error (which may be
+ timeout or eagain), or reads until we have all data we need.
+ """
+ while self._recv_len_size > 0:
+ new_data = self._receive_bytes(self._recv_len_size)
+ self._recv_len_data += new_data
+ self._recv_len_size -= len(new_data)
+
+ def _receive_data(self):
+ """Reads self._recv_size bytes of data from the socket into
+ self._recv_data.
+ This is done through class variables so in the case of
+ an EAGAIN we can continue on a subsequent call.
+ Raises a ProtocolError, a socket.error (which may be
+ timeout or eagain), or reads until we have all data we need.
+ """
+ while self._recv_size > 0:
+ new_data = self._receive_bytes(self._recv_size)
+ self._recv_data += new_data
+ self._recv_size -= len(new_data)
+
def _receive_full_buffer(self, nonblock):
if nonblock:
self._socket.setblocking(0)
@@ -131,35 +169,47 @@
else:
self._socket.settimeout(self._socket_timeout)
- if self._recvlength == 0:
- length = 4
- length -= len(self._recvbuffer)
- try:
- data = self._socket.recv(length)
- except:
+ try:
+ # we might be in a call following an EAGAIN, in which case
+ # we simply continue. In the first case, either
+ # recv_size or recv_len size are not zero
+ # they may never both be non-zero (we are either starting
+ # a full read, or continuing one of the reads
+ assert self._recv_size == 0 or self._recv_len_size == 0
+
+ if self._recv_size == 0:
+ if self._recv_len_size == 0:
+ # both zero, start a new full read
+ self._recv_len_size = 4
+ self._recv_len_data = bytearray()
+ self._receive_len_data()
+
+ self._recv_size = struct.unpack('>I', self._recv_len_data)[0]
+ self._recv_data = bytearray()
+ self._receive_data()
+
+ # no EAGAIN, so copy data and reset internal counters
+ data = self._recv_data
+
+ self._recv_len_size = 0
+ self._recv_size = 0
+
+ return (data)
+
+ except socket.timeout:
+ raise SessionTimeout("recv() on cc session timed out")
+ except socket.error as se:
+ # Only keep data in case of EAGAIN
+ if se.errno == errno.EAGAIN:
return None
- if data == "": # server closed connection
- raise ProtocolError("Read of 0 bytes: connection closed")
- self._recvbuffer += data
- if len(self._recvbuffer) < 4:
+ # unknown state otherwise, best to drop data
+ self._recv_len_size = 0
+ self._recv_size = 0
+ # ctrl-c can result in EINTR, return None to prevent
+ # stacktrace output
+ if se.errno == errno.EINTR:
return None
- self._recvlength = struct.unpack('>I', self._recvbuffer)[0]
- self._recvbuffer = bytearray()
-
- length = self._recvlength - len(self._recvbuffer)
- while (length > 0):
- try:
- data = self._socket.recv(length)
- except:
- return None
- if data == "": # server closed connection
- raise ProtocolError("Read of 0 bytes: connection closed")
- self._recvbuffer += data
- length -= len(data)
- data = self._recvbuffer
- self._recvbuffer = bytearray()
- self._recvlength = 0
- return (data)
+ raise se
def _next_sequence(self):
self._sequence += 1
Modified: branches/trac232/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac232/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac232/src/lib/python/isc/cc/tests/session_test.py Fri Oct 8 09:51:09 2010
@@ -28,6 +28,7 @@
self.type = type
self.recvqueue = bytearray()
self.sendqueue = bytearray()
+ self._blocking = True
def connect(self, to):
pass
@@ -36,7 +37,7 @@
pass
def setblocking(self, val):
- pass
+ self._blocking = val
def send(self, data):
self.sendqueue.extend(data);
@@ -67,6 +68,11 @@
return result
def recv(self, length):
+ if len(self.recvqueue) == 0:
+ if self._blocking:
+ return bytes()
+ else:
+ raise socket.error(errno.EAGAIN, "Resource temporarily unavailable")
if length > len(self.recvqueue):
raise Exception("Buffer underrun in test, does the test provide the right data?")
result = self.recvqueue[:length]
@@ -105,7 +111,8 @@
self._socket_timeout = 1
self._lname = None
self._recvbuffer = bytearray()
- self._recvlength = 0
+ self._recv_len_size = 0
+ self._recv_size = 0
self._sequence = 1
self._closed = False
self._queue = []
@@ -192,10 +199,10 @@
# get no message without asking for a specific sequence number reply
self.assertFalse(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
- env, msg = sess.recvmsg(False)
+ env, msg = sess.recvmsg(True)
self.assertEqual(None, env)
self.assertTrue(sess.has_queued_msgs())
- env, msg = sess.recvmsg(False, 1)
+ env, msg = sess.recvmsg(True, 1)
self.assertEqual({'to': 'someone', 'reply': 1}, env)
self.assertEqual({"hello": "a"}, msg)
self.assertFalse(sess.has_queued_msgs())
@@ -204,11 +211,11 @@
# then ask for the one that is there
self.assertFalse(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
- env, msg = sess.recvmsg(False, 2)
+ env, msg = sess.recvmsg(True, 2)
self.assertEqual(None, env)
self.assertEqual(None, msg)
self.assertTrue(sess.has_queued_msgs())
- env, msg = sess.recvmsg(False, 1)
+ env, msg = sess.recvmsg(True, 1)
self.assertEqual({'to': 'someone', 'reply': 1}, env)
self.assertEqual({"hello": "a"}, msg)
self.assertFalse(sess.has_queued_msgs())
@@ -217,11 +224,11 @@
# then ask for any message
self.assertFalse(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone', 'reply': 1}, {"hello": "a"})
- env, msg = sess.recvmsg(False, 2)
+ env, msg = sess.recvmsg(True, 2)
self.assertEqual(None, env)
self.assertEqual(None, msg)
self.assertTrue(sess.has_queued_msgs())
- env, msg = sess.recvmsg(False, 1)
+ env, msg = sess.recvmsg(True, 1)
self.assertEqual({'to': 'someone', 'reply': 1}, env)
self.assertEqual({"hello": "a"}, msg)
self.assertFalse(sess.has_queued_msgs())
@@ -233,16 +240,16 @@
# then ask for any message (get the second)
self.assertFalse(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone', 'reply': 1}, {'hello': 'a'})
- env, msg = sess.recvmsg(False, 2)
+ env, msg = sess.recvmsg(True, 2)
self.assertEqual(None, env)
self.assertEqual(None, msg)
self.assertTrue(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone' }, {'hello': 'b'})
- env, msg = sess.recvmsg(False, 1)
+ env, msg = sess.recvmsg(True, 1)
self.assertEqual({'to': 'someone', 'reply': 1 }, env)
self.assertEqual({"hello": "a"}, msg)
self.assertFalse(sess.has_queued_msgs())
- env, msg = sess.recvmsg(False)
+ env, msg = sess.recvmsg(True)
self.assertEqual({'to': 'someone'}, env)
self.assertEqual({"hello": "b"}, msg)
self.assertFalse(sess.has_queued_msgs())
@@ -253,11 +260,11 @@
self.assertFalse(sess.has_queued_msgs())
sess._socket.addrecv({'to': 'someone' }, {'hello': 'b'})
sess._socket.addrecv({'to': 'someone', 'reply': 1}, {'hello': 'a'})
- env, msg = sess.recvmsg(False, 1)
+ env, msg = sess.recvmsg(True, 1)
self.assertEqual({'to': 'someone', 'reply': 1}, env)
self.assertEqual({"hello": "a"}, msg)
self.assertTrue(sess.has_queued_msgs())
- env, msg = sess.recvmsg(False)
+ env, msg = sess.recvmsg(True)
self.assertEqual({'to': 'someone'}, env)
self.assertEqual({"hello": "b"}, msg)
self.assertFalse(sess.has_queued_msgs())
@@ -353,9 +360,7 @@
sess = MySession(1, s2)
# set timeout to 100 msec, so test does not take too long
sess.set_timeout(100)
- env, msg = sess.group_recvmsg(False)
- self.assertEqual(None, env)
- self.assertEqual(None, msg)
+ self.assertRaises(SessionTimeout, sess.group_recvmsg, False)
finally:
os.remove(TEST_SOCKET_FILE)
Modified: branches/trac232/src/lib/python/isc/config/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/config/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/config/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py ccsession.py cfgmgr.py config_data.py module_spec.py
Modified: branches/trac232/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac232/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac232/src/lib/python/isc/config/ccsession.py Fri Oct 8 09:51:09 2010
@@ -177,10 +177,14 @@
def check_command(self):
"""Check whether there is a command or configuration update
on the channel. Call the corresponding callback function if
- there is."""
- msg, env = self._session.group_recvmsg(False)
+ there is. This function does a non-blocking read on the
+ cc session, and returns nothing. It will respond to any
+ command by either an error or the answer message returned
+ by the callback, unless the latter is None."""
+ msg, env = self._session.group_recvmsg(True)
+
# should we default to an answer? success-by-default? unhandled error?
- if msg and not 'result' in msg:
+ if msg is not None and not 'result' in msg:
answer = None
try:
module_name = env['group']
@@ -244,6 +248,8 @@
also subscribes to the channel of the remote module name
to receive the relevant updates. It is not possible to
specify your own handler for this right now.
+ start() must have been called on this CCSession
+ prior to the call to this method.
Returns the name of the module."""
module_spec = isc.config.module_spec_from_file(spec_file_name)
module_cfg = ConfigData(module_spec)
@@ -252,7 +258,13 @@
# Get the current config for that module now
seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": module_name }), "ConfigManager")
- answer, env = self._session.group_recvmsg(False, seq)
+
+ try:
+ answer, env = self._session.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ raise ModuleCCSessionError("No answer from ConfigManager when "
+ "asking about Remote module " +
+ module_name)
if answer:
rcode, value = parse_answer(answer)
if rcode == 0:
@@ -283,25 +295,32 @@
"""Sends the data specification to the configuration manager"""
msg = create_command(COMMAND_MODULE_SPEC, self.get_module_spec().get_full_spec())
seq = self._session.group_sendmsg(msg, "ConfigManager")
- answer, env = self._session.group_recvmsg(False, seq)
+ try:
+ answer, env = self._session.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ # TODO: log an error?
+ pass
def __request_config(self):
"""Asks the configuration manager for the current configuration, and call the config handler if set.
Raises a ModuleCCSessionError if there is no answer from the configuration manager"""
seq = self._session.group_sendmsg(create_command(COMMAND_GET_CONFIG, { "module_name": self._module_name }), "ConfigManager")
- answer, env = self._session.group_recvmsg(False, seq)
- if answer:
- rcode, value = parse_answer(answer)
- if rcode == 0:
- if value != None and self.get_module_spec().validate_config(False, value):
- self.set_local_config(value);
- if self._config_handler:
- self._config_handler(value)
+ try:
+ answer, env = self._session.group_recvmsg(False, seq)
+ if answer:
+ rcode, value = parse_answer(answer)
+ if rcode == 0:
+ if value != None and self.get_module_spec().validate_config(False, value):
+ self.set_local_config(value);
+ if self._config_handler:
+ self._config_handler(value)
+ else:
+ # log error
+ print("[" + self._module_name + "] Error requesting configuration: " + value)
else:
- # log error
- print("[" + self._module_name + "] Error requesting configuration: " + value)
- else:
- raise ModuleCCSessionError("No answer from configuration manager")
+ raise ModuleCCSessionError("No answer from configuration manager")
+ except isc.cc.SessionTimeout:
+ raise ModuleCCSessionError("CC Session timeout waiting for configuration manager")
class UIModuleCCSession(MultiConfigData):
Modified: branches/trac232/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- branches/trac232/src/lib/python/isc/config/cfgmgr.py (original)
+++ branches/trac232/src/lib/python/isc/config/cfgmgr.py Fri Oct 8 09:51:09 2010
@@ -283,7 +283,10 @@
update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
conf_part)
seq = self.cc.group_sendmsg(update_cmd, module_name)
- answer, env = self.cc.group_recvmsg(False, seq)
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
else:
conf_part = data.set(self.config.data, module_name, {})
data.merge(conf_part[module_name], cmd[1])
@@ -292,7 +295,10 @@
conf_part[module_name])
seq = self.cc.group_sendmsg(update_cmd, module_name)
# replace 'our' answer with that of the module
- answer, env = self.cc.group_recvmsg(False, seq)
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ except isc.cc.SessionTimeout:
+ answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
if answer:
rcode, val = ccsession.parse_answer(answer)
if rcode == 0:
@@ -313,15 +319,19 @@
update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
self.config.data[module])
seq = self.cc.group_sendmsg(update_cmd, module)
- answer, env = self.cc.group_recvmsg(False, seq)
- if answer == None:
+ try:
+ answer, env = self.cc.group_recvmsg(False, seq)
+ if answer == None:
+ got_error = True
+ err_list.append("No answer message from " + module)
+ else:
+ rcode, val = ccsession.parse_answer(answer)
+ if rcode != 0:
+ got_error = True
+ err_list.append(val)
+ except isc.cc.SessionTimeout:
got_error = True
- err_list.append("No answer message from " + module)
- else:
- rcode, val = ccsession.parse_answer(answer)
- if rcode != 0:
- got_error = True
- err_list.append(val)
+ err_list.append("CC Timeout waiting on answer message from " + module)
if not got_error:
self.write_config()
return ccsession.create_answer(0)
@@ -394,8 +404,13 @@
"""Runs the configuration manager."""
self.running = True
while (self.running):
+ # we just wait eternally for any command here, so disable
+ # timeouts for this specific recv
+ self.cc.set_timeout(0)
msg, env = self.cc.group_recvmsg(False)
- # ignore 'None' value (current result of timeout)
+ # and set it back to whatever we default to
+ self.cc.set_timeout(isc.cc.Session.MSGQ_DEFAULT_TIMEOUT)
+ # ignore 'None' value (even though they should not occur)
# and messages that are answers to questions we did
# not ask
if msg is not None and not 'result' in msg:
Modified: branches/trac232/src/lib/python/isc/config/tests/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/config/tests/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/config/tests/Makefile.am Fri Oct 8 09:51:09 2010
@@ -10,7 +10,7 @@
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python \
- CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/testdata \
- CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/testdata \
+ CONFIG_TESTDATA_PATH=$(abs_top_srcdir)/src/lib/config/tests/testdata \
+ CONFIG_WR_TESTDATA_PATH=$(abs_top_builddir)/src/lib/config/tests/testdata \
$(PYCOVERAGE) $(abs_srcdir)/$$pytest || exit ; \
done
Modified: branches/trac232/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac232/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac232/src/lib/python/isc/config/tests/unittest_fakesession.py Fri Oct 8 09:51:09 2010
@@ -15,6 +15,8 @@
# $Id$
+import isc
+
#
# We can probably use a more general version of this
#
@@ -24,6 +26,10 @@
# each entry is of the form [ channel, instance, message ]
self.message_queue = []
self._socket = "ok we just need something not-None here atm"
+ # if self.timeout is set to anything other than 0, and
+ # the message_queue is empty when receive is called, throw
+ # a SessionTimeout
+ self._timeout = 0
def group_subscribe(self, group_name, instance_name = None):
if not group_name in self.subscriptions:
@@ -63,7 +69,11 @@
if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
self.message_queue.remove(qm)
return qm[2], {'group': qm[0], 'from': qm[1]}
- return None, None
+ if self._timeout == 0:
+ return None, None
+ else:
+ raise isc.cc.SessionTimeout("Timeout set but no data to "
+ "return to group_recvmsg()")
def get_message(self, channel, target = None):
for qm in self.message_queue:
@@ -75,4 +85,6 @@
def close(self):
# need to pass along somehow that this function has been called,
self._socket = "closed"
- pass
+
+ def set_timeout(self, timeout):
+ self._timeout = timeout
Modified: branches/trac232/src/lib/python/isc/dns/__init__.py
==============================================================================
--- branches/trac232/src/lib/python/isc/dns/__init__.py (original)
+++ branches/trac232/src/lib/python/isc/dns/__init__.py Fri Oct 8 09:51:09 2010
@@ -1,1 +1,1 @@
-from libdns_python_name import *
+from pydnspp import *
Modified: branches/trac232/src/lib/python/isc/log/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/log/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/log/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py log.py
Modified: branches/trac232/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- branches/trac232/src/lib/python/isc/notify/Makefile.am (original)
+++ branches/trac232/src/lib/python/isc/notify/Makefile.am Fri Oct 8 09:51:09 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py notify_out.py
Modified: branches/trac232/src/lib/python/isc/notify/notify_out.py
==============================================================================
--- branches/trac232/src/lib/python/isc/notify/notify_out.py (original)
+++ branches/trac232/src/lib/python/isc/notify/notify_out.py Fri Oct 8 09:51:09 2010
@@ -22,7 +22,7 @@
from isc.datasrc import sqlite3_ds
import isc
try:
- from libdns_python import *
+ from pydnspp import *
except ImportError as e:
# C++ loadable module may not be installed;
sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
More information about the bind10-changes
mailing list