[svn] commit: r3041 - in /branches/trac191-rebased: ./ doc/guide/ src/bin/auth/ src/bin/auth/benchmarks/ src/bin/auth/tests/ src/bin/bind10/ src/bin/bindctl/ src/bin/cfgmgr/ src/bin/cmdctl/ src/bin/loadzone/ src/bin/msgq/ src/bin/xfrin/ src/bin/xfrout/ src/bin/xfrout/tests/ src/bin/zonemgr/ src/lib/config/tests/ src/lib/datasrc/ 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/cc/ src/lib/python/isc/cc/tests/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/ src/lib/python/isc/log/ src/lib/python/isc/notify/
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Sep 28 02:46:26 UTC 2010
Author: naokikambe
Date: Tue Sep 28 02:46:25 2010
New Revision: 3041
Log:
- sync with trunk
- fix a conflict of ChangeLog
- fix account name of stats entry in ChangeLog
Added:
branches/trac191-rebased/src/bin/auth/benchmarks/
- copied from r3040, trunk/src/bin/auth/benchmarks/
branches/trac191-rebased/src/bin/zonemgr/b10-zonemgr.8
- copied unchanged from r3040, trunk/src/bin/zonemgr/b10-zonemgr.8
branches/trac191-rebased/src/bin/zonemgr/b10-zonemgr.xml
- copied unchanged from r3040, trunk/src/bin/zonemgr/b10-zonemgr.xml
branches/trac191-rebased/src/lib/dns/edns.cc
- copied unchanged from r3040, trunk/src/lib/dns/edns.cc
branches/trac191-rebased/src/lib/dns/edns.h
- copied unchanged from r3040, trunk/src/lib/dns/edns.h
branches/trac191-rebased/src/lib/dns/python/edns_python.cc
- copied unchanged from r3040, trunk/src/lib/dns/python/edns_python.cc
branches/trac191-rebased/src/lib/dns/python/tests/edns_python_test.py
- copied unchanged from r3040, trunk/src/lib/dns/python/tests/edns_python_test.py
branches/trac191-rebased/src/lib/dns/python/tests/testutil.py
- copied unchanged from r3040, trunk/src/lib/dns/python/tests/testutil.py
branches/trac191-rebased/src/lib/dns/tests/edns_unittest.cc
- copied unchanged from r3040, trunk/src/lib/dns/tests/edns_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/testdata/Makefile.am
- copied unchanged from r3040, trunk/src/lib/dns/tests/testdata/Makefile.am
branches/trac191-rebased/src/lib/dns/tests/testdata/edns_toWire1.spec
- copied unchanged from r3040, trunk/src/lib/dns/tests/testdata/edns_toWire1.spec
branches/trac191-rebased/src/lib/dns/tests/testdata/edns_toWire2.spec
- copied unchanged from r3040, trunk/src/lib/dns/tests/testdata/edns_toWire2.spec
branches/trac191-rebased/src/lib/dns/tests/testdata/edns_toWire3.spec
- copied unchanged from r3040, trunk/src/lib/dns/tests/testdata/edns_toWire3.spec
branches/trac191-rebased/src/lib/dns/tests/testdata/edns_toWire4.spec
- copied unchanged from r3040, trunk/src/lib/dns/tests/testdata/edns_toWire4.spec
Removed:
branches/trac191-rebased/src/lib/dns/message_test.py
Modified:
branches/trac191-rebased/ (props changed)
branches/trac191-rebased/ChangeLog
branches/trac191-rebased/README
branches/trac191-rebased/configure.ac
branches/trac191-rebased/doc/guide/bind10-guide.html
branches/trac191-rebased/doc/guide/bind10-guide.xml
branches/trac191-rebased/src/bin/auth/Makefile.am
branches/trac191-rebased/src/bin/auth/asio_link.cc
branches/trac191-rebased/src/bin/auth/auth_srv.cc
branches/trac191-rebased/src/bin/auth/auth_srv.h
branches/trac191-rebased/src/bin/auth/b10-auth.8
branches/trac191-rebased/src/bin/auth/b10-auth.xml
branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc
branches/trac191-rebased/src/bin/bind10/Makefile.am
branches/trac191-rebased/src/bin/bind10/bind10.8
branches/trac191-rebased/src/bin/bind10/bind10.py.in
branches/trac191-rebased/src/bin/bind10/bind10.xml
branches/trac191-rebased/src/bin/bindctl/Makefile.am
branches/trac191-rebased/src/bin/cfgmgr/Makefile.am
branches/trac191-rebased/src/bin/cmdctl/Makefile.am
branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in
branches/trac191-rebased/src/bin/loadzone/Makefile.am
branches/trac191-rebased/src/bin/msgq/Makefile.am
branches/trac191-rebased/src/bin/xfrin/Makefile.am
branches/trac191-rebased/src/bin/xfrin/TODO
branches/trac191-rebased/src/bin/xfrin/b10-xfrin.8
branches/trac191-rebased/src/bin/xfrin/b10-xfrin.xml
branches/trac191-rebased/src/bin/xfrout/Makefile.am
branches/trac191-rebased/src/bin/xfrout/TODO
branches/trac191-rebased/src/bin/xfrout/b10-xfrout.8
branches/trac191-rebased/src/bin/xfrout/b10-xfrout.xml
branches/trac191-rebased/src/bin/xfrout/tests/xfrout_test.py
branches/trac191-rebased/src/bin/xfrout/xfrout.py.in
branches/trac191-rebased/src/bin/zonemgr/Makefile.am
branches/trac191-rebased/src/bin/zonemgr/TODO
branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in
branches/trac191-rebased/src/lib/config/tests/Makefile.am
branches/trac191-rebased/src/lib/datasrc/data_source.cc
branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc
branches/trac191-rebased/src/lib/dns/Makefile.am
branches/trac191-rebased/src/lib/dns/message.cc
branches/trac191-rebased/src/lib/dns/message.h
branches/trac191-rebased/src/lib/dns/python/Makefile.am
branches/trac191-rebased/src/lib/dns/python/message_python.cc
branches/trac191-rebased/src/lib/dns/python/messagerenderer_python.cc
branches/trac191-rebased/src/lib/dns/python/name_python.cc
branches/trac191-rebased/src/lib/dns/python/pydnspp.cc
branches/trac191-rebased/src/lib/dns/python/question_python.cc
branches/trac191-rebased/src/lib/dns/python/rdata_python.cc
branches/trac191-rebased/src/lib/dns/python/rrclass_python.cc
branches/trac191-rebased/src/lib/dns/python/rrset_python.cc
branches/trac191-rebased/src/lib/dns/python/rrttl_python.cc
branches/trac191-rebased/src/lib/dns/python/rrtype_python.cc
branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am
branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py
branches/trac191-rebased/src/lib/dns/python/tests/question_python_test.py
branches/trac191-rebased/src/lib/dns/rrclass-placeholder.h
branches/trac191-rebased/src/lib/dns/rrset.h
branches/trac191-rebased/src/lib/dns/rrtype-placeholder.h
branches/trac191-rebased/src/lib/dns/tests/Makefile.am
branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc
branches/trac191-rebased/src/lib/dns/tests/run_unittests.cc
branches/trac191-rebased/src/lib/exceptions/exceptions.h
branches/trac191-rebased/src/lib/python/isc/cc/Makefile.am
branches/trac191-rebased/src/lib/python/isc/cc/session.py
branches/trac191-rebased/src/lib/python/isc/cc/tests/session_test.py
branches/trac191-rebased/src/lib/python/isc/config/Makefile.am
branches/trac191-rebased/src/lib/python/isc/config/ccsession.py
branches/trac191-rebased/src/lib/python/isc/config/cfgmgr.py
branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py
branches/trac191-rebased/src/lib/python/isc/log/Makefile.am
branches/trac191-rebased/src/lib/python/isc/notify/Makefile.am
Modified: branches/trac191-rebased/ChangeLog
==============================================================================
--- branches/trac191-rebased/ChangeLog (original)
+++ branches/trac191-rebased/ChangeLog Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
- XX. [func] kambe
+ XX. [func] naokikambe
Added the initial version of the stats module for the statistics
feature of BIND 10, which supports the restricted features and
items and reports via bindctl command (Trac #191, rXXXX)
@@ -6,6 +6,46 @@
Added the document of the stats module, which is about how stats
module collects the data (Trac #170)
+ 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
@@ -14,7 +54,7 @@
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/trac191-rebased/README
==============================================================================
--- branches/trac191-rebased/README (original)
+++ branches/trac191-rebased/README Tue Sep 28 02:46:25 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/trac191-rebased/configure.ac
==============================================================================
--- branches/trac191-rebased/configure.ac (original)
+++ branches/trac191-rebased/configure.ac Tue Sep 28 02:46:25 2010
@@ -39,6 +39,14 @@
[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
# OS dependent configuration
SET_ENV_LIBRARY_PATH=no
@@ -167,7 +175,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 +277,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)
#
@@ -389,10 +413,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 +443,7 @@
src/bin/msgq/tests/Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
+ src/bin/auth/benchmarks/Makefile
src/bin/xfrin/Makefile
src/bin/xfrin/tests/Makefile
src/bin/xfrout/Makefile
@@ -454,6 +475,7 @@
src/lib/config/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
@@ -554,7 +576,6 @@
Flags:
DEFS: $DEFS
CPPFLAGS: $CPPFLAGS
- CFLAGS: $CFLAGS
CXXFLAGS: $CXXFLAGS
B10_CXXFLAGS: $B10_CXXFLAGS
dnl includes too
Modified: branches/trac191-rebased/doc/guide/bind10-guide.html
==============================================================================
--- branches/trac191-rebased/doc/guide/bind10-guide.html (original)
+++ branches/trac191-rebased/doc/guide/bind10-guide.html Tue Sep 28 02:46:25 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/trac191-rebased/doc/guide/bind10-guide.xml
==============================================================================
--- branches/trac191-rebased/doc/guide/bind10-guide.xml (original)
+++ branches/trac191-rebased/doc/guide/bind10-guide.xml Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/auth/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/auth/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/auth/Makefile.am Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/auth/asio_link.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/asio_link.cc (original)
+++ branches/trac191-rebased/src/bin/auth/asio_link.cc Tue Sep 28 02:46:25 2010
@@ -67,7 +67,7 @@
// 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
+// a big deal, but when we receive UDP packets at a high rate, the copy
// overhead might be significant.
class TCPEndpoint : public IOEndpoint {
public:
Modified: branches/trac191-rebased/src/bin/auth/auth_srv.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/auth_srv.cc (original)
+++ branches/trac191-rebased/src/bin/auth/auth_srv.cc Tue Sep 28 02:46:25 2010
@@ -24,6 +24,7 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/messagerenderer.h>
#include <dns/name.h>
@@ -168,7 +169,6 @@
message.setQid(qid);
message.setOpcode(opcode);
message.setHeaderFlag(MessageFlag::QR());
- message.setUDPSize(AuthSrvImpl::DEFAULT_LOCAL_UDPSIZE);
if (rd) {
message.setHeaderFlag(MessageFlag::RD());
}
@@ -194,6 +194,16 @@
bool
AuthSrv::getVerbose() const {
return (impl_->verbose_mode_);
+}
+
+void
+AuthSrv::setCacheSlots(const size_t slots) {
+ impl_->cache_.setSlots(slots);
+}
+
+size_t
+AuthSrv::getCacheSlots() const {
+ return (impl_->cache_.getSlots());
}
void
@@ -304,14 +314,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/trac191-rebased/src/bin/auth/auth_srv.h
==============================================================================
--- branches/trac191-rebased/src/bin/auth/auth_srv.h (original)
+++ branches/trac191-rebased/src/bin/auth/auth_srv.h Tue Sep 28 02:46:25 2010
@@ -73,6 +73,26 @@
isc::config::ModuleCCSession* configSession() const;
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;
+
///
/// Note: this interface is tentative. We'll revisit the ASIO and session
/// frameworks, at which point the session will probably be passed on
Modified: branches/trac191-rebased/src/bin/auth/b10-auth.8
==============================================================================
--- branches/trac191-rebased/src/bin/auth/b10-auth.8 (original)
+++ branches/trac191-rebased/src/bin/auth/b10-auth.8 Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/auth/b10-auth.xml
==============================================================================
--- branches/trac191-rebased/src/bin/auth/b10-auth.xml (original)
+++ branches/trac191-rebased/src/bin/auth/b10-auth.xml Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc (original)
+++ branches/trac191-rebased/src/bin/auth/tests/auth_srv_unittest.cc Tue Sep 28 02:46:25 2010
@@ -445,13 +445,20 @@
EXPECT_EQ(true, server.processMessage(*io_message, parse_message,
response_renderer));
- // The response must have an EDNS OPT RR in the additional section.
+ // 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) {
@@ -750,4 +757,14 @@
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/trac191-rebased/src/bin/bind10/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/bind10/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
sbin_SCRIPTS = bind10
CLEANFILES = bind10 bind10.pyc
Modified: branches/trac191-rebased/src/bin/bind10/bind10.8
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.8 (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.8 Tue Sep 28 02:46:25 2010
@@ -101,6 +101,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/trac191-rebased/src/bin/bind10/bind10.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.py.in (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.py.in Tue Sep 28 02:46:25 2010
@@ -65,7 +65,9 @@
import isc.cc
# 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@)"
# This is for bind10.boottime of stats module
_BASETIME = time.gmtime()
@@ -653,7 +655,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)")
@@ -706,7 +708,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/
@@ -775,7 +777,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/trac191-rebased/src/bin/bind10/bind10.xml
==============================================================================
--- branches/trac191-rebased/src/bin/bind10/bind10.xml (original)
+++ branches/trac191-rebased/src/bin/bind10/bind10.xml Tue Sep 28 02:46:25 2010
@@ -189,6 +189,12 @@
<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>
</refsect1>
Modified: branches/trac191-rebased/src/bin/bindctl/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/bindctl/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/bindctl/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
bin_SCRIPTS = bindctl
man_MANS = bindctl.1
Modified: branches/trac191-rebased/src/bin/cfgmgr/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/cfgmgr/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/cfgmgr/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac191-rebased/src/bin/cmdctl/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/cmdctl/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/cmdctl/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in (original)
+++ branches/trac191-rebased/src/bin/cmdctl/cmdctl.py.in Tue Sep 28 02:46:25 2010
@@ -380,6 +380,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 +391,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 +414,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 +605,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/trac191-rebased/src/bin/loadzone/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/loadzone/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/loadzone/Makefile.am Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/msgq/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/msgq/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/msgq/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac191-rebased/src/bin/xfrin/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/xfrin/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac191-rebased/src/bin/xfrin/TODO
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/TODO (original)
+++ branches/trac191-rebased/src/bin/xfrin/TODO Tue Sep 28 02:46:25 2010
@@ -65,4 +65,6 @@
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/trac191-rebased/src/bin/xfrin/b10-xfrin.8
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/b10-xfrin.8 (original)
+++ branches/trac191-rebased/src/bin/xfrin/b10-xfrin.8 Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/xfrin/b10-xfrin.xml
==============================================================================
--- branches/trac191-rebased/src/bin/xfrin/b10-xfrin.xml (original)
+++ branches/trac191-rebased/src/bin/xfrin/b10-xfrin.xml Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/xfrout/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/xfrout/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
pkglibexecdir = $(libexecdir)/@PACKAGE@
Modified: branches/trac191-rebased/src/bin/xfrout/TODO
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/TODO (original)
+++ branches/trac191-rebased/src/bin/xfrout/TODO Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/xfrout/b10-xfrout.8
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/b10-xfrout.8 (original)
+++ branches/trac191-rebased/src/bin/xfrout/b10-xfrout.8 Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/xfrout/b10-xfrout.xml
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/b10-xfrout.xml (original)
+++ branches/trac191-rebased/src/bin/xfrout/b10-xfrout.xml Tue Sep 28 02:46:25 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.
@@ -97,12 +98,16 @@
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/trac191-rebased/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/tests/xfrout_test.py (original)
+++ branches/trac191-rebased/src/bin/xfrout/tests/xfrout_test.py Tue Sep 28 02:46:25 2010
@@ -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/trac191-rebased/src/bin/xfrout/xfrout.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/xfrout/xfrout.py.in (original)
+++ branches/trac191-rebased/src/bin/xfrout/xfrout.py.in Tue Sep 28 02:46:25 2010
@@ -27,7 +27,7 @@
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 socket
import select
@@ -57,6 +57,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 +130,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 +234,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 +258,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 +269,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 +310,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 +320,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 +404,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 +476,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 +520,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/trac191-rebased/src/bin/zonemgr/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/Makefile.am (original)
+++ branches/trac191-rebased/src/bin/zonemgr/Makefile.am Tue Sep 28 02:46:25 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/trac191-rebased/src/bin/zonemgr/TODO
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/TODO (original)
+++ branches/trac191-rebased/src/bin/zonemgr/TODO Tue Sep 28 02:46:25 2010
@@ -1,5 +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/trac191-rebased/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in (original)
+++ branches/trac191-rebased/src/bin/zonemgr/zonemgr.py.in Tue Sep 28 02:46:25 2010
@@ -261,7 +261,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 +513,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?")
+ "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/trac191-rebased/src/lib/config/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/config/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/config/tests/Makefile.am Tue Sep 28 02:46:25 2010
@@ -21,15 +21,13 @@
run_unittests_SOURCES = ccsession_unittests.cc module_spec_unittests.cc config_data_unittests.cc run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+# TODO: remove PTHREAD_LDFLAGS (and from configure too)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) $(PTHREAD_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/trac191-rebased/src/lib/datasrc/data_source.cc
==============================================================================
--- branches/trac191-rebased/src/lib/datasrc/data_source.cc (original)
+++ branches/trac191-rebased/src/lib/datasrc/data_source.cc Tue Sep 28 02:46:25 2010
@@ -206,6 +206,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/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/datasrc/tests/datasrc_unittest.cc Tue Sep 28 02:46:25 2010
@@ -915,6 +915,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/trac191-rebased/src/lib/dns/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/Makefile.am Tue Sep 28 02:46:25 2010
@@ -63,6 +63,7 @@
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
@@ -88,8 +89,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/trac191-rebased/src/lib/dns/message.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/message.cc (original)
+++ branches/trac191-rebased/src/lib/dns/message.cc Tue Sep 28 02:46:25 2010
@@ -28,6 +28,7 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
@@ -64,10 +65,7 @@
//
// 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;
@@ -167,10 +165,37 @@
return (opcodetext[code_]);
}
-Rcode::Rcode(uint16_t code) : code_(code) {
+namespace {
+// This diagram shows the wire-format representation of the 12-bit extended
+// form RCODEs and its relationship with implementation specific parameters.
+//
+// 0 3 11 15
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |UNUSED | EXTENDED-RCODE | RCODE |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// <= EXTRCODE_SHIFT (4 bits)
+const unsigned int EXTRCODE_SHIFT = 4;
+}
+
+Rcode::Rcode(const uint16_t code) : code_(code) {
if (code_ > MAX_RCODE) {
- isc_throw(OutOfRange, "Rcode is too large to construct");
- }
+ isc_throw(OutOfRange, "Rcode is too large to construct: " << code_);
+ }
+}
+
+Rcode::Rcode(const uint8_t code, const uint8_t extended_code) :
+ code_((extended_code << EXTRCODE_SHIFT) | (code & RCODE_MASK))
+{
+ if (code > RCODE_MASK) {
+ isc_throw(OutOfRange,
+ "Base Rcode is too large to construct: "
+ << static_cast<unsigned int>(code));
+ }
+}
+
+uint8_t
+Rcode::getExtendedCode() const {
+ return (code_ >> EXTRCODE_SHIFT);
}
string
@@ -203,17 +228,13 @@
Rcode rcode_;
const Opcode* opcode_;
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
@@ -237,11 +258,7 @@
qid_ = 0;
rcode_ = Rcode::NOERROR(); // XXX
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;
@@ -285,38 +302,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_);
@@ -357,6 +342,20 @@
"setOpcode performed in non-render mode");
}
impl_->opcode_ = &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,54 +440,6 @@
};
}
-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) {
@@ -528,12 +479,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
@@ -657,6 +616,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 +665,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));
+ rcode_ = 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);
@@ -786,30 +749,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 +807,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());
Modified: branches/trac191-rebased/src/lib/dns/message.h
==============================================================================
--- branches/trac191-rebased/src/lib/dns/message.h (original)
+++ branches/trac191-rebased/src/lib/dns/message.h Tue Sep 28 02:46:25 2010
@@ -25,6 +25,7 @@
#include <exceptions/exceptions.h>
+#include <dns/edns.h>
#include <dns/question.h>
#include <dns/rrset.h>
@@ -314,8 +315,10 @@
/// Constant objects are defined for standard flags.
class Rcode {
public:
- Rcode(uint16_t code);
+ Rcode(const uint16_t code);
+ Rcode(const uint8_t code, const uint8_t extended_code);
uint16_t getCode() const { return (code_); }
+ uint8_t getExtendedCode() const;
bool operator==(const Rcode& other) const { return (code_ == other.code_); }
bool operator!=(const Rcode& other) const { return (code_ != other.code_); }
std::string toText() const;
@@ -627,45 +630,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;
@@ -682,9 +646,10 @@
/// returned.
const Rcode& getRcode() const;
- /// \brief Return the Response Code of the message.
+ /// \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);
@@ -696,6 +661,23 @@
///
/// 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;
Modified: branches/trac191-rebased/src/lib/dns/python/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/python/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CXXFLAGS = $(B10_CXXFLAGS)
@@ -11,6 +11,7 @@
# directly included from source files, so these don't have their own
# rules
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
Modified: branches/trac191-rebased/src/lib/dns/python/message_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/message_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/message_python.cc Tue Sep 28 02:46:25 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
@@ -120,7 +119,6 @@
0 // tp_version_tag
};
-
static int
MessageFlag_init(s_MessageFlag* self UNUSED_PARAM,
PyObject* args UNUSED_PARAM)
@@ -486,6 +484,7 @@
static void Rcode_destroy(s_Rcode* self);
static PyObject* Rcode_getCode(s_Rcode* self);
+static PyObject* Rcode_getExtendedCode(const s_Rcode* self);
static PyObject* Rcode_toText(s_Rcode* self);
static PyObject* Rcode_str(PyObject* self);
static PyObject* Rcode_NOERROR(s_Rcode* self);
@@ -509,6 +508,9 @@
static PyMethodDef Rcode_methods[] = {
{ "get_code", reinterpret_cast<PyCFunction>(Rcode_getCode), METH_NOARGS, "Returns the code value" },
+ { "get_extended_code",
+ reinterpret_cast<PyCFunction>(Rcode_getExtendedCode),
+ METH_NOARGS, "Returns the extended 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" },
@@ -617,6 +619,11 @@
}
static PyObject*
+Rcode_getExtendedCode(const s_Rcode* self) {
+ return (Py_BuildValue("B", self->rcode->getExtendedCode()));
+}
+
+static PyObject*
Rcode_toText(s_Rcode* self) {
return (Py_BuildValue("s", self->rcode->toText().c_str()));
}
@@ -973,16 +980,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 +1024,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 +1042,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,
@@ -1248,57 +1230,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()));
}
@@ -1378,6 +1309,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());
@@ -1535,7 +1501,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
Modified: branches/trac191-rebased/src/lib/dns/python/messagerenderer_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/messagerenderer_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/messagerenderer_python.cc Tue Sep 28 02:46:25 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,6 +57,9 @@
"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 }
};
@@ -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/trac191-rebased/src/lib/dns/python/name_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/name_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/name_python.cc Tue Sep 28 02:46:25 2010
@@ -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);
Modified: branches/trac191-rebased/src/lib/dns/python/pydnspp.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/pydnspp.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/pydnspp.cc Tue Sep 28 02:46:25 2010
@@ -40,8 +40,12 @@
#include <dns/python/pydnspp_common.h>
-// For our 'general' isc::Exception
+// For our 'general' isc::Exceptions
static PyObject* po_IscException;
+static PyObject* po_InvalidParameter;
+
+// For our own isc::dns::Exception
+static PyObject* po_DNSMessageBADVERS;
// order is important here!
#include <dns/python/messagerenderer_python.cc>
@@ -53,6 +57,7 @@
#include <dns/python/rrset_python.cc> // needs Rdata, RRTTL
#include <dns/python/question_python.cc> // needs RRClass, RRType, RRTTL,
// Name
+#include <dns/python/edns_python.cc> // needs Messagerenderer, Rcode
#include <dns/python/message_python.cc> // needs RRset, Question
//
@@ -81,8 +86,13 @@
return (NULL);
}
+ // Add the exceptions to the class
po_IscException = PyErr_NewException("pydnspp.IscException", NULL, NULL);
PyModule_AddObject(mod, "IscException", po_IscException);
+
+ po_InvalidParameter = PyErr_NewException("pydnspp.InvalidParameter",
+ NULL, NULL);
+ PyModule_AddObject(mod, "InvalidParameter", po_InvalidParameter);
// for each part included above, we call its specific initializer
@@ -122,6 +132,10 @@
return (NULL);
}
+ if (!initModulePart_EDNS(mod)) {
+ return (NULL);
+ }
+
return (mod);
}
Modified: branches/trac191-rebased/src/lib/dns/python/question_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/question_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/question_python.cc Tue Sep 28 02:46:25 2010
@@ -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/trac191-rebased/src/lib/dns/python/rdata_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/rdata_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/rdata_python.cc Tue Sep 28 02:46:25 2010
@@ -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
Modified: branches/trac191-rebased/src/lib/dns/python/rrclass_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/rrclass_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/rrclass_python.cc Tue Sep 28 02:46:25 2010
@@ -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
Modified: branches/trac191-rebased/src/lib/dns/python/rrset_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/rrset_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/rrset_python.cc Tue Sep 28 02:46:25 2010
@@ -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
Modified: branches/trac191-rebased/src/lib/dns/python/rrttl_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/rrttl_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/rrttl_python.cc Tue Sep 28 02:46:25 2010
@@ -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
Modified: branches/trac191-rebased/src/lib/dns/python/rrtype_python.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/rrtype_python.cc (original)
+++ branches/trac191-rebased/src/lib/dns/python/rrtype_python.cc Tue Sep 28 02:46:25 2010
@@ -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
Modified: branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,5 @@
-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
@@ -23,8 +24,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/trac191-rebased/src/lib/dns/python/tests/message_python_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/message_python_test.py Tue Sep 28 02:46:25 2010
@@ -20,7 +20,7 @@
import unittest
import os
from pydnspp import *
-
+from testutil import *
class MessageFlagTest(unittest.TestCase):
def test_init(self):
@@ -240,19 +240,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 +303,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,
@@ -365,6 +330,24 @@
self.assertRaises(InvalidMessageOperation,
self.p.set_opcode, opcode)
+
+ def test_get_edns(self):
+ self.assertEqual(None, self.p.get_edns())
+
+ message_parse = Message(Message.PARSE)
+ factoryFromFile(message_parse, "message_fromWire10")
+ 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")
@@ -487,84 +470,6 @@
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)
Modified: branches/trac191-rebased/src/lib/dns/python/tests/question_python_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/dns/python/tests/question_python_test.py (original)
+++ branches/trac191-rebased/src/lib/dns/python/tests/question_python_test.py Tue Sep 28 02:46:25 2010
@@ -20,24 +20,12 @@
import unittest
import os
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/trac191-rebased/src/lib/dns/rrclass-placeholder.h
==============================================================================
--- branches/trac191-rebased/src/lib/dns/rrclass-placeholder.h (original)
+++ branches/trac191-rebased/src/lib/dns/rrclass-placeholder.h Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/dns/rrset.h
==============================================================================
--- branches/trac191-rebased/src/lib/dns/rrset.h (original)
+++ branches/trac191-rebased/src/lib/dns/rrset.h Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/dns/rrtype-placeholder.h
==============================================================================
--- branches/trac191-rebased/src/lib/dns/rrtype-placeholder.h (original)
+++ branches/trac191-rebased/src/lib/dns/rrtype-placeholder.h Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/dns/tests/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/dns/tests/Makefile.am Tue Sep 28 02:46:25 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,6 +17,7 @@
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
@@ -53,6 +57,8 @@
# NOTE: keep this in sync with real file listing
# so is included in tarball
EXTRA_DIST = testdata/gen-wiredata.py.in
+EXTRA_DIST += testdata/edns_toWire1.spec testdata/edns_toWire2.spec
+EXTRA_DIST += testdata/edns_toWire3.spec testdata/edns_toWire4.spec
EXTRA_DIST += testdata/message_fromWire1
EXTRA_DIST += testdata/message_fromWire10
EXTRA_DIST += testdata/message_fromWire10.spec
Modified: branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/message_unittest.cc Tue Sep 28 02:46:25 2010
@@ -17,6 +17,7 @@
#include <exceptions/exceptions.h>
#include <dns/buffer.h>
+#include <dns/edns.h>
#include <dns/exceptions.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
@@ -93,6 +94,25 @@
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");
+ 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,82 +147,7 @@
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");
EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode());
@@ -221,19 +166,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) {
Modified: branches/trac191-rebased/src/lib/dns/tests/run_unittests.cc
==============================================================================
--- branches/trac191-rebased/src/lib/dns/tests/run_unittests.cc (original)
+++ branches/trac191-rebased/src/lib/dns/tests/run_unittests.cc Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/exceptions/exceptions.h
==============================================================================
--- branches/trac191-rebased/src/lib/exceptions/exceptions.h (original)
+++ branches/trac191-rebased/src/lib/exceptions/exceptions.h Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/cc/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/cc/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/cc/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py data.py session.py message.py
Modified: branches/trac191-rebased/src/lib/python/isc/cc/session.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/cc/session.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/cc/session.py Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/cc/tests/session_test.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/cc/tests/session_test.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/cc/tests/session_test.py Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/config/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/Makefile.am Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/config/ccsession.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/ccsession.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/ccsession.py Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/config/cfgmgr.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/cfgmgr.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/cfgmgr.py Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ branches/trac191-rebased/src/lib/python/isc/config/tests/unittest_fakesession.py Tue Sep 28 02:46:25 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/trac191-rebased/src/lib/python/isc/log/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/log/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/log/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py log.py
Modified: branches/trac191-rebased/src/lib/python/isc/notify/Makefile.am
==============================================================================
--- branches/trac191-rebased/src/lib/python/isc/notify/Makefile.am (original)
+++ branches/trac191-rebased/src/lib/python/isc/notify/Makefile.am Tue Sep 28 02:46:25 2010
@@ -1,4 +1,4 @@
-SUBDIRS = tests
+SUBDIRS = . tests
python_PYTHON = __init__.py notify_out.py
More information about the bind10-changes
mailing list