Browse Source

update merge; merge trunk rev. 1670 - 1813 into this branch

git-svn-id: svn://bind10.isc.org/svn/bind10/experiments/python-binding@1814 e5f2f494-b856-4b98-b285-d166d9295462
Jelte Jansen 15 years ago
parent
commit
61dca75df5
100 changed files with 1597 additions and 834 deletions
  1. 15 0
      ChangeLog
  2. 36 13
      configure.ac
  3. 116 63
      doc/guide/bind10-guide.html
  4. 165 51
      doc/guide/bind10-guide.xml
  5. 2 2
      src/bin/auth/Makefile.am
  6. 5 5
      src/bin/auth/auth_srv.cc
  7. 4 7
      src/bin/auth/b10-auth.8
  8. 5 8
      src/bin/auth/b10-auth.xml
  9. 1 1
      src/bin/auth/main.cc
  10. 15 0
      src/bin/auth/spec_config.h.in
  11. 2 1
      src/bin/auth/tests/Makefile.am
  12. 15 14
      src/bin/auth/tests/auth_srv_unittest.cc
  13. 4 0
      src/bin/auth/tests/run_unittests.cc
  14. 4 2
      src/bin/bind10/Makefile.am
  15. 3 0
      src/bin/bind10/TODO
  16. 5 5
      src/bin/bind10/bind10.8
  17. 73 52
      src/bin/bind10/bind10.py.in
  18. 5 5
      src/bin/bind10/bind10.xml
  19. 15 0
      src/bin/bind10/run_bind10.sh.in
  20. 12 0
      src/bin/bind10/tests/Makefile.am
  21. 15 0
      src/bin/bind10/tests/bind10_test.in
  22. 2 1
      src/bin/bindctl/Makefile.am
  23. 0 1
      src/bin/bindctl/bindctl.1
  24. 0 3
      src/bin/bindctl/bindctl.xml
  25. 2 2
      src/bin/bindctl/exception.py
  26. 15 0
      src/bin/bindctl/run_bindctl.sh.in
  27. 12 0
      src/bin/bindctl/tests/Makefile.am
  28. 15 0
      src/bin/bindctl/tests/bindctl_test.in
  29. 1 1
      src/bin/cfgmgr/b10-cfgmgr.8
  30. 15 0
      src/bin/cfgmgr/b10-cfgmgr.py.in
  31. 1 1
      src/bin/cfgmgr/b10-cfgmgr.xml
  32. 3 2
      src/bin/cmdctl/Makefile.am
  33. 15 0
      src/bin/cmdctl/run_b10-cmdctl.sh.in
  34. 12 0
      src/bin/cmdctl/tests/Makefile.am
  35. 15 0
      src/bin/cmdctl/tests/cmdctl_test.in
  36. 1 0
      src/bin/cmdctl/tests/cmdctl_test.py
  37. 14 0
      src/bin/host/host.cc
  38. 5 4
      src/bin/loadzone/b10-loadzone.py.in
  39. 15 0
      src/bin/loadzone/run_loadzone.sh.in
  40. 8 6
      src/bin/msgq/Makefile.am
  41. 13 13
      src/bin/msgq/msgq.8
  42. 15 0
      src/bin/msgq/msgq.py.in
  43. 10 10
      src/bin/msgq/msgq.xml
  44. 0 13
      src/bin/msgq/msgq_test.in
  45. 16 1
      src/bin/msgq/run_msgq.sh.in
  46. 13 0
      src/bin/msgq/tests/Makefile.am
  47. 28 0
      src/bin/msgq/tests/msgq_test.in
  48. 0 0
      src/bin/msgq/tests/msgq_test.py
  49. 15 0
      src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in
  50. 3 2
      src/bin/xfrin/Makefile.am
  51. 27 14
      src/bin/xfrin/b10-xfrin.8
  52. 33 46
      src/bin/xfrin/b10-xfrin.xml
  53. 16 1
      src/bin/xfrin/run_b10-xfrin.sh.in
  54. 16 0
      src/bin/xfrin/tests/Makefile.am
  55. 15 0
      src/bin/xfrin/tests/xfrin_test.in
  56. 57 2
      src/bin/xfrin/tests/xfrin_test.py
  57. 84 88
      src/bin/xfrin/xfrin.py.in
  58. 1 16
      src/bin/xfrin/xfrin.spec.pre.in
  59. 13 2
      src/bin/xfrout/Makefile.am
  60. 116 0
      src/bin/xfrout/b10-xfrout.8
  61. 181 0
      src/bin/xfrout/b10-xfrout.xml
  62. 16 1
      src/bin/xfrout/run_b10-xfrout.sh.in
  63. 16 0
      src/bin/xfrout/tests/Makefile.am
  64. 15 0
      src/bin/xfrout/tests/xfrout_test.in
  65. 34 17
      src/bin/xfrout/xfrout.py.in
  66. 1 1
      src/lib/Makefile.am
  67. 0 13
      src/lib/auth/Makefile.am
  68. 0 2
      src/lib/auth/TODO
  69. 0 127
      src/lib/auth/tests/unittest_util.cc
  70. 0 84
      src/lib/auth/tests/unittest_util.h
  71. 2 2
      src/lib/cc/data.cc
  72. 1 1
      src/lib/cc/data.h
  73. 14 0
      src/lib/config/tests/data_def_unittests_config.h.in
  74. 13 0
      src/lib/datasrc/Makefile.am
  75. 1 0
      src/lib/datasrc/TODO
  76. 54 61
      src/lib/auth/data_source.cc
  77. 1 1
      src/lib/auth/data_source.h
  78. 1 1
      src/lib/auth/query.cc
  79. 1 1
      src/lib/auth/query.h
  80. 7 7
      src/lib/auth/sqlite3_datasrc.cc
  81. 1 1
      src/lib/auth/sqlite3_datasrc.h
  82. 2 2
      src/lib/auth/static_datasrc.cc
  83. 1 1
      src/lib/auth/static_datasrc.h
  84. 6 4
      src/lib/auth/tests/Makefile.am
  85. 40 26
      src/lib/auth/tests/datasrc_unittest.cc
  86. 2 2
      src/lib/auth/tests/query_unittest.cc
  87. 4 0
      src/lib/auth/tests/run_unittests.cc
  88. 9 9
      src/lib/auth/tests/sqlite3_unittest.cc
  89. 9 7
      src/lib/auth/tests/static_unittest.cc
  90. 3 3
      src/lib/auth/tests/test_datasrc.cc
  91. 2 2
      src/lib/auth/tests/test_datasrc.h
  92. 0 0
      src/lib/datasrc/tests/testdata/brokendb.sqlite3
  93. 0 0
      src/lib/datasrc/tests/testdata/example.com.signed
  94. 1 0
      src/lib/auth/tests/testdata/example.org
  95. BIN
      src/lib/auth/tests/testdata/example.org.sqlite3
  96. 0 0
      src/lib/datasrc/tests/testdata/example2.com
  97. 0 0
      src/lib/datasrc/tests/testdata/example2.com.sqlite3
  98. 0 0
      src/lib/datasrc/tests/testdata/mkbrokendb.c
  99. 0 0
      src/lib/datasrc/tests/testdata/q_cname
  100. 0 0
      src/lib/auth/tests/testdata/q_cname_ext

+ 15 - 0
ChangeLog

@@ -0,0 +1,15 @@
+   1.	[bug]		jinmei
+	lib/dns: parameter validation of Name::split() was not sufficient,
+	and invalid parameters could cause integer overflow and make the
+	library crash. (Trac #177, svn r1806)
+
+LEGEND
+[bug] general bug fix.  This is generally a backward compatible change,
+	unless it's deemed to be impossible or very hard to keep
+	compatibility to fix the bug.
+[doc] update to documentation.  This shouldn't change run time behavior.
+[func] new feature.  In some cases this may be a backward incompatible
+	change, which would require a bump of major version.
+[security] security hole fix.  This is no different than a general bug fix
+	except that it will be handled as confidential and will cause 
+	security patch releases.

+ 36 - 13
configure.ac

@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.59])
-AC_INIT(bind10-devel, 20100318, bind10-bugs@isc.org)
+AC_INIT(bind10-devel, 20100318, bind10-dev@isc.org)
 AC_CONFIG_SRCDIR(README)
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADERS([config.h])
@@ -48,15 +48,30 @@ else
 	AC_SUBST(pkgpyexecdir)
 fi
 
-if test ! -x ${PYTHON}-config; then
-	AC_MSG_ERROR([${PYTHON}-config not found])
-fi
+# Check for python development environments
+if test -x ${PYTHON}-config; then
+	PYTHON_INCLUDES=`${PYTHON}-config --includes`
 
-PYTHON_INCLUDES=`${PYTHON}-config --includes`
+	for flag in `${PYTHON}-config --ldflags`; do
+		# add any '-L..." flags to PYTHON_LDFLAGS
+		flag=`echo $flag | sed -ne 's/^\(\-L.*\)$/\1/p'`
+		if test "X${flag}" != X; then
+			PYTHON_LDFLAGS="$PYTHON_LDFLAGS ${flag}"
+		fi
+	done
+	# on some platforms, ${PYTHON}-config --ldflags doesn't provide a -L
+	# option while having the library under a non trivial directory.
+	# as a workaround we try the "lib" sub directory under the common
+	# prefix for this python.
+	if test -z "${PYTHON_LDFLAGS}"; then
+		PYTHON_LDFLAGS="-L`${PYTHON}-config --prefix`/lib"
+	fi
+else
+	if test "X$PYTHON_INCLUDES" = X -o "X$PYTHON_LDFLAGS" = X; then
+		AC_MSG_WARN([${PYTHON}-config does not exist or is not executable, so we could not detect python development environment.  Your system may require an additional package (e.g. "python3-dev").  Alternatively, if you are sure you have python headers and libraries, define PYTHON_INCLUDES and PYTHON_LDFLAGS and run this script.])
+	fi
+fi
 AC_SUBST(PYTHON_INCLUDES)
-for flag in `${PYTHON}-config --ldflags`; do
-	PYTHON_LDFLAGS="$PYTHON_LDFLAGS `echo $flag | sed -ne 's/^\(\-L.*\)$/\1/p'`"
-done
 AC_SUBST(PYTHON_LDFLAGS)
 
 CPPFLAGS_SAVED="$CPPFLAGS"
@@ -361,24 +376,32 @@ AC_CONFIG_FILES([Makefile
                  src/Makefile
                  src/bin/Makefile
                  src/bin/bind10/Makefile
+                 src/bin/bind10/tests/Makefile
                  src/bin/cmdctl/Makefile
+                 src/bin/cmdctl/tests/Makefile
                  src/bin/bindctl/Makefile
+                 src/bin/bindctl/tests/Makefile
                  src/bin/cfgmgr/Makefile
                  src/bin/host/Makefile
                  src/bin/loadzone/Makefile
                  src/bin/msgq/Makefile
+                 src/bin/msgq/tests/Makefile
                  src/bin/auth/Makefile
                  src/bin/auth/tests/Makefile
                  src/bin/xfrin/Makefile
+                 src/bin/xfrin/tests/Makefile
                  src/bin/xfrout/Makefile
+                 src/bin/xfrout/tests/Makefile
                  src/bin/usermgr/Makefile
                  src/lib/Makefile
                  src/lib/cc/Makefile
                  src/lib/python/Makefile
                  src/lib/python/isc/Makefile
-                 src/lib/python/isc/auth/Makefile
+                 src/lib/python/isc/datasrc/Makefile
                  src/lib/python/isc/cc/Makefile
+                 src/lib/python/isc/cc/tests/Makefile
                  src/lib/python/isc/config/Makefile
+                 src/lib/python/isc/config/tests/Makefile
                  src/lib/config/Makefile
                  src/lib/config/tests/Makefile
                  src/lib/dns/Makefile
@@ -386,8 +409,8 @@ AC_CONFIG_FILES([Makefile
                  src/lib/dns/python/Makefile
                  src/lib/dns-python/Makefile
                  src/lib/exceptions/Makefile
-                 src/lib/auth/Makefile
-                 src/lib/auth/tests/Makefile
+                 src/lib/datasrc/Makefile
+                 src/lib/datasrc/tests/Makefile
                  src/lib/xfr/Makefile
                ])
 AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
@@ -413,7 +436,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
            src/bin/usermgr/run_b10-cmdctl-usermgr.sh
            src/bin/usermgr/b10-cmdctl-usermgr.py
            src/bin/msgq/msgq.py
-           src/bin/msgq/msgq_test
+           src/bin/msgq/tests/msgq_test
            src/bin/msgq/run_msgq.sh
            src/bin/auth/auth.spec.pre
            src/bin/auth/spec_config.h
@@ -436,7 +459,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
            chmod +x src/bin/loadzone/run_loadzone.sh
            chmod +x src/bin/usermgr/run_b10-cmdctl-usermgr.sh
            chmod +x src/bin/msgq/run_msgq.sh
-           chmod +x src/bin/msgq/msgq_test
+           chmod +x src/bin/msgq/tests/msgq_test
            chmod +x src/lib/dns/gen-rdatacode.py
            chmod +x src/lib/dns/tests/testdata/gen-wiredata.py
            chmod +x src/lib/dns/python/tests/libdns_python_test

File diff suppressed because it is too large
+ 116 - 63
doc/guide/bind10-guide.html


+ 165 - 51
doc/guide/bind10-guide.xml

@@ -71,11 +71,12 @@
       </para>
 
       <note><para>
-        For the Y1 prototype release, the only supported data source
-        backend is SQLite3. The authoritative server requires
-        SQLite 3.3.9 or newer,
-        and the <command>b10-xfrin</command> module requires the
-        Python _sqlite3.so module.
+	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 libboost library, libpython3 library,
+	and the Python _sqlite3.so module.
       </para></note>
 <!-- TODO: this will change ... -->
 
@@ -104,9 +105,8 @@
       <para>
         At first, running many different processes may seem confusing.  However,
         these processes are started, stopped, and maintained by a single command,
-        <command>bind10</command>.  Additionally, most processes started by
-        the <command>bind10</command> command have names starting with "b10-",
-        with one exception, <command>msgq</command>.
+        <command>bind10</command>.  Additionally, the processes started by
+        the <command>bind10</command> command have names starting with "b10-".
       </para>
       
       <para>
@@ -122,7 +122,7 @@
         <itemizedlist>
           <listitem>
             <simpara>
-              <command>msgq</command> &mdash;
+              <command>b10-msgq</command> &mdash;
               message bus daemon.
               This process coordinates communication between all of the other
               BIND 10 processes.
@@ -154,11 +154,21 @@
             <simpara>
               <command>b10-xfrin</command> &mdash;
               Incoming zone transfer service.
-              This process is started as needed to transfer a new copy
+              This process is used to transfer a new copy
               of a zone into BIND 10, when acting as a secondary server.
             </simpara>
           </listitem>
 
+          <listitem>
+            <simpara>
+              <command>b10-xfrout</command> &mdash;
+              Outgoing zone transfer service.
+	      This process is used to handle transfer requests to
+	      send a local zone to a remote secondary server,
+	      when acting as a master server.
+            </simpara>
+          </listitem>
+
         </itemizedlist>
       </para>
     </section>
@@ -259,6 +269,17 @@ var/
         </para>
 
         <para>
+	  The Boost Library, Boost Python library, Python Library,
+	  and Python _sqlite3 module are required to enable the
+	  Xfrout and Xfrin support.
+        </para>
+
+        <note><simpara>
+          The Python related libraries and modules need to be built
+          for Python 3.1.
+        </simpara></note>
+
+        <para>
           If the Boost System Library is detected at configure time,
           BIND 10 will be built using an alternative method for
           networking I/O using Boost ASIO support.  This provides
@@ -279,7 +300,7 @@ implementation in BIND 10.
           Building BIND 10 also requires a C++ compiler and
           standard development headers.
           BIND 10 builds have been tested with GCC g++ 3.4.3, 4.1.2,
-          4.2.1, 4.3.2, and 4.4.1.
+          4.1.3, 4.2.1, 4.3.2, and 4.4.1.
         </para>
     </section>
 
@@ -296,7 +317,7 @@ implementation in BIND 10.
 
       <note>
         <simpara>
-          The Y1 prototype of the b10-auth server listens on
+          The development prototype of the b10-auth server listens on
           0.0.0.0 (all interfaces) port 5300. (This is not the standard
           domain service port.)
         </simpara>
@@ -422,9 +443,7 @@ implementation in BIND 10.
           and un-reviewed code, is available via the BIND 10 code revision
           control system. This is powered by Subversion and all the BIND 10
           development is public.
-          The leading development is done in the <quote>trunk</quote>
-          and the reviewed code is in
-          <filename>branches/REVIEWED</filename>.
+          The leading development is done in the <quote>trunk</quote>.
         </para>
         <para>
           The code can be checked out from <filename>svn://bind10.isc.org/svn/bind10</filename>; for example to check out the trunk:
@@ -465,43 +484,61 @@ implementation in BIND 10.
           <variablelist>
 
           <varlistentry>
-            <term>--with-boostlib</term>
+            <term>--prefix</term>
+            <listitem>
+              <simpara>Define the the installation location (the
+                default is <filename>/usr/local/</filename>).
+              </simpara>
+            </listitem> 
+          </varlistentry>
+
+          <varlistentry>
+            <term>--with-boost-include</term>
             <listitem> 
-              <simpara>Define the path to find the Boost system library.
+              <simpara>Define the path to find the Boost headers.
               </simpara>
             </listitem> 
           </varlistentry>
 
           <varlistentry>
-            <term>--without-boostlib</term> or
-            <term>--with-boostlib=no</term>
+            <term>--with-boost-lib</term>
             <listitem> 
-              <simpara>Disable the Boost ASIO support.</simpara>
+              <simpara>Define the path to find the Boost library.
+              </simpara>
             </listitem> 
           </varlistentry>
 
           <varlistentry>
-            <term>--with-pythonpath</term>
+            <term>--with-boost-python</term>
             <listitem> 
-              <simpara>Define the path to Python 3.1 if it is not in the
-                standard execution path.
+              <simpara>Define to use the Boost Python library.
               </simpara>
             </listitem> 
           </varlistentry>
 
           <varlistentry>
-            <term>--with-boost-include</term>
+            <term>--with-boost-system</term>
             <listitem> 
-              <simpara>Define the path to find the Boost headers.
+              <simpara>Define to use the Boost System library.
               </simpara>
             </listitem> 
           </varlistentry>
 
           <varlistentry>
-            <term>--prefix</term>
-            <listitem>
-        <simpara>Define the the installation location (the
-          default is <filename>/usr/local/</filename>).
+            <term>--with-pythonpath</term>
+            <listitem> 
+              <simpara>Define the path to Python 3.1 if it is not in the
+                standard execution path.
+              </simpara>
+            </listitem> 
+          </varlistentry>
+
+          <varlistentry>
+            <term>--with-gtest</term>
+            <listitem> 
+              <simpara>Enable building the C++ Unit Tests using the
+                Google Tests framework. Optionally this can define the
+                path to the gtest header files and library.
               </simpara>
             </listitem> 
           </varlistentry>
@@ -509,15 +546,17 @@ implementation in BIND 10.
           </variablelist>
 
         </para>
-  <!-- TODO: gtest, lcov -->
+  <!-- TODO: lcov -->
 
         <para>
           For example, the following configures it to build
     with BOOST ASIO support, find the Boost headers, find the
     Python interpreter, and sets the installation location:
 
-          <screen>$ <userinput>./configure --with-boostlib=/usr/pkg/lib \
+          <screen>$ <userinput>./configure --with-boost-lib=/usr/pkg/lib \
       --with-boost-include=/usr/pkg/include \
+      --with-boost-python \
+      --with-boost-system \
       --with-pythonpath=/usr/pkg/bin/python3.1 \
       --prefix=/opt/bind10</userinput></screen>
         </para>
@@ -550,6 +589,14 @@ implementation in BIND 10.
           <para>The install step may require superuser privileges.</para>
         </note>
 
+<!-- Trac #148 -->
+        <note><simpara>
+	  Depending on your system and the location of your Boost
+	  Python and Python shared libraries, you may need to
+	  configure your run-time linker to find them (such as
+	  setting LD_LIBRARY_PATH).
+        </simpara></note>
+
       </section>
 
   <!-- TODO: tests -->
@@ -636,15 +683,15 @@ implementation in BIND 10.
     </para>
 
     <para>
-      After starting the <command>msgq</command> communications channel,
+      After starting the <command>b10-msgq</command> communications channel,
       <command>bind10</command> connects to it, 
       runs the configuration manager, and reads its own configuration.
       Then it starts the other modules.
     </para>
 
     <para>
-      The <command>msgq</command> and <command>b10-cfgmgr</command>
-      services make up the core. The <command>msgq</command> daemon
+      The <command>b10-msgq</command> and <command>b10-cfgmgr</command>
+      services make up the core. The <command>b10-msgq</command> daemon
       provides the communication channel between every part of the system.
       The <command>b10-cfgmgr</command> daemon is always needed by every
       module, if only to send information about themselves somewhere,
@@ -653,7 +700,8 @@ implementation in BIND 10.
       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,
-      and <command>b10-xfrin</command> for inbound DNS zone transfers.
+      <command>b10-xfrin</command> for inbound DNS zone transfers.
+      and <command>b10-xfrout</command> for outbound DNS zone transfers.
     </para>
 
     <section id="start">
@@ -672,9 +720,9 @@ implementation in BIND 10.
     <title>Command channel</title>
 
       <para>
-        The BIND 10 components use the <command>msgq</command>
+        The BIND 10 components use the <command>b10-msgq</command>
         message routing daemon to communicate with other BIND 10 components.
-        The <command>msgq</command> implements what is called the
+        The <command>b10-msgq</command> implements what is called the
         <quote>Command Channel</quote>.
         Processes intercommunicate by sending messages on the command
         channel.
@@ -686,17 +734,19 @@ implementation in BIND 10.
 
       <para>
         Administrators do not communicate directly with the
-        <command>msgq</command> daemon.
+        <command>b10-msgq</command> daemon.
         By default, BIND 10 uses port 9912 for the
-        <command>msgq</command> service.
+        <command>b10-msgq</command> service.
         It listens on 127.0.0.1.
       </para>
       
+<!-- TODO: this is broken, see Trac #111
       <para>
-        To select an alternate port for the <command>msgq</command> to
+        To select an alternate port for the <command>b10-msgq</command> to
         use, run <command>bind10</command> specifying the option:
-        <screen> $ <userinput>bind10 --msgq-port 9912</userinput></screen>
+        <screen> $ <userinput>bind10 -TODO-msgq-port 9912</userinput></screen>
       </para>
+-->
 
 <!-- TODO: upcoming plans:
 Unix domain sockets
@@ -717,7 +767,7 @@ Unix domain sockets
       <para>
         The <command>b10-auth</command> and <command>b10-xfrin</command>
         daemons and other components receive their configurations
-        from the configuration manager over the <command>msgq</command>
+        from the configuration manager over the <command>b10-msgq</command>
         command channel.
       </para>
 
@@ -730,7 +780,7 @@ Unix domain sockets
 <!-- TODO -->
       <note>
         <para>
-          The Y1 prototype release only provides the
+          The development prototype release only provides the
           <command>bindctl</command> as a user interface to
           <command>b10-cmdctl</command>.
           Upcoming releases will provide another interactive command-line
@@ -826,7 +876,7 @@ options for that module
       When <command>b10-cmdctl</command> starts, it firsts
       asks <command>b10-cfgmgr</command> about what modules are
       running and what their configuration is (over the
-      <command>msgq</command> channel). Then it will start listening
+      <command>b10-msgq</command> channel). Then it will start listening
       on HTTPS for clients &mdash; the user interface &mdash; such
       as <command>bindctl</command>.
     </para>
@@ -956,7 +1006,7 @@ TODO
     <title>Control and configure user interface</title>
 
     <note><para>
-      For the Y1 prototype release, <command>bindctl</command>
+      For this development prototype release, <command>bindctl</command>
       is the only user interface. It is expected that upcoming
       releases will provide another interactive command-line
       interface and a web-based interface for controlling and
@@ -979,9 +1029,9 @@ TODO
       <command>b10-cfgmgr</command>. So when <command>bindctl</command>
       sends a configuration, it is sent to <command>b10-cmdctl</command>
       (over a HTTPS connection); then <command>b10-cmdctl</command>
-      sends the command (over a <command>msgq</command> command
+      sends the command (over a <command>b10-msgq</command> command
       channel) to <command>b10-cfgmgr</command> which then stores
-      the details and relays (over a <command>msgq</command> command
+      the details and relays (over a <command>b10-msgq</command> command
       channel) the configuration on to the specified module.
     </para>
 
@@ -1001,8 +1051,8 @@ TODO
     </para>
 
     <note><simpara>
-      The Y1 prototype release listens on all interfaces and the non-standard
-      port 5300.
+      This development prototype release listens on all interfaces
+      and the non-standard port 5300.
     </simpara></note>
 
     <section>
@@ -1062,7 +1112,7 @@ This may be a temporary setting until then.
       <title>Data Source Backends</title>
 
       <note><para>
-        For the Y1 prototype release, <command>b10-auth</command>
+        For the development prototype release, <command>b10-auth</command>
         only supports the SQLite3 data source backend.
         Upcoming versions will be able to use multiple different
         data sources, such as MySQL, Berkeley DB, or in-memory DB.
@@ -1132,7 +1182,8 @@ This may be a temporary setting until then.
 
       <note>
       <para>
-        In the Y1 prototype release, only the SQLite3 back end is used.
+        In the development prototype release, only the SQLite3 back
+        end is used.
         By default, it stores the zone data in
         <filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>
         unless the <option>-d</option> switch is used to set the
@@ -1162,6 +1213,69 @@ TODO
 
   </chapter>
 
+  <chapter id="xfrin">
+    <title>Incoming Zone Transfers</title>
+
+    <para>
+      The <command>b10-xfrin</command> process is started by
+      <command>bind10</command>.
+      It can be manually triggered to request an AXFR zone
+      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.
+    </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>
+       To manually trigger a zone transfer to retrieve a remote zone,
+       you may use the <command>bindctl</command> utility.
+       For example, at the <command>bindctl</command> prompt run:
+
+       <screen>&gt; <userinput>Xfrin retransfer zone_name="<option>foo.example.org</option>" master=<option>192.0.2.99</option></userinput></screen>
+    </para>
+
+  </chapter>
+
+  <chapter id="xfrout">
+    <title>Outbound Zone Transfers</title>
+
+    <para>
+      The <command>b10-xfrout</command> process is started by
+      <command>bind10</command>.
+      When the <command>b10-auth</command> authoritative DNS server
+      receives an AXFR request, <command>b10-xfrout</command>
+      sends the zone.
+      This is used to provide master DNS service to share zones
+      to secondary name servers.
+    </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>
+
+
+<!--
+TODO:
+xfrout section:
+auth servers checks for AXFR query
+sends the XFR query to the xfrout module
+uses /tmp/auth_xfrout_conn which is a socket
+what is XfroutClient xfr_client??
+/tmp/auth_xfrout_conn is not removed
+-->
+
+  </chapter>
+
 <!-- TODO: how to help: run unit tests, join lists, review trac tickets -->
 
   <!-- <index>    <title>Index</title> </index> -->

+ 2 - 2
src/bin/auth/Makefile.am

@@ -27,8 +27,8 @@ pkglibexec_PROGRAMS = b10-auth
 b10_auth_SOURCES = auth_srv.cc auth_srv.h
 b10_auth_SOURCES += common.h
 b10_auth_SOURCES += main.cc
-b10_auth_LDADD =  $(top_builddir)/src/lib/auth/.libs/libauth.a
-b10_auth_LDADD +=  $(top_builddir)/src/lib/dns/.libs/libdns.a
+b10_auth_LDADD =  $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
+b10_auth_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a
 b10_auth_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
 b10_auth_LDADD += $(top_builddir)/src/lib/cc/libcc.a
 b10_auth_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a

+ 5 - 5
src/bin/auth/auth_srv.cc

@@ -33,10 +33,10 @@
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
 
-#include <auth/query.h>
-#include <auth/data_source.h>
-#include <auth/static_datasrc.h>
-#include <auth/sqlite3_datasrc.h>
+#include <datasrc/query.h>
+#include <datasrc/data_source.h>
+#include <datasrc/static_datasrc.h>
+#include <datasrc/sqlite3_datasrc.h>
 
 #include <cc/data.h>
 
@@ -48,7 +48,7 @@
 using namespace std;
 
 using namespace isc;
-using namespace isc::auth;
+using namespace isc::datasrc;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
 using namespace isc::data;

+ 4 - 7
src/bin/auth/b10-auth.8

@@ -29,19 +29,16 @@ The
 \fBb10\-auth\fR
 daemon provides the BIND 10 authoritative DNS server\&. Normally it is started by the
 \fBbind10\fR(8)
-master process\&.
+boss process\&.
 .PP
 This daemon communicates with other BIND 10 components over a
-\fBmsgq\fR(8)
+\fBb10-msgq\fR(8)
 C\-Channel connection\&. If this connection is not established,
 \fBb10\-auth\fR
 will exit\&.
 .PP
 It also receives its configurations from
-\fBb10-cfgmgr\fR(8)
-(via the
-\fBmsgq\fR(8)
-command channel)\&. It will honor the
+\fBb10-cfgmgr\fR(8)\&. It will honor the
 \fIdatabase_file\fR
 configuration to point to the SQLite3 zone file\&.
 .if n \{\
@@ -113,8 +110,8 @@ configuration is not defined\&.
 \fBb10-cfgmgr\fR(8),
 \fBb10-cmdctl\fR(8),
 \fBb10-loadzone\fR(8),
+\fBb10-msgq\fR(8),
 \fBbind10\fR(8),
-\fBmsgq\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"
 .PP

+ 5 - 8
src/bin/auth/b10-auth.xml

@@ -58,12 +58,12 @@
       authoritative DNS server.
       Normally it is started by the
       <citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      master process.
+      boss process.
     </para>
 
     <para>
       This daemon communicates with other BIND 10 components over a
-      <citerefentry><refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      <citerefentry><refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
       C-Channel connection.  If this connection is not established,
       <command>b10-auth</command> will exit.
 <!-- TODO what if msgq connection closes later, will b10-auth exit? -->
@@ -71,10 +71,7 @@
 
     <para>
       It also receives its configurations from
-<citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      (via the
-      <citerefentry><refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      command channel).
+<citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
       It will honor the <emphasis>database_file</emphasis> configuration
       to point to the SQLite3 zone file.
 
@@ -158,10 +155,10 @@
         <refentrytitle>b10-loadzone</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
-        <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
-        <refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>

+ 1 - 1
src/bin/auth/main.cc

@@ -130,7 +130,7 @@ check_axfr_query(char *msg_data, uint16_t msg_len)
 static void
 dispatch_axfr_query(int tcp_sock, char axfr_query[], uint16_t query_len)
 {
-    std::string path = "/tmp/auth_xfrout_conn";
+    std::string path = string(UNIX_SOCKET_FILE);
     XfroutClient xfr_client(path);
     try {
         xfr_client.connect();

+ 15 - 0
src/bin/auth/spec_config.h.in

@@ -1 +1,16 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
 #define AUTH_SPECFILE_LOCATION "@prefix@/share/@PACKAGE@/auth.spec"
+#define UNIX_SOCKET_FILE "@prefix@/var/auth_xfrout_conn"

+ 2 - 1
src/bin/auth/tests/Makefile.am

@@ -1,5 +1,6 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
+AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
 
 CLEANFILES = *.gcno *.gcda
 
@@ -15,7 +16,7 @@ run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD = $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
-run_unittests_LDADD +=  $(top_builddir)/src/lib/auth/.libs/libauth.a
+run_unittests_LDADD +=  $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a
 run_unittests_LDADD +=  $(top_builddir)/src/lib/dns/.libs/libdns.a
 run_unittests_LDADD += $(top_builddir)/src/lib/config/.libs/libcfgclient.a
 run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a

+ 15 - 14
src/bin/auth/tests/auth_srv_unittest.cc

@@ -35,11 +35,12 @@ using namespace isc::dns;
 using namespace isc::data;
 
 namespace {
-const char* CONFIG_TESTDB = "{\"database_file\": \"testdata/example.sqlite3\"}";
+const char* CONFIG_TESTDB =
+    "{\"database_file\": \"" TEST_DATA_DIR "/example.sqlite3\"}";
 // The following file must be non existent and must be non"creatable" (see
 // the sqlite3 test).
 const char* BADCONFIG_TESTDB =
-    "{ \"database_file\": \"testdata/nodir/notexist\"}";
+    "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}";
 
 class AuthSrvTest : public ::testing::Test {
 protected:
@@ -117,7 +118,7 @@ TEST_F(AuthSrvTest, unsupportedRequest) {
     for (unsigned int i = 1; i < 16; ++i) {
         // set Opcode to 'i', which iterators over all possible codes except
         // the standard query (0)
-        createDataFromFile("testdata/simplequery_fromWire");
+        createDataFromFile("simplequery_fromWire");
         data[2] = ((i << 3) & 0xff);
 
         parse_message.clear(Message::PARSE);
@@ -139,7 +140,7 @@ TEST_F(AuthSrvTest, verbose) {
 
 // Multiple questions.  Should result in FORMERR.
 TEST_F(AuthSrvTest, multiQuestion) {
-    createDataFromFile("testdata/multiquestion_fromWire");
+    createDataFromFile("multiquestion_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
     headerCheck(parse_message, default_qid, Rcode::FORMERR(), opcode.getCode(),
@@ -160,7 +161,7 @@ TEST_F(AuthSrvTest, multiQuestion) {
 // Incoming data doesn't even contain the complete header.  Must be silently
 // dropped.
 TEST_F(AuthSrvTest, shortMessage) {
-    createDataFromFile("testdata/shortmessage_fromWire");
+    createDataFromFile("shortmessage_fromWire");
     EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
                                            response_renderer, true));
 }
@@ -169,25 +170,25 @@ TEST_F(AuthSrvTest, shortMessage) {
 // or malformed or could otherwise cause a protocol error.
 TEST_F(AuthSrvTest, response) {
     // A valid (although unusual) response
-    createDataFromFile("testdata/simpleresponse_fromWire");
+    createDataFromFile("simpleresponse_fromWire");
     EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
                                            response_renderer, true));
 
     // A response with a broken question section.  must be dropped rather than
     // returning FORMERR.
-    createDataFromFile("testdata/shortresponse_fromWire");
+    createDataFromFile("shortresponse_fromWire");
     EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
                                            response_renderer, true));
 
     // A response to iquery.  must be dropped rather than returning NOTIMP.
-    createDataFromFile("testdata/iqueryresponse_fromWire");
+    createDataFromFile("iqueryresponse_fromWire");
     EXPECT_EQ(false, server.processMessage(*ibuffer, parse_message,
                                            response_renderer, true));
 }
 
 // Query with a broken question
 TEST_F(AuthSrvTest, shortQuestion) {
-    createDataFromFile("testdata/shortquestion_fromWire");
+    createDataFromFile("shortquestion_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
     // Since the query's question is broken, the question section of the
@@ -198,7 +199,7 @@ TEST_F(AuthSrvTest, shortQuestion) {
 
 // Query with a broken answer section
 TEST_F(AuthSrvTest, shortAnswer) {
-    createDataFromFile("testdata/shortanswer_fromWire");
+    createDataFromFile("shortanswer_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
 
@@ -217,7 +218,7 @@ TEST_F(AuthSrvTest, shortAnswer) {
 
 // Query with unsupported version of EDNS.
 TEST_F(AuthSrvTest, ednsBadVers) {
-    createDataFromFile("testdata/queryBadEDNS_fromWire");
+    createDataFromFile("queryBadEDNS_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
 
@@ -251,7 +252,7 @@ TEST_F(AuthSrvTest, updateConfig) {
     // query for existent data in the installed data source.  The resulting
     // response should have the AA flag on, and have an RR in each answer
     // and authority section.
-    createDataFromFile("testdata/examplequery_fromWire");
+    createDataFromFile("examplequery_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
     headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),
@@ -265,7 +266,7 @@ TEST_F(AuthSrvTest, datasourceFail) {
     // tool and the data source itself naively accept it).  This will result
     // in a SERVFAIL response, and the answer and authority sections should
     // be empty.
-    createDataFromFile("testdata/badExampleQuery_fromWire");
+    createDataFromFile("badExampleQuery_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
     headerCheck(parse_message, default_qid, Rcode::SERVFAIL(), opcode.getCode(),
@@ -280,7 +281,7 @@ TEST_F(AuthSrvTest, updateConfigFail) {
     updateConfig(&server, BADCONFIG_TESTDB, false);
 
     // The original data source should still exist.
-    createDataFromFile("testdata/examplequery_fromWire");
+    createDataFromFile("examplequery_fromWire");
     EXPECT_EQ(true, server.processMessage(*ibuffer, parse_message,
                                           response_renderer, true));
     headerCheck(parse_message, default_qid, Rcode::NOERROR(), opcode.getCode(),

+ 4 - 0
src/bin/auth/tests/run_unittests.cc

@@ -16,9 +16,13 @@
 
 #include <gtest/gtest.h>
 
+#include <dns/tests/unittest_util.h>
+
 int
 main(int argc, char* argv[])
 {
     ::testing::InitGoogleTest(&argc, argv);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+
     return (RUN_ALL_TESTS());
 }

+ 4 - 2
src/bin/bind10/Makefile.am

@@ -1,5 +1,7 @@
+SUBDIRS = tests
+
 sbin_SCRIPTS = bind10
-CLEANFILES = bind10
+CLEANFILES = bind10 bind10.pyc
 
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
@@ -8,7 +10,7 @@ bind10_DATA = bob.spec
 EXTRA_DIST = bob.spec
 
 man_MANS = bind10.8
-EXTRA_DIST += $(man_MANS) bind10.xml tests/bind10_test.py
+EXTRA_DIST += $(man_MANS) bind10.xml
 
 if ENABLE_MAN
 

+ 3 - 0
src/bin/bind10/TODO

@@ -14,3 +14,6 @@
 - Rename "c-channel" stuff to msgq for clarity
 - Use logger
 - Reply to shutdown message?
+- Some sort of group creation so termination signals can be sent to
+  children of children processes (if any)
+

+ 5 - 5
src/bin/bind10/bind10.8

@@ -2,12 +2,12 @@
 .\"     Title: bind10
 .\"    Author: [see the "AUTHORS" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: March 18, 2010
+.\"      Date: April 19, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "BIND10" "8" "March 18, 2010" "BIND10" "BIND10"
+.TH "BIND10" "8" "April 19, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -19,7 +19,7 @@
 .\" * MAIN CONTENT STARTS HERE *
 .\" -----------------------------------------------------------------
 .SH "NAME"
-bind10 \- BIND 10 master process
+bind10 \- BIND 10 boss process
 .SH "SYNOPSIS"
 .HP \w'\fBbind10\fR\ 'u
 \fBbind10\fR [\fB\-m\ \fR\fB\fInumber\fR\fR] [\fB\-p\ \fR\fB\fInumber\fR\fR] [\fB\-v\fR] [\fB\-msgq\-port\ \fR\fB\fInumber\fR\fR] [\fB\-port\ \fR\fB\fInumber\fR\fR] [\fB\-verbose\fR]
@@ -35,7 +35,7 @@ The arguments are as follows:
 \fB\-m\fR \fInumber\fR, \fB\-\-msgq\-port\fR \fInumber\fR
 .RS 4
 The port number for the
-\fBmsgq\fR(8)
+\fBb10-msgq\fR(8)
 daemon to listen on\&. The default is 9912\&.
 .RE
 .PP
@@ -74,8 +74,8 @@ and its child processes\&.
 \fBb10-auth\fR(8),
 \fBb10-cfgmgr\fR(8),
 \fBb10-cmdctl\fR(8),
+\fBb10-msgq\fR(8),
 \fBb10-xfrin\fR(8),
-\fBmsgq\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"
 .PP

+ 73 - 52
src/bin/bind10/bind10.py.in

@@ -1,5 +1,20 @@
 #!@PYTHON@
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 """\
 This file implements the Boss of Bind (BoB, or bob) program.
 
@@ -108,30 +123,33 @@ class ProcessInfo:
             spawn_stdout = self.dev_null
         else:
             spawn_stdout = None
-        spawn_env = self.env
-        spawn_env['PATH'] = os.environ['PATH']
-        if 'B10_FROM_SOURCE' in os.environ:
-            spawn_env['B10_FROM_SOURCE'] = os.environ['B10_FROM_SOURCE']
-        else: 
+        if self.dev_null_stderr:
+            spawn_stderr = self.dev_null
+        else:
+            spawn_stderr = None
+        # Environment variables for the child process will be a copy of those
+        # of the boss process with any additional specific variables given
+        # on construction (self.env).
+        spawn_env = os.environ
+        spawn_env.update(self.env)
+        if not 'B10_FROM_SOURCE' in os.environ:
             spawn_env['PATH'] = "@@LIBEXECDIR@@:" + spawn_env['PATH']
-        if 'PYTHON_EXEC' in os.environ:
-            spawn_env['PYTHON_EXEC'] = os.environ['PYTHON_EXEC']
-        if 'PYTHONPATH' in os.environ:
-            spawn_env['PYTHONPATH'] = os.environ['PYTHONPATH']
         self.process = subprocess.Popen(self.args,
                                         stdin=subprocess.PIPE,
                                         stdout=spawn_stdout,
-                                        stderr=spawn_stdout,
+                                        stderr=spawn_stderr,
                                         close_fds=True,
                                         env=spawn_env,)
         self.pid = self.process.pid
         self.restart_schedule.set_run_start_time()
 
-    def __init__(self, name, args, env={}, dev_null_stdout=False):
+    def __init__(self, name, args, env={}, dev_null_stdout=False,
+                 dev_null_stderr=False):
         self.name = name 
         self.args = args
         self.env = env
         self.dev_null_stdout = dev_null_stdout
+        self.dev_null_stderr = dev_null_stderr
         self.restart_schedule = RestartSchedule()
         self._spawn()
 
@@ -161,7 +179,7 @@ class BoB:
 
     def config_handler(self, new_config):
         if self.verbose:
-            print("[XX] handling new config:")
+            print("[bind10] handling new config:")
             print(new_config)
         answer = isc.config.ccsession.create_answer(0)
         return answer
@@ -169,15 +187,15 @@ class BoB:
 
     def command_handler(self, command, args):
         if self.verbose:
-            print("[XX] Boss got command:")
+            print("[bind10] Boss got command:")
             print(command)
-        answer = [ 1, "Command not implemented" ]
+        answer = isc.config.ccsession.create_answer(1, "command not implemented")
         if type(command) != str:
             answer = isc.config.ccsession.create_answer(1, "bad command")
         else:
             cmd = command
             if cmd == "shutdown":
-                print("[XX] got shutdown command")
+                print("[bind10] got shutdown command")
                 self.runnable = False
                 answer = isc.config.ccsession.create_answer(0)
             elif cmd == "print_message":
@@ -185,7 +203,7 @@ class BoB:
                     print(args)
                 answer = isc.config.ccsession.create_answer(0, args)
             elif cmd == "print_settings":
-                print("Full Config:")
+                print("[bind10] Full Config:")
                 full_config = self.ccs.get_full_config()
                 for item in full_config:
                     print(item + ": " + str(full_config[item]))
@@ -204,25 +222,26 @@ class BoB:
         # to see if it is already running
         c_channel_env = { "ISC_MSGQ_PORT": str(self.c_channel_port), }
         if self.verbose:
-            sys.stdout.write("Checking for already running msgq\n")
+            sys.stdout.write("Checking for already running b10-msgq\n")
         # try to connect, and if we can't wait a short while
         try:
             self.cc_session = isc.cc.Session(self.c_channel_port)
-            return "msgq already running, cannot start"
+            return "b10-msgq already running, cannot start"
         except isc.cc.session.SessionError:
             pass
 
         # start the c-channel daemon
         if self.verbose:
-            sys.stdout.write("Starting msgq using port %d\n" % 
+            sys.stdout.write("Starting b10-msgq using port %d\n" % 
                              self.c_channel_port)
         try:
-            c_channel = ProcessInfo("msgq", ["msgq"], c_channel_env, True)
+            c_channel = ProcessInfo("b10-msgq", ["b10-msgq"], c_channel_env,
+                                    True, not self.verbose)
         except Exception as e:
-            return "Unable to start msgq; " + str(e)
+            return "Unable to start b10-msgq; " + str(e)
         self.processes[c_channel.pid] = c_channel
         if self.verbose:
-            sys.stdout.write("Started msgq (PID %d)\n" % c_channel.pid)
+            sys.stdout.write("Started b10-msgq (PID %d)\n" % c_channel.pid)
 
         # now connect to the c-channel
         cc_connect_start = time.time()
@@ -240,7 +259,7 @@ class BoB:
 
         # start the configuration manager
         if self.verbose:
-            sys.stdout.write("Starting b10-cfgmgr\n")
+            sys.stdout.write("[bind10] Starting b10-cfgmgr\n")
         try:
             bind_cfgd = ProcessInfo("b10-cfgmgr", ["b10-cfgmgr"],
                                     { 'ISC_MSGQ_PORT': str(self.c_channel_port)})
@@ -249,7 +268,7 @@ class BoB:
             return "Unable to start b10-cfgmgr; " + str(e)
         self.processes[bind_cfgd.pid] = bind_cfgd
         if self.verbose:
-            sys.stdout.write("Started b10-cfgmgr (PID %d)\n" % bind_cfgd.pid)
+            sys.stdout.write("[bind10] Started b10-cfgmgr (PID %d)\n" % bind_cfgd.pid)
 
         # TODO: once this interface is done, replace self.cc_session
         # by this one
@@ -259,11 +278,11 @@ class BoB:
         # message
         time.sleep(1)
         if self.verbose:
-            print("[XX] starting ccsession")
+            print("[bind10] starting ccsession")
         self.ccs = isc.config.ModuleCCSession(SPECFILE_LOCATION, self.config_handler, self.command_handler)
         self.ccs.start()
         if self.verbose:
-            print("[XX] ccsession started")
+            print("[bind10] ccsession started")
 
         # start the xfrout before auth-server, to make sure every xfr-query can be
         # processed properly.
@@ -271,7 +290,7 @@ class BoB:
             sys.stdout.write("Starting b10-xfrout\n")
         try:
             xfrout = ProcessInfo("b10-xfrout", ["b10-xfrout"], 
-								 { 'ISC_MSGQ_PORT': str(self.c_channel_port)})
+                                 { 'ISC_MSGQ_PORT': str(self.c_channel_port)})
         except Exception as e:
             c_channel.process.kill()
             bind_cfgd.process.kill()
@@ -299,7 +318,7 @@ class BoB:
         if self.verbose:
             sys.stdout.write("Started b10-auth (PID %d)\n" % auth.pid)
 
-        # start the b10-xfrin
+        # start b10-xfrin
         if self.verbose:
             sys.stdout.write("Starting b10-xfrin\n")
         try:
@@ -343,6 +362,8 @@ class BoB:
         self.cc_session.group_sendmsg(cmd, 'Boss', 'Cmd-Ctrld')
         self.cc_session.group_sendmsg(cmd, "Boss", "ConfigManager")
         self.cc_session.group_sendmsg(cmd, "Boss", "Auth")
+        self.cc_session.group_sendmsg(cmd, "Boss", "Xfrout")
+        self.cc_session.group_sendmsg(cmd, "Boss", "Xfrin")
 
     def stop_process(self, process):
         """Stop the given process, friendly-like."""
@@ -359,11 +380,10 @@ class BoB:
         except:
             pass
         # XXX: some delay probably useful... how much is uncertain
-        time.sleep(0.1)  
+        time.sleep(0.5)  
         self.reap_children()
         # next try sending a SIGTERM
         processes_to_stop = list(self.processes.values())
-        unstopped_processes = []
         for proc_info in processes_to_stop:
             if self.verbose:
                 sys.stdout.write("Sending SIGTERM to %s (PID %d).\n" % 
@@ -374,21 +394,22 @@ class BoB:
                 # ignore these (usually ESRCH because the child
                 # finally exited)
                 pass
-        # XXX: some delay probably useful... how much is uncertain
-        time.sleep(0.1)  
-        self.reap_children()
-        # finally, send a SIGKILL (unmaskable termination)
-        processes_to_stop = unstopped_processes
-        for proc_info in processes_to_stop:
-            if self.verbose:
-                sys.stdout.write("Sending SIGKILL to %s (PID %d).\n" % 
-                                 (proc_info.name, proc_info.pid))
-            try:
-                proc_info.process.kill()
-            except OSError:
-                # ignore these (usually ESRCH because the child
-                # finally exited)
-                pass
+        # finally, send SIGKILL (unmaskable termination) until everybody dies
+        while self.processes:
+            # XXX: some delay probably useful... how much is uncertain
+            time.sleep(0.1)  
+            self.reap_children()
+            processes_to_stop = list(self.processes.values())
+            for proc_info in processes_to_stop:
+                if self.verbose:
+                    sys.stdout.write("Sending SIGKILL to %s (PID %d).\n" % 
+                                     (proc_info.name, proc_info.pid))
+                try:
+                    proc_info.process.kill()
+                except OSError:
+                    # ignore these (usually ESRCH because the child
+                    # finally exited)
+                    pass
         if self.verbose:
             sys.stdout.write("All processes ended, server done.\n")
 
@@ -411,10 +432,10 @@ class BoB:
                 if self.verbose:
                     sys.stdout.write("Process %s (PID %d) died.\n" % 
                                      (proc_info.name, proc_info.pid))
-                if proc_info.name == "msgq":
+                if proc_info.name == "b10-msgq":
                     if self.verbose and self.runnable:
                         sys.stdout.write(
-                                     "The msgq process died, shutting down.\n")
+                                     "The b10-msgq process died, shutting down.\n")
                     self.runnable = False
             else:
                 sys.stdout.write("Unknown child pid %d exited.\n" % pid)
@@ -495,13 +516,13 @@ class BoB:
                 still_dead[proc_info.pid] = proc_info
             else:
                 if self.verbose:
-                    sys.stdout.write("Resurrecting dead %s process...\n" % 
+                    sys.stdout.write("[bind10] Resurrecting dead %s process...\n" % 
                                      proc_info.name)
                 try:
                     proc_info.respawn()
                     self.processes[proc_info.pid] = proc_info
                     if self.verbose:
-                        sys.stdout.write("Resurrected %s (PID %d)\n" %
+                        sys.stdout.write("[bind10] Resurrected %s (PID %d)\n" %
                                          (proc_info.name, proc_info.pid))
                 except:
                     still_dead[proc_info.pid] = proc_info
@@ -535,7 +556,7 @@ def fatal_signal(signal_number, stack_frame):
     global options
     global boss_of_bind
     if options.verbose:
-        sys.stdout.write("Received %s.\n" % get_signame(signal_number))
+        sys.stdout.write("[bind10] Received %s.\n" % get_signame(signal_number))
     signal.signal(signal.SIGCHLD, signal.SIG_DFL)
     boss_of_bind.runnable = False
 
@@ -563,7 +584,7 @@ def main():
                       help="port the b10-auth daemon will use (default 5300)")
     parser.add_option("-m", "--msgq-port", dest="msgq_port", type="string",
                       action="callback", callback=check_port, default="9912",
-                      help="port the msgq daemon will use (default 9912)")
+                      help="port the b10-msgq daemon will use (default 9912)")
     (options, args) = parser.parse_args()
 
     # Announce startup.
@@ -586,7 +607,7 @@ def main():
     signal.signal(signal.SIGTERM, fatal_signal)
 
     # Go bob!
-    boss_of_bind = BoB(int(options.msgq_port), int(options.auth_port), \
+    boss_of_bind = BoB(int(options.msgq_port), int(options.auth_port),
                        options.verbose)
     startup_result = boss_of_bind.startup()
     if startup_result:

+ 5 - 5
src/bin/bind10/bind10.xml

@@ -21,7 +21,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>March 18, 2010</date>
+    <date>April 19, 2010</date>
   </refentryinfo>
 
   <refmeta>
@@ -32,7 +32,7 @@
 
   <refnamediv>
     <refname>bind10</refname>
-    <refpurpose>BIND 10 master process</refpurpose>
+    <refpurpose>BIND 10 boss process</refpurpose>
   </refnamediv>
 
   <docinfo>
@@ -84,7 +84,7 @@
 
         <listitem>
           <para>The port number for the
-	    <citerefentry><refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+	    <citerefentry><refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
             daemon to listen on.
             The default is 9912.</para>
          </listitem>
@@ -139,10 +139,10 @@
         <refentrytitle>b10-cmdctl</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
-        <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
-        <refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>b10-xfrin</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>

+ 15 - 0
src/bin/bind10/run_bind10.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 12 - 0
src/bin/bind10/tests/Makefile.am

@@ -0,0 +1,12 @@
+PYTESTS = bind10_test.py
+EXTRA_DIST = $(PYTESTS)
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/bin/bind10 \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done

+ 15 - 0
src/bin/bind10/tests/bind10_test.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 2 - 1
src/bin/bindctl/Makefile.am

@@ -1,3 +1,5 @@
+SUBDIRS = tests
+
 bin_SCRIPTS = bindctl
 man_MANS = bindctl.1
 
@@ -9,7 +11,6 @@ pythondir = $(pyexecdir)/bindctl
 bindctldir = $(DESTDIR)$(pkgdatadir)
 bindctl_DATA = bindctl.pem
 EXTRA_DIST += bindctl.pem
-EXTRA_DIST += tests/bindctl_test.py
 
 CLEANFILES = bindctl
 

+ 0 - 1
src/bin/bindctl/bindctl.1

@@ -79,7 +79,6 @@ Additional modules may be available, such as
 \fBb10-cmdctl\fR(8),
 \fBb10-xfrin\fR(8),
 \fBbind10\fR(8),
-\fBmsgq\fR(8),
 BIND 10 Guide\&.
 .SH "AUTHORS"
 .PP

+ 0 - 3
src/bin/bindctl/bindctl.xml

@@ -215,9 +215,6 @@ configuration location.
       <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
-      <citerefentry>
-        <refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum>
-      </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>
 <!-- TODO: point to developer docs -->

+ 2 - 2
src/bin/bindctl/exception.py

@@ -31,7 +31,7 @@ class CmdModuleNameFormatError(CmdFormatError):
     """module name format error"""
 
     def __str__(self):
-        return "Module name format error: the charater of name can only be '0-9a-zA-Z_'" 
+        return "Module name format error: the character of name can only be '0-9a-zA-Z_'" 
                       
                 
 class CmdCommandNameFormatError(CmdFormatError):
@@ -41,7 +41,7 @@ class CmdCommandNameFormatError(CmdFormatError):
         self.module = module        
         
     def __str__(self):
-        return "Command name format error: the charater of name can only be '0-9a-zA-Z_'"      
+        return "Command name format error: the character of name can only be '0-9a-zA-Z_'"      
         
         
 class CmdMissCommandNameFormatError(CmdFormatError):

+ 15 - 0
src/bin/bindctl/run_bindctl.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 12 - 0
src/bin/bindctl/tests/Makefile.am

@@ -0,0 +1,12 @@
+PYTESTS = bindctl_test.py
+EXTRA_DIST = $(PYTESTS)
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_srcdir)/src/bin \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done

+ 15 - 0
src/bin/bindctl/tests/bindctl_test.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 1 - 1
src/bin/cfgmgr/b10-cfgmgr.8

@@ -33,7 +33,7 @@ can be used to talk to this configuration manager via a
 connection\&.
 .PP
 This daemon communicates over a
-\fBmsgq\fR
+\fBb10\-msgq\fR
 C\-Channel connection\&. If this connection is not established,
 \fBb10\-cfgmgr\fR
 will exit\&.

+ 15 - 0
src/bin/cfgmgr/b10-cfgmgr.py.in

@@ -1,5 +1,20 @@
 #!@PYTHON@
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 import sys; sys.path.append ('@@PYTHONPATH@@')
 
 from isc.config.cfgmgr import ConfigManager

+ 1 - 1
src/bin/cfgmgr/b10-cfgmgr.xml

@@ -69,7 +69,7 @@
      
 <!-- TODO: briefly explain why both msqg channel and cmdctl communication -->
     <para>
-      This daemon communicates over a <command>msgq</command> C-Channel
+      This daemon communicates over a <command>b10-msgq</command> C-Channel
       connection.  If this connection is not established,
       <command>b10-cfgmgr</command> will exit.
     </para>

+ 3 - 2
src/bin/cmdctl/Makefile.am

@@ -1,3 +1,5 @@
+SUBDIRS = tests
+
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
 pkglibexec_SCRIPTS = b10-cmdctl
@@ -16,9 +18,8 @@ b10_cmdctl_DATA += cmdctl.spec
  
 EXTRA_DIST = $(CMDCTL_CONFIGURATIONS)
 EXTRA_DIST += cmdctl.spec
-EXTRA_DIST += tests/cmdctl_test.py
 
-CLEANFILES=	b10-cmdctl
+CLEANFILES=	b10-cmdctl cmdctl.pyc
 
 man_MANS = b10-cmdctl.8
 EXTRA_DIST += $(man_MANS) b10-cmdctl.xml

+ 15 - 0
src/bin/cmdctl/run_b10-cmdctl.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 12 - 0
src/bin/cmdctl/tests/Makefile.am

@@ -0,0 +1,12 @@
+PYTESTS = cmdctl_test.py
+EXTRA_DIST = $(PYTESTS)
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/bin/cmdctl \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done

+ 15 - 0
src/bin/cmdctl/tests/cmdctl_test.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 1 - 0
src/bin/cmdctl/tests/cmdctl_test.py

@@ -47,6 +47,7 @@ class MySecureHTTPServer(SecureHTTPServer):
         self.user_sessions = {}
         self.idle_timeout = 1200
         self.cmdctrl = MyCommandControl()
+        self._verbose = False
 
 class MyCommandControl(CommandControl):
     def __init__(self):

+ 14 - 0
src/bin/host/host.cc

@@ -1,3 +1,17 @@
+// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
 // host rewritten in C++ using BIND 10 DNS library
 
 #include <arpa/inet.h>

+ 5 - 4
src/bin/loadzone/b10-loadzone.py.in

@@ -1,4 +1,5 @@
 #!@PYTHON@
+
 # Copyright (C) 2010  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
@@ -16,8 +17,8 @@
 
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import re, getopt
-import isc.auth
-from isc.auth.master import MasterFile
+import isc.datasrc
+from isc.datasrc.master import MasterFile
 
 #########################################################################
 # usage: print usage note and exit
@@ -70,10 +71,10 @@ def main():
         exit(1)
 
     try:
-        isc.auth.sqlite3_ds.load(dbfile, zone, master.zonedata)
+        isc.datasrc.sqlite3_ds.load(dbfile, zone, master.zonedata)
     except Exception as e:
         print("Error loading database: " + str(e))
         exit(1)
 
 if __name__ == "__main__":
-    main()
+    main(datasrc

+ 15 - 0
src/bin/loadzone/run_loadzone.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 8 - 6
src/bin/msgq/Makefile.am

@@ -1,21 +1,23 @@
+SUBDIRS = tests
+
 pkglibexecdir = $(libexecdir)/@PACKAGE@
  
-pkglibexec_SCRIPTS = msgq
+pkglibexec_SCRIPTS = b10-msgq
 
-CLEANFILES = msgq
+CLEANFILES = b10-msgq msgq.pyc
 
-man_MANS = msgq.8
-EXTRA_DIST = $(man_MANS) msgq.xml msgq_test.py
+man_MANS = b10-msgq.8
+EXTRA_DIST = $(man_MANS) msgq.xml
 
 if ENABLE_MAN
 
-msgq.8: msgq.xml
+b10-msgq.8: msgq.xml
 	xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/msgq.xml
 
 endif
 
 # TODO: does this need $$(DESTDIR) also?
 # this is done here since configure.ac AC_OUTPUT doesn't expand exec_prefix
-msgq: msgq.py
+b10-msgq: msgq.py
 	$(SED) "s|@@PYTHONPATH@@|@pyexecdir@|" msgq.py >$@
 	chmod a+x $@

+ 13 - 13
src/bin/msgq/msgq.8

@@ -1,13 +1,13 @@
 '\" t
-.\"     Title: msgq
+.\"     Title: b10-msgq
 .\"    Author: [see the "AUTHORS" section]
 .\" Generator: DocBook XSL Stylesheets v1.75.2 <http://docbook.sf.net/>
-.\"      Date: January 21, 2010
+.\"      Date: April 19, 2010
 .\"    Manual: BIND10
 .\"    Source: BIND10
 .\"  Language: English
 .\"
-.TH "MSGQ" "8" "January 21, 2010" "BIND10" "BIND10"
+.TH "B10\-MSGQ" "8" "April 19, 2010" "BIND10" "BIND10"
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -19,18 +19,18 @@
 .\" * MAIN CONTENT STARTS HERE *
 .\" -----------------------------------------------------------------
 .SH "NAME"
-msgq \- message routing daemon for the Command Channel
+b10-msgq \- message routing daemon for the Command Channel
 .SH "SYNOPSIS"
-.HP \w'\fBmsgq\fR\ 'u
-\fBmsgq\fR [\fB\-m\ \fR\fB\fInumber\fR\fR] [\fB\-v\fR] [\fB\-\-msgq\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-verbose\fR]
+.HP \w'\fBb10\-msgq\fR\ 'u
+\fBb10\-msgq\fR [\fB\-m\ \fR\fB\fInumber\fR\fR] [\fB\-v\fR] [\fB\-\-msgq\-port\ \fR\fB\fInumber\fR\fR] [\fB\-\-verbose\fR]
 .SH "DESCRIPTION"
 .PP
 The
-\fBmsgq\fR
+\fBb10\-msgq\fR
 daemon provides message routing for the Command Channel\&.
 .PP
-The Command Channel is a message bus and subscription manager\&. Programs may subscribe to certain groups to receive messages for that group\&. Every new connection to the
-\fBmsgq\fR
+The Command Channel is a message bus and subscription manager\&. Programs may subscribe to certain groups to receive messages for that group\&. Every new connection to
+\fBb10\-msgq\fR
 is assigned a unique identifier \-\- this is the local name\&. The commands it handles are:
 .sp
 .RS 4
@@ -90,7 +90,7 @@ is assigned a unique identifier \-\- this is the local name\&. The commands it h
 It listens on 127\&.0\&.0\&.1\&.
 .PP
 The
-\fBmsgq\fR
+\fBb10\-msgq\fR
 daemon may be cleanly stopped by sending the SIGTERM signal to the process\&. This shutdown does not notify the subscribers\&.
 .SH "OPTIONS"
 .PP
@@ -99,14 +99,14 @@ The arguments are as follows:
 \fB\-m \fR\fB\fInumber\fR\fR, \fB\-\-msgq\-port \fR\fB\fInumber\fR\fR
 .RS 4
 The port number that
-\fBmsgq\fR
+\fBb10\-msgq\fR
 will listen on\&. The default is 9912\&.
 .RE
 .PP
 \fB\-v\fR, \fB\-\-verbose\fR
 .RS 4
 Enabled verbose mode\&. This enables diagnostic messages to STDERR\&. Displays more about what
-\fBmsgq\fR
+\fBb10\-msgq\fR
 is doing\&.
 .RE
 .SH "SEE ALSO"
@@ -117,7 +117,7 @@ BIND 10 Guide\&.
 .SH "AUTHORS"
 .PP
 The
-\fBmsgq\fR
+\fBb10\-msgq\fR
 daemon and Control Channel specification were initially designed by Michael Graff of ISC\&.
 .SH "HISTORY"
 .PP

+ 15 - 0
src/bin/msgq/msgq.py.in

@@ -1,5 +1,20 @@
 #!@PYTHON@
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 import sys; sys.path.append ('@@PYTHONPATH@@')
 
 """This code implements the msgq daemon."""

+ 10 - 10
src/bin/msgq/msgq.xml

@@ -21,17 +21,17 @@
 <refentry>
 
   <refentryinfo>
-    <date>January 21, 2010</date>
+    <date>April 19, 2010</date>
   </refentryinfo>
 
   <refmeta>
-    <refentrytitle>msgq</refentrytitle>
+    <refentrytitle>b10-msgq</refentrytitle>
     <manvolnum>8</manvolnum>
     <refmiscinfo>BIND10</refmiscinfo>
   </refmeta>
 
   <refnamediv>
-    <refname>msgq</refname>
+    <refname>b10-msgq</refname>
     <refpurpose>message routing daemon for the Command Channel</refpurpose>
   </refnamediv>
 
@@ -44,7 +44,7 @@
 
   <refsynopsisdiv>
     <cmdsynopsis>
-      <command>msgq</command>
+      <command>b10-msgq</command>
       <arg><option>-m <replaceable>number</replaceable></option></arg>
       <arg><option>-v</option></arg>
       <arg><option>--msgq-port <replaceable>number</replaceable></option></arg>
@@ -55,7 +55,7 @@
   <refsect1>
     <title>DESCRIPTION</title>
     <para>
-      The <command>msgq</command>
+      The <command>b10-msgq</command>
       daemon provides message routing for the Command Channel.
     </para>
 
@@ -63,7 +63,7 @@
       The Command Channel is a message bus and subscription manager.
       Programs may subscribe to certain groups to receive messages
       for that group.
-      Every new connection to the <command>msgq</command> is
+      Every new connection to <command>b10-msgq</command> is
       assigned a unique identifier -- this is the local name.
       The commands it handles are:
       <itemizedlist>
@@ -97,7 +97,7 @@
     </para>
 
     <para>
-      The <command>msgq</command> daemon may be cleanly stopped by
+      The <command>b10-msgq</command> daemon may be cleanly stopped by
       sending the SIGTERM signal to the process.
       This shutdown does not notify the subscribers.
     </para>
@@ -114,7 +114,7 @@
         <term><option>-m <replaceable>number</replaceable></option>,
           <option>--msgq-port <replaceable>number</replaceable></option></term>
         <listitem><para>
-          The port number that <command>msgq</command> will listen on.
+          The port number that <command>b10-msgq</command> will listen on.
           The default is 9912.</para>
         </listitem>
       </varlistentry>
@@ -123,7 +123,7 @@
         <term><option>-v</option>, <option>--verbose</option></term>
         <listitem><para>
           Enabled verbose mode. This enables diagnostic messages to
-          STDERR.  Displays more about what <command>msgq</command>
+          STDERR.  Displays more about what <command>b10-msgq</command>
           is doing.
 <!-- TODO: is STDERR correct? -->
         </para></listitem>
@@ -147,7 +147,7 @@
   <refsect1>
     <title>AUTHORS</title>
     <para>
-      The <command>msgq</command> daemon and Control Channel specification
+      The <command>b10-msgq</command> daemon and Control Channel specification
       were initially designed by Michael Graff of ISC.
     </para>
   </refsect1>

+ 0 - 13
src/bin/msgq/msgq_test.in

@@ -1,13 +0,0 @@
-#! /bin/sh
-
-PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
-export PYTHON_EXEC
-
-MYPATH_PATH=@abs_top_srcdir@/src/bin/msgq
-
-PYTHONPATH=@abs_top_srcdir@/src/lib/python
-
-export PYTHONPATH
-
-cd ${MYPATH_PATH}
-exec ${PYTHON_EXEC} -O msgq_test.py $*

+ 16 - 1
src/bin/msgq/run_msgq.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 
@@ -9,4 +24,4 @@ PYTHONPATH=@abs_top_srcdir@/src/lib/python
 export PYTHONPATH
 
 cd ${MYPATH_PATH}
-exec ${PYTHON_EXEC} -O msgq $*
+exec ${PYTHON_EXEC} -O b10-msgq $*

+ 13 - 0
src/bin/msgq/tests/Makefile.am

@@ -0,0 +1,13 @@
+PYTESTS = msgq_test.py
+EXTRA_DIST = $(PYTESTS)
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_builddir)/src/bin/msgq:$(abs_top_srcdir)/src/lib/python \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done
+

+ 28 - 0
src/bin/msgq/tests/msgq_test.in

@@ -0,0 +1,28 @@
+#! /bin/sh
+
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
+export PYTHON_EXEC
+
+MYPATH_PATH=@abs_top_srcdir@/src/bin/msgq/tests
+
+PYTHONPATH=@abs_top_srcdir@/src/bin/msgq:@abs_top_srcdir@/src/lib/python
+
+export PYTHONPATH
+
+cd ${MYPATH_PATH}
+exec ${PYTHON_EXEC} -O msgq_test.py $*

src/bin/msgq/msgq_test.py → src/bin/msgq/tests/msgq_test.py


+ 15 - 0
src/bin/usermgr/run_b10-cmdctl-usermgr.sh.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 3 - 2
src/bin/xfrin/Makefile.am

@@ -1,3 +1,5 @@
+SUBDIRS = tests
+
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
 pkglibexec_SCRIPTS = b10-xfrin
@@ -5,11 +7,10 @@ pkglibexec_SCRIPTS = b10-xfrin
 b10_xfrindir = $(DESTDIR)$(pkgdatadir)
 b10_xfrin_DATA = xfrin.spec
 
-CLEANFILES = b10-xfrin xfrin.spec
+CLEANFILES = b10-xfrin xfrin.pyc xfrin.spec
 
 man_MANS = b10-xfrin.8
 EXTRA_DIST = $(man_MANS) b10-xfrin.xml
-EXTRA_DIST += tests/xfrin_test.py
 
 if ENABLE_MAN
 

+ 27 - 14
src/bin/xfrin/b10-xfrin.8

@@ -29,9 +29,7 @@ The
 \fBb10\-xfrin\fR
 daemon provides the BIND 10 incoming DNS zone transfer service\&. Normally it is started by the
 \fBbind10\fR(8)
-master process and communicates with the
-\fBb10-auth\fR(8)
-authoritative DNS server\&.
+boss process\&. When triggered it can request and receive a zone transfer and store the zone in a BIND 10 zone data store\&.
 .if n \{\
 .sp
 .\}
@@ -49,20 +47,37 @@ The Y1 prototype release only supports AXFR\&. IXFR is not implemented\&.
 .sp .5v
 .RE
 .PP
-This daemon communicates over a
-\fBmsgq\fR(8)
+
+This daemon communicates with BIND 10 over a
+\fBb10-msgq\fR(8)
 C\-Channel connection\&. If this connection is not established,
 \fBb10\-xfrin\fR
 will exit\&.
 .PP
-It also receives its configurations from
-\fBb10-cfgmgr\fR(8)
-using the REST\-ful interface provided by
-\fBb10-cmdctl\fR(8)\&.
+
+\fBb10\-xfrin\fR
+receives its configurations from
+\fBb10-cfgmgr\fR(8)\&.
+.SH "CONFIGURATION AND COMMANDS"
+.PP
+The configurable setting is
+\fItransfers\-in\fR
+which defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
 .PP
-The configurable setting is transfers\-in which defines the maximum number of inbound zone transfers that can run concurrently\&. The default is 10\&.
+The configuration commands are:
 .PP
-The configuration commands are: print_settings, shutdown, and retransfer (triggers the transfer in for a single zone without checking the zone\'s serial number)\&.
+
+\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
 .\}
@@ -82,11 +97,9 @@ This prototype version uses SQLite3 as its data source backend\&. Future version
 .SH "SEE ALSO"
 .PP
 
-\fBb10-auth\fR(8),
 \fBb10-cfgmgr\fR(8),
-\fBb10-cmdctl\fR(8),
+\fBb10-msgq\fR(8),
 \fBbind10\fR(8),
-\fBmsgq\fR(8),
 BIND 10 Guide\&.
 .SH "HISTORY"
 .PP

+ 33 - 46
src/bin/xfrin/b10-xfrin.xml

@@ -58,38 +58,36 @@
       incoming DNS zone transfer service.
       Normally it is started by the
       <citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      master process
-      and communicates with the
-      <citerefentry><refentrytitle>b10-auth</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      authoritative DNS server.
+      boss process.
+      When triggered it can request and receive a zone transfer and store
+      the zone in a BIND 10 zone data store.
     </para>
 
     <note><simpara>
       The Y1 prototype release only supports AXFR. IXFR is not implemented.
     </simpara></note>
 
-<!-- TODO:
-add a usage example of xfrin -->
-
     <para>
-      This daemon communicates over a
-      <citerefentry><refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+<!-- 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,
       <command>b10-xfrin</command> will exit.
-<!-- TODO what if connection closes later, will b10-auth exit? -->
+<!-- TODO what if connection closes later, will b10-xfrin exit? -->
     </para>
 
     <para>
-     It also receives its configurations from
-<citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>
-      using the REST-ful interface provided by
-      <citerefentry><refentrytitle>b10-cmdctl</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+     <command>b10-xfrin</command> receives its configurations from
+<citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
     </para>
+  </refsect1>
 
+  <refsect1>
+    <title>CONFIGURATION AND COMMANDS</title>
     <para>
-      The configurable setting is transfers-in which defines
-      the maximum number of inbound zone transfers that can run
-      concurrently. The default is 10.
+      The configurable setting is <varname>transfers-in</varname>
+      which defines the maximum number of inbound zone transfers
+      that can run concurrently. The default is 10.
     </para>
 
 <!-- TODO: formating -->
@@ -97,25 +95,30 @@ add a usage example of xfrin -->
 <!-- schedule immediate maintenance for a zone(check soa serial ) -->
     <para>
       The configuration commands are:
-print_settings,
-shutdown, and
-retransfer (triggers the transfer in for a single zone without checking
-the zone's serial number).
+    </para>
+    <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:
 
-retransfer has the following arguments:
-zone_name
 port (defaults to 53)
-master
 db_file (defaults to zone.sqlite3) --> <!-- TODO: fix this -->
 
-
-<!--
-If the admin want to get the latest zone data from master, he can send the
-command "retransfer to xfrin."
--->
 <!-- TODO:
 
  later it will can be triggered by :
@@ -130,16 +133,6 @@ command "retransfer to xfrin."
 
 -->
 
-<!-- TODO: reword -->
-<!-- TODO:
-    <para>
-      The administrator can send zone transfer-in command to xfrin
-      module, or terminate all ongoing incoming transfers by sending
-      the <quote>shutdown</quote> command to xfrin module.
-    </para>
--->
-<!-- TODO: kills it and bind10 restarts? -->
-
     <note><para>
       This prototype version uses SQLite3 as its data source backend.
       Future versions will be configurable, supporting multiple
@@ -183,20 +176,14 @@ operation
     <title>SEE ALSO</title>
     <para>
       <citerefentry>
-        <refentrytitle>b10-auth</refentrytitle><manvolnum>8</manvolnum>
-      </citerefentry>,
-      <citerefentry>
         <refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
-        <refentrytitle>b10-cmdctl</refentrytitle><manvolnum>8</manvolnum>
+        <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
       <citerefentry>
         <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
       </citerefentry>,
-      <citerefentry>
-        <refentrytitle>msgq</refentrytitle><manvolnum>8</manvolnum>
-      </citerefentry>,
       <citetitle>BIND 10 Guide</citetitle>.
     </para>
   </refsect1>

+ 16 - 1
src/bin/xfrin/run_b10-xfrin.sh.in

@@ -1,10 +1,25 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 
 MYPATH_PATH=@abs_top_builddir@/src/bin/xfrin
-PYTHONPATH=@abs_top_srcdir@/src/lib/python
+PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/dns/.libs
 export PYTHONPATH
 
 cd ${MYPATH_PATH}

+ 16 - 0
src/bin/xfrin/tests/Makefile.am

@@ -0,0 +1,16 @@
+PYTESTS = xfrin_test.py
+EXTRA_DIST = $(PYTESTS)
+
+if HAVE_BOOST_PYTHON
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/bin/xfrin:$(abs_top_srcdir)/src/lib/python \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done
+
+endif

+ 15 - 0
src/bin/xfrin/tests/xfrin_test.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

File diff suppressed because it is too large
+ 57 - 2
src/bin/xfrin/tests/xfrin_test.py


+ 84 - 88
src/bin/xfrin/xfrin.py.in

@@ -15,6 +15,7 @@
 # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+# $Id$
 
 import sys; sys.path.append ('@@PYTHONPATH@@')
 import os
@@ -29,8 +30,10 @@ from optparse import OptionParser, OptionValueError
 from isc.config.ccsession import *
 try:
     from bind10_dns import *
-except:
-    pass
+except ImportError as e:
+    # C++ loadable module may not be installed; even so the xfrin process
+    # must keep running, so we warn about it and move forward.
+    sys.stderr.write('[b10-xfrin] failed to import DNS module: %s\n' % str(e))
 
 # If B10_FROM_SOURCE is set in the environment, we use data files
 # from a directory relative to that, otherwise we use the ones
@@ -47,54 +50,51 @@ SPECFILE_LOCATION = SPECFILE_PATH + "/xfrin.spec"
 __version__ = 'BIND10'
 # define xfrin rcode
 XFRIN_OK = 0
-XFRIN_RECV_TIMEOUT = 1
-XFRIN_NO_NEWDATA = 2
-XFRIN_QUOTA_ERROR = 3
-XFRIN_IS_DOING = 4
-
-# define xfrin state
-XFRIN_QUERY_SOA = 1
-XFRIN_FIRST_AXFR = 2
-XFRIN_FIRST_IXFR = 3
 
 def log_error(msg):
     sys.stderr.write("[b10-xfrin] ")
     sys.stderr.write(str(msg))
     sys.stderr.write('\n')
 
-
 class XfrinException(Exception): 
     pass
 
-
 class XfrinConnection(asyncore.dispatcher):
     '''Do xfrin in this class. '''    
 
-    def __init__(self, zone_name, db_file, 
-                 shutdown_event,
-                 master_addr, 
-                 port = 53, 
-                 check_soa = True, 
-                 verbose = False,
-                 idle_timeout = 60): 
+    def __init__(self, 
+                 zone_name, db_file, shutdown_event, master_addr, 
+                 port = 53, verbose = False, idle_timeout = 60): 
         ''' idle_timeout: max idle time for read data from socket.
             db_file: specify the data source file.
             check_soa: when it's true, check soa first before sending xfr query
         '''
+
         asyncore.dispatcher.__init__(self)
         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
         self._zone_name = zone_name
         self._db_file = db_file
-        self._axfrin_db = isc.auth.sqlite3_ds.AXFRInDB(self._db_file, self._zone_name)
         self._soa_rr_count = 0
         self._idle_timeout = idle_timeout
         self.setblocking(1)
-        self.connect((master_addr, port))
         self._shutdown_event = shutdown_event
         self._verbose = verbose
+        self._master_addr = master_addr
+        self._port = port
+
+    def connect_to_master(self):
+        '''Connect to master in TCP.'''
+
+        try:
+            self.connect((self._master_addr, self._port))
+            return True
+        except socket.error as e:
+            self.log_msg('Failed to connect:(%s:%d), %s' % (self._master_addr, self._port, str(e)))
+            return False
 
     def _create_query(self, query_type):
         '''Create dns query message. '''
+
         msg = message(message_mode.RENDER)
         query_id = random.randint(1, 0xFFFF)
         self._query_id = query_id
@@ -112,9 +112,9 @@ class XfrinConnection(asyncore.dispatcher):
             count = self.send(data[total_count:])
             total_count += count
 
-
     def _send_query(self, query_type):
         '''Send query message over TCP. '''
+
         msg = self._create_query(query_type)
         obuf = output_buffer(0)
         render = message_render(obuf)
@@ -123,7 +123,6 @@ class XfrinConnection(asyncore.dispatcher):
 
         self._send_data(header_len)
         self._send_data(obuf.get_data())
-
     
     def _get_request_response(self, size):
         recv_size = 0
@@ -140,55 +139,56 @@ class XfrinConnection(asyncore.dispatcher):
 
         return data
 
-
-    def handle_read(self):
-        '''Read query's response from socket. '''
-        self._recvd_data = self.recv(self._need_recv_size)
-        self._recvd_size = len(self._recvd_data)
-        self._recv_time_out = False
-
-
     def _check_soa_serial(self):
         ''' Compare the soa serial, if soa serial in master is less than
         the soa serial in local, Finish xfrin.
         False: soa serial in master is less or equal to the local one.
         True: soa serial in master is bigger
         '''
+
         self._send_query(rr_type.SOA())
         data_size = self._get_request_response(2)
         soa_reply = self._get_request_response(int(data_size))
         #TODO, need select soa record from data source then compare the two 
-        #serial 
+        #serial, current just return OK, since this function hasn't been used now 
         return XFRIN_OK
 
     def do_xfrin(self, check_soa, ixfr_first = False):
+        '''Do xfr by sending xfr request and parsing response. '''
+
         try:
             ret = XFRIN_OK
             if check_soa:
                 ret =  self._check_soa_serial()
             
-            self.log_msg('transfer of \'%s\': AXFR started' % self._zone_name)
+            logstr = 'transfer of \'%s\': AXFR ' % self._zone_name
             if ret == XFRIN_OK:    
-                self._axfrin_db.prepare_axfrin()
+                self.log_msg(logstr + 'started')
                 self._send_query(rr_type.AXFR())
-                ret = self._handle_xfrin_response()
+                isc.datasrc.sqlite3_ds.load(self._db_file, self._zone_name,
+                                            self._handle_xfrin_response)
+
+                self.log_msg(logstr + 'succeeded')
 
-            self.log_msg('transfer of \'%s\' AXFR ended' % self._zone_name)
         except XfrinException as e:
             self.log_msg(e)
-            self.log_msg('Error happened during xfrin!')
-            #TODO, recover data source. 
+            self.log_msg(logstr + 'failed')
+            #TODO, recover data source.
+        except isc.datasrc.sqlite3_ds.Sqlite3DSError as e:
+            self.log_msg(e)
+            self.log_msg(logstr + 'failed')
         finally:
            self.close()
-           if ret == XFRIN_OK:
-               self._axfrin_db.finish_axfrin()
 
         return ret
     
     def _check_response_status(self, msg):
+        '''Check validation of xfr response. '''
+
         #TODO, check more?
-        if msg.get_rcode() != rcode.NOERROR():
-            raise XfrinException('error response: ')
+        msg_rcode = msg.get_rcode()
+        if msg_rcode != rcode.NOERROR():
+            raise XfrinException('error response: %s' % msg_rcode.to_text())
 
         if not msg.get_header_flag(message_flag.QR()):
             raise XfrinException('response is not a response ')
@@ -202,8 +202,9 @@ class XfrinConnection(asyncore.dispatcher):
         if msg.get_rr_count(section.QUESTION()) > 1:
             raise XfrinException('query section count greater than 1')
 
-
     def _handle_answer_section(self, rrset_iter):
+        '''Return a generator for the reponse in one tcp package to a zone transfer.'''
+
         while not rrset_iter.is_last():
             rrset = rrset_iter.get_rrset()
             rrset_iter.next()
@@ -218,17 +219,24 @@ class XfrinConnection(asyncore.dispatcher):
                 # Count the soa record count
                 if rrset.get_type() == rr_type.SOA():
                     self._soa_rr_count += 1
+
+                    # XXX: the current DNS message parser can't preserve the
+                    # RR order or separete the beginning and ending SOA RRs.
+                    # As a short term workaround, we simply ignore the second
+                    # SOA, and ignore the erroneous case where the transfer
+                    # session doesn't end with an SOA.
                     if (self._soa_rr_count == 2):
-                        # Avoid inserting soa record twice                        
-                        return
+                        # Avoid inserting soa record twice
+                        break
 
                 rdata_text = rdata_iter.get_current().to_text()
-                rr_data = (rrset_name, rrset_ttl, rrset_class, rrset_type, rdata_text)
-                self._axfrin_db.insert_axfr_record([rr_data]) 
+                yield (rrset_name, rrset_ttl, rrset_class, rrset_type,
+                       rdata_text)
                 rdata_iter.next()
 
-
     def _handle_xfrin_response(self):
+        '''Return a generator for the response to a zone transfer. '''
+
         while True:
             data_len = self._get_request_response(2)
             msg_len = socket.htons(struct.unpack('H', data_len)[0])
@@ -236,44 +244,48 @@ class XfrinConnection(asyncore.dispatcher):
             msg = message(message_mode.PARSE)
             msg.from_wire(input_buffer(recvdata))
             self._check_response_status(msg)
-            
+
             rrset_iter = section_iter(msg, section.ANSWER())
-            self._handle_answer_section(rrset_iter)
+            for rr in self._handle_answer_section(rrset_iter):
+                yield rr
+
             if self._soa_rr_count == 2:
-                return XFRIN_OK
+                break
             
             if self._shutdown_event.is_set():
-                #Check if xfrin process is shutdown.
-                #TODO, xfrin may be blocked in one loop. 
                 raise XfrinException('xfrin is forced to stop')
 
-        return XFRIN_OK
+    def handle_read(self):
+        '''Read query's response from socket. '''
 
+        self._recvd_data = self.recv(self._need_recv_size)
+        self._recvd_size = len(self._recvd_data)
+        self._recv_time_out = False
 
     def writable(self):
         '''Ignore the writable socket. '''
-        return False
 
+        return False
 
     def log_info(self, msg, type='info'):
         # Overwrite the log function, log nothing
         pass
 
     def log_msg(self, msg):
-        sys.stdout.write('[b10-xfrin] ')
-        sys.stdout.write(str(msg))
-        sys.stdout.write('\n')
+        if self._verbose:
+            sys.stdout.write('[b10-xfrin] ')
+            sys.stdout.write(str(msg))
+            sys.stdout.write('\n')
 
 
 def process_xfrin(xfrin_recorder, zone_name, db_file, 
                   shutdown_event, master_addr, port, check_soa, verbose):
-    xfrin_recorder.increment(name)
-    try:
-        conn = XfrinConnection(zone_name, db_file, shutdown_event, 
-                           master_addr, int(port), check_soa, verbose)
-        conn.do_xfrin(False)
-    except Exception as e:
-        log_error(str(e))
+    port = int(port)
+    xfrin_recorder.increment(zone_name)
+    conn = XfrinConnection(zone_name, db_file, shutdown_event, 
+                           master_addr, port, verbose)
+    if conn.connect_to_master():
+        conn.do_xfrin(check_soa)
 
     xfrin_recorder.decrement(zone_name)
 
@@ -320,13 +332,6 @@ class Xfrin():
         # TODO, process new config data
         return create_answer(0)
 
-
-    def _print_settings(self):
-        full_config = self._cc.get_full_config()
-        for item in full_config:
-            print(item + ":" + str(full_config[item]))
-
-
     def shutdown(self):
         ''' shutdown the xfrin process. the thread which is doing xfrin should be 
         terminated.
@@ -343,13 +348,7 @@ class Xfrin():
         answer = create_answer(0)
         cmd = command
         try:
-            if cmd == 'print_message':
-                print(args)
-
-            elif cmd == 'print_settings':
-                self._print_settings()  
-
-            elif cmd == 'shutdown':
+            if cmd == 'shutdown':
                 self._shutdown_event.set()
 
             elif cmd == 'retransfer':
@@ -409,12 +408,12 @@ class Xfrin():
         if self.recorder.xfrin_in_progress(zone_name):
             return (1, 'zone xfrin is in progress')
 
-        xfrin_thread = threading.Thread(target = process_xfrin, 
-                                        args = (self.recorder, 
-                                                zone_name, 
-                                                db_file, 
+        xfrin_thread = threading.Thread(target = process_xfrin,
+                                        args = (self.recorder,
+                                                zone_name,
+                                                db_file,
                                                 self._shutdown_event,
-                                                master_addr, 
+                                                master_addr,
                                                 port, check_soa, self._verbose))
                                                 
         xfrin_thread.start()
@@ -471,6 +470,3 @@ if __name__ == '__main__':
 
     if xfrind:
         xfrind.shutdown()
-
-
-

+ 1 - 16
src/bin/xfrin/xfrin.spec.pre.in

@@ -10,22 +10,7 @@
       }
     ],
     "commands": [
-      {
-        "command_name": "print_message",
-        "command_description": "Print the given message to stdout",
-        "command_args": [ {
-          "item_name": "message",
-          "item_type": "string",
-          "item_optional": False,
-          "item_default": ""
-        } ]
-      },
-      {
-        "command_name": "print_settings",
-        "command_description": "Print some_string and some_int to stdout",
-        "command_args": []
-      },
-      {
+     {
         'command_name': 'retransfer',
         "command_description": 'retransfer a single zone without checking zone serial number',
         'command_args': [ {

+ 13 - 2
src/bin/xfrout/Makefile.am

@@ -1,3 +1,5 @@
+SUBDIRS = tests
+
 pkglibexecdir = $(libexecdir)/@PACKAGE@
 
 pkglibexec_SCRIPTS = b10-xfrout
@@ -5,9 +7,18 @@ pkglibexec_SCRIPTS = b10-xfrout
 b10_xfroutdir = $(DESTDIR)$(pkgdatadir)
 b10_xfrout_DATA = xfrout.spec
 
-CLEANFILES=	b10-xfrout xfrout.spec
+CLEANFILES=	b10-xfrout xfrout.pyc xfrout.spec
+
+man_MANS = b10-xfrout.8
+EXTRA_DIST = $(man_MANS) b10-xfrout.xml
+
+if ENABLE_MAN
+
+b10-xfrout.8: b10-xfrout.xml
+	xsltproc --novalid --xinclude --nonet -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(srcdir)/b10-xfrout.xml
+
+endif
 
-EXTRA_DIST = tests/xfrout_test.py
 
 xfrout.spec: xfrout.spec.pre
 	$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" xfrout.spec.pre >$@

+ 116 - 0
src/bin/xfrout/b10-xfrout.8

@@ -0,0 +1,116 @@
+'\" t
+.\"     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
+.\"    Manual: BIND10
+.\"    Source: BIND10
+.\"  Language: English
+.\"
+.TH "B10\-XFROUT" "8" "April 20, 2010" "BIND10" "BIND10"
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+b10-xfrout \- Outbound DNS zone transfer service
+.SH "SYNOPSIS"
+.HP \w'\fBb10\-xfrout\fR\ 'u
+\fBb10\-xfrout\fR [\fB\-v\fR] [\fB\-\-verbose\fR]
+.SH "DESCRIPTION"
+.PP
+The
+\fBb10\-xfrout\fR
+daemon provides the BIND 10 outgoing DNS zone transfer service\&. Normally it is started by the
+\fBbind10\fR(8)
+boss process\&. When the
+\fBb10\-auth\fR
+DNS server receives a transfer request,
+\fBb10\-xfrout\fR
+sends the zone as found in the BIND 10 zone data store\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.sp
+This development prototype release only supports AXFR\&. IXFR is not implemented\&.
+.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,
+\fBb10\-xfrout\fR
+will exit\&.
+.PP
+
+\fBb10\-xfrout\fR
+receives its configurations from
+\fBb10-cfgmgr\fR(8)\&.
+.SH "CONFIGURATION AND COMMANDS"
+.PP
+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\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.sp
+This prototype version uses SQLite3 as its data source backend\&. Future versions will be configurable, supporting multiple data storage types\&.
+.sp .5v
+.RE
+.PP
+The configuration command is:
+.PP
+
+\fBshutdown\fR
+stops all outbound zone transfers and exits
+\fBb10\-xfrout\fR\&. (Note that the BIND 10 boss process will restart this service\&.)
+.SH "SEE ALSO"
+.PP
+
+\fBb10-auth\fR(8),
+\fBb10-cfgmgr\fR(8),
+\fBb10-msgq\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\&.
+.SH "COPYRIGHT"
+.br
+Copyright \(co 2010 Internet Systems Consortium, Inc. ("ISC")
+.br

+ 181 - 0
src/bin/xfrout/b10-xfrout.xml

@@ -0,0 +1,181 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+               "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
+	       [<!ENTITY mdash "&#8212;">]>
+<!--
+ - Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+ -
+ - Permission to use, copy, modify, and/or distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ - AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ - PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id$ -->
+<refentry>
+
+  <refentryinfo>
+    <date>April 20, 2010</date>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>b10-xfrout</refentrytitle>
+    <manvolnum>8</manvolnum>
+    <refmiscinfo>BIND10</refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>b10-xfrout</refname>
+    <refpurpose>Outbound DNS zone transfer service</refpurpose>
+  </refnamediv>
+
+  <docinfo>
+    <copyright>
+      <year>2010</year>
+      <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
+    </copyright>
+  </docinfo>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>b10-xfrout</command>
+      <arg><option>-v</option></arg>
+      <arg><option>--verbose</option></arg>
+    </cmdsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>DESCRIPTION</title>
+    <para>The <command>b10-xfrout</command> daemon provides the BIND 10
+      outgoing DNS zone transfer service.
+      Normally it is started by the
+      <citerefentry><refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+      boss process.
+      When the <command>b10-auth</command> DNS server receives
+      a transfer request, <command>b10-xfrout</command> sends the
+      zone as found in the BIND 10 zone data store.
+    </para>
+
+<!-- TODO
+ BTW, do we need to mention that the xfr request is received by auth
+ process?, and then the socket and xfr request is sent to xfrout.
+-->
+
+    <note><simpara>
+      This development prototype release only supports AXFR.
+      IXFR is not implemented.
+    </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,
+      <command>b10-xfrout</command> will exit.
+<!-- TODO what if connection closes later, will b10-xfrout exit? -->
+    </para>
+
+    <para>
+     <command>b10-xfrout</command> receives its configurations from
+<citerefentry><refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+    </para>
+  </refsect1>
+
+  <refsect1>
+    <title>CONFIGURATION AND COMMANDS</title>
+    <para>
+      The configurable settings are:
+    </para>
+    <para>
+      <varname>transfers-out</varname>
+      defines the maximum number of outgoing zone transfers
+      that can run concurrently. The default is 10.
+    </para>
+    <para>
+      <varname>db_file</varname>
+      defines the path to the SQLite3 data store file.
+      The default is
+      <filename>/usr/local/var/bind10-devel/zone.sqlite3</filename>.
+    </para>
+
+    <note><simpara>
+      This prototype version uses SQLite3 as its data source backend.
+      Future versions will be configurable, supporting multiple
+      data storage types.
+    </simpara></note>
+
+<!-- TODO: formating -->
+    <para>
+      The configuration command is:
+    </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>
+
+  </refsect1>
+
+<!--
+  <refsect1>
+    <title>OPTIONS</title>
+
+    <para>The arguments are as follows:</para>
+
+    <variablelist>
+      <varlistentry>
+        <term><option></option></term>
+        <listitem><para>
+        </para></listitem>
+      </varlistentry>
+
+    </variablelist>
+
+  </refsect1>
+-->
+<!--
+  <refsect1>
+    <title>FILES</title>
+    <para>
+    <filename>/tmp/auth_xfrout_conn</filename>
+    </para>
+  </refsect1>
+-->
+
+  <refsect1>
+    <title>SEE ALSO</title>
+    <para>
+      <citerefentry>
+        <refentrytitle>b10-auth</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-cfgmgr</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>b10-msgq</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>bind10</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citetitle>BIND 10 Guide</citetitle>.
+    </para>
+  </refsect1>
+
+  <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.
+    </para>
+  </refsect1>
+</refentry><!--
+ - Local variables:
+ - mode: sgml
+ - End:
+-->

+ 16 - 1
src/bin/xfrout/run_b10-xfrout.sh.in

@@ -1,10 +1,25 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 
 MYPATH_PATH=@abs_top_builddir@/src/bin/xfrout
-PYTHONPATH=@abs_top_srcdir@/src/lib/python
+PYTHONPATH=@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/xfr/.libs
 export PYTHONPATH
 
 cd ${MYPATH_PATH}

+ 16 - 0
src/bin/xfrout/tests/Makefile.am

@@ -0,0 +1,16 @@
+PYTESTS = xfrout_test.py
+EXTRA_DIST = $(PYTESTS)
+
+if HAVE_BOOST_PYTHON
+
+# later will have configure option to choose this, like: coverage run --branch
+PYCOVERAGE = $(PYTHON)
+# test using command-line arguments, so use check-local target instead of TESTS
+check-local:
+	for pytest in $(PYTESTS) ; do \
+	echo Running test: $$pytest ; \
+	env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
+	$(PYCOVERAGE) $(abs_srcdir)/$$pytest ; \
+	done
+
+endif

+ 15 - 0
src/bin/xfrout/tests/xfrout_test.in

@@ -1,5 +1,20 @@
 #! /bin/sh
 
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 PYTHON_EXEC=${PYTHON_EXEC:-@PYTHON@}
 export PYTHON_EXEC
 

+ 34 - 17
src/bin/xfrout/xfrout.py.in

@@ -22,7 +22,7 @@ import isc.cc
 import threading
 import struct
 import signal
-from isc.auth import sqlite3_ds
+from isc.datasrc import sqlite3_ds
 from socketserver import *
 import os
 from isc.config.ccsession import *
@@ -32,8 +32,10 @@ from optparse import OptionParser, OptionValueError
 try:
     from bind10_xfr import *
     from bind10_dns import *
-except:
-    pass
+except ImportError as e:
+    # C++ loadable module may not be installed; even so the xfrout process
+    # must keep running, so we warn about it and move forward.
+    sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
 
 if "B10_FROM_SOURCE" in os.environ:
     SPECFILE_PATH = os.environ["B10_FROM_SOURCE"] + "/src/bin/xfrout"
@@ -42,6 +44,7 @@ else:
     DATAROOTDIR = "@datarootdir@"
     SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
 SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
+UNIX_SOCKET_FILE = "@localstatedir@".replace("${prefix}", PREFIX) + "/auth_xfrout_conn"
 
 MAX_TRANSFERS_OUT = 10
 verbose_mode = False
@@ -53,8 +56,10 @@ class XfroutException(Exception): pass
 class XfroutSession(BaseRequestHandler):
     def handle(self):
         fd = recv_fd(self.request.fileno())
+        if fd < 0:
+            raise XfroutException("failed to receive the FD for XFR connection")
         data_len = self.request.recv(2)
-        msg_len = struct.unpack('H', data_len)[0]
+        msg_len = struct.unpack('!H', data_len)[0]
         msgdata = self.request.recv(msg_len)
         sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
         try:
@@ -64,7 +69,7 @@ class XfroutSession(BaseRequestHandler):
                 self.log_msg(str(e))
 
         sock.close()
-               
+
     def _parse_query_message(self, mdata):
         ''' parse query message to [socket,message]'''
         #TODO, need to add parseHeader() in case the message header is invalid 
@@ -78,7 +83,6 @@ class XfroutSession(BaseRequestHandler):
 
         return rcode.NOERROR(), msg
 
-
     def _get_query_zone_name(self, msg):
         q_iter = question_iter(msg)
         question = q_iter.get_question()
@@ -273,12 +277,25 @@ class UnixSockServer(ThreadingUnixStreamServer):
     '''The unix domain socket server which accept xfr query sent from auth server.'''
 
     def __init__(self, sock_file, handle_class, shutdown_event, config_data):
+        try:
+            os.unlink(sock_file)
+        except:
+            pass
+ 
+        self._sock_file = sock_file
         ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
         self._lock = threading.Lock()
         self._transfers_counter = 0
         self._shutdown_event = shutdown_event
         self.update_config_data(config_data)
+    
 
+    def shutdown(self):
+        ThreadingUnixStreamServer.shutdown(self)
+        try:
+            os.unlink(self._sock_file)
+        except:
+            pass
 
     def update_config_data(self, new_config):
         '''Apply the new config setting of xfrout module. '''
@@ -311,16 +328,18 @@ class UnixSockServer(ThreadingUnixStreamServer):
         self._transfers_counter -= 1
         self._lock.release()
 
-
 def listen_on_xfr_query(unix_socket_server):
-    '''Listen xfr query in one single thread. '''
-    unix_socket_server.serve_forever()
+
+    '''Listen xfr query in one single thread. Polls for shutdown 
+    every 0.1 seconds, is there a better time?
+    '''
+    unix_socket_server.serve_forever(poll_interval = 0.1)
    
 
 class XfroutServer:
     def __init__(self):
         self._unix_socket_server = None
-        self._listen_sock_file = '/tmp/auth_xfrout_conn' # TODO, should this be configurable in cfgmgr
+        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._config_data = self._cc.get_full_config()
@@ -330,11 +349,7 @@ class XfroutServer:
 
     def _start_xfr_query_listener(self):
         '''Start a new thread to accept xfr query. '''
-        try:
-            os.unlink(self._listen_sock_file)
-        except:
-            pass
-     
+    
         self._unix_socket_server = UnixSockServer(self._listen_sock_file, XfroutSession, 
                                                   self._shutdown_event, self._config_data);
         listener = threading.Thread(target = listen_on_xfr_query, args = (self._unix_socket_server,))
@@ -360,6 +375,9 @@ class XfroutServer:
         ''' shutdown the xfrout process. The thread which is doing zone transfer-out should be
         terminated.
         '''
+
+        global xfrout_server
+        xfrout_server = None #Avoid shutdown is called twice
         self._shutdown_event.set()
         if self._unix_socket_server:
             self._unix_socket_server.shutdown()
@@ -370,7 +388,6 @@ class XfroutServer:
                 continue
             th.join()
 
-
     def command_handler(self, cmd, args):
         if cmd == "shutdown":
             if verbose_mode:
@@ -392,7 +409,7 @@ class XfroutServer:
 xfrout_server = None
 
 def signal_handler(signal, frame):
-   if xfrout_server:
+    if xfrout_server:
         xfrout_server.shutdown()
         sys.exit(0)
 

+ 1 - 1
src/lib/Makefile.am

@@ -1,4 +1,4 @@
-SUBDIRS = exceptions dns cc config auth dns-python python
+SUBDIRS = exceptions dns cc config datasrc python
 if HAVE_BOOST_PYTHON
 if HAVE_BOOST_SYSTEM
 SUBDIRS += xfr

+ 0 - 13
src/lib/auth/Makefile.am

@@ -1,13 +0,0 @@
-SUBDIRS = . tests
-
-AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
-AM_CPPFLAGS += $(SQLITE_CFLAGS)
-
-CLEANFILES = *.gcno *.gcda
-
-lib_LTLIBRARIES = libauth.la
-libauth_la_SOURCES = data_source.h data_source.cc
-libauth_la_SOURCES += static_datasrc.h static_datasrc.cc
-libauth_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
-libauth_la_SOURCES += query.h query.cc

+ 0 - 2
src/lib/auth/TODO

@@ -1,2 +0,0 @@
-- change filenames so we don't have everything starting with "data_source_"?
-- store rdata in the database as binary blobs instead of text

+ 0 - 127
src/lib/auth/tests/unittest_util.cc

@@ -1,127 +0,0 @@
-// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-// $Id$
-
-#include <iostream>
-#include <fstream>
-#include <sstream>
-#include <stdexcept>
-#include <vector>
-#include <string>
-
-#include <gtest/gtest.h>
-
-#include <dns/name.h>
-#include "unittest_util.h"
-
-using isc::UnitTestUtil;
-using isc::dns::NameComparisonResult;
-
-namespace isc {
-
-void
-UnitTestUtil::readWireData(const char* datafile,
-                           std::vector<unsigned char>& data)
-{
-    std::ifstream ifs;
- 
-    ifs.open(datafile, std::ios_base::in);
-    if ((ifs.rdstate() & std::istream::failbit) != 0) {
-        throw std::runtime_error("failed to open data file: " +
-                                 std::string(datafile));
-    }
-
-    data.clear();
-
-    std::string s;
-    while (getline(ifs, s), !ifs.eof()) {
-        if (ifs.bad() || ifs.fail()) {
-            throw std::runtime_error("unexpected data line");
-        }
-        if (s.empty() || s[0] == '#') {
-            continue;
-        }
-
-        readWireData(s, data);
-    }
-}
-
-void
-UnitTestUtil::readWireData(const std::string& datastr,
-                           std::vector<unsigned char>& data)
-{
-    std::istringstream iss(datastr);
-
-    do {
-        std::string bytes;
-        iss >> bytes;
-        if (iss.bad() || iss.fail() || (bytes.size() % 2) != 0) {
-            throw std::runtime_error("unexpected input or I/O error");
-        }
-
-        for (int pos = 0; pos < bytes.size(); pos += 2) {
-            unsigned int ch;
-            std::istringstream(bytes.substr(pos, 2)) >> std::hex >> ch;
-            data.push_back(static_cast<unsigned char>(ch));
-        }
-    } while (!iss.eof());
-}
-
-::testing::AssertionResult
-UnitTestUtil::matchWireData(const char* dataexp1, const char* lenexp1,
-                            const char* dataexp2, const char* lenexp2,
-                            const void* data1, size_t len1,
-                            const void* data2, size_t len2)
-{
-    ::testing::Message msg;
-    size_t cmplen = std::min(len1, len2);
-
-    for (int i = 0; i < cmplen; i++) {
-        int ch1 = static_cast<const uint8_t*>(data1)[i];
-        int ch2 = static_cast<const uint8_t*>(data2)[i];
-        if (ch1 != ch2) {
-            msg << "Wire data mismatch at " << i << "th byte\n"
-                << "  Actual: " << ch1 << "\n"
-                << "Expected: " << ch2 << "\n";
-            return (::testing::AssertionFailure(msg));
-        }
-    }
-    if (len1 != len2) {
-        msg << "Wire data mismatch in length:\n"
-            << "  Actual: " << len1 << "\n"
-            << "Expected: " << len2 << "\n";
-        return (::testing::AssertionFailure(msg));
-    }
-    return ::testing::AssertionSuccess();
-}
-
-::testing::AssertionResult
-UnitTestUtil::matchName(const char* nameexp1, const char* nameexp2,
-                        const isc::dns::Name& name1,
-                        const isc::dns::Name& name2)
-{
-    ::testing::Message msg;
-
-    NameComparisonResult cmpresult = name1.compare(name2);
-    if (cmpresult.getOrder() != 0 ||
-        cmpresult.getRelation() != NameComparisonResult::EQUAL) {
-        msg << "Two names are expected to be equal but not:\n"
-            << "  One: " << name1 << "\n"
-            << "Other: " << name2 << "\n";
-        return (::testing::AssertionFailure(msg));
-    }
-    return ::testing::AssertionSuccess();
-}
-}

+ 0 - 84
src/lib/auth/tests/unittest_util.h

@@ -1,84 +0,0 @@
-// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-// PERFORMANCE OF THIS SOFTWARE.
-
-// $Id$
-
-#ifndef __UNITTEST_UTIL_H
-#define __UNITTEST_UTIL_H 1
-
-#include <vector>
-#include <string>
-
-#include <dns/name.h>
-
-#include <gtest/gtest.h>
-
-namespace isc {
-
-class UnitTestUtil {
-public:
-    ///
-    /// read text format wire data from a file and put it to the given vector.
-    ///
-    static void readWireData(const char*datafile,
-                             std::vector<unsigned char>& data);
-
-    ///
-    /// convert a sequence of hex strings into the corresponding list of
-    /// 8-bit integers, and append them to the vector.
-    ///
-    static void readWireData(const std::string& datastr,
-                             std::vector<unsigned char>& data);
-
-    ///
-    /// Compare len1 bytes of data1 with len2 bytes of data2 as binary data.
-    ///
-    /// If they don't match report the point of mismatch in the google test
-    /// format.  This method is expected to be used from the EXPECT_PRED_FORMAT4
-    /// macro of google test as follows:
-    /// \code EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
-    ///                           actual_data, actual_data_len,
-    ///                           expected_data, expected_data_len); \endcode
-    /// Parameters from dataexp1 to lenexp2 are passed via the macro but will
-    /// be ignored by this method.
-    /// Note: newer versions of google test supports the direct use of
-    /// AssertionResult with the EXPECT_TRUE macro, which would be more
-    /// intuitive, but to be as compatible as possible we use the more primitive
-    /// macro, i.e., EXPECT_PRED_FORMAT4.
-    ///
-    static ::testing::AssertionResult
-    matchWireData(const char* dataexp1, const char* lenexp1,
-                  const char* dataexp2, const char* lenexp2,
-                  const void* data1, size_t len1,
-                  const void* data2, size_t len2);
-
-    ///
-    /// Compare two names.
-    ///
-    /// This check method uses \c Name::compare() for comparison, which performs
-    /// deeper checks including the equality of offsets, and should be better
-    /// than EXPECT_EQ, which uses operater==.  Like the \c matchWireData()
-    /// method, the usage is a bit awkward; the caller should use
-    /// \c EXPECT_PRED_FORMAT2.
-    ///
-    static ::testing::AssertionResult
-    matchName(const char* nameexp1, const char* nameexp2,
-              const isc::dns::Name& name1, const isc::dns::Name& name2);
-};
-}
-#endif // __UNITTEST_UTIL_H
-
-// Local Variables: 
-// mode: c++
-// End: 

+ 2 - 2
src/lib/cc/data.cc

@@ -898,9 +898,9 @@ BoolElement::toWire(std::stringstream& ss,
 {
     ss << encode_length(1, ITEM_BOOL);
     if (boolValue()) {
-        ss << 0x01;
+        ss << '1';
     } else {
-        ss << 0x00;
+        ss << '0';
     }
 }
 

+ 1 - 1
src/lib/cc/data.h

@@ -411,7 +411,7 @@ class MapElement : public Element {
     std::map<std::string, ElementPtr> m;
 
 public:
-    MapElement(std::map<std::string, ElementPtr> v) : Element(map), m(v) {};
+    MapElement(const std::map<std::string, ElementPtr>& v) : Element(map), m(v) {};
     const std::map<std::string, ElementPtr>& mapValue() { return m; }
     using Element::getValue;
     bool getValue(std::map<std::string, ElementPtr>& t) { t = m; return true; };

+ 14 - 0
src/lib/config/tests/data_def_unittests_config.h.in

@@ -1 +1,15 @@
+// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")   
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
 #define TEST_DATA_PATH "@abs_srcdir@/../testdata"

+ 13 - 0
src/lib/datasrc/Makefile.am

@@ -0,0 +1,13 @@
+SUBDIRS = . tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
+AM_CPPFLAGS += $(SQLITE_CFLAGS)
+
+CLEANFILES = *.gcno *.gcda
+
+lib_LTLIBRARIES = libdatasrc.la
+libdatasrc_la_SOURCES = data_source.h data_source.cc
+libdatasrc_la_SOURCES += static_datasrc.h static_datasrc.cc
+libdatasrc_la_SOURCES += sqlite3_datasrc.h sqlite3_datasrc.cc
+libdatasrc_la_SOURCES += query.h query.cc

+ 1 - 0
src/lib/datasrc/TODO

@@ -0,0 +1 @@
+- store rdata in the database as binary blobs instead of text

+ 54 - 61
src/lib/auth/data_source.cc

@@ -49,14 +49,15 @@ using namespace isc::dns;
 using namespace isc::dns::rdata;
 
 namespace isc {
-namespace auth {
+namespace datasrc {
 
 typedef boost::shared_ptr<const Nsec3Param> ConstNsec3ParamPtr;
 
+namespace {
 // Add a task to the query task queue to look up additional data
 // (i.e., address records for the names included in NS or MX records)
-static void
-getAdditional(Query& q, RRsetPtr rrset) {
+void
+getAdditional(Query& q, ConstRRsetPtr rrset) {
     if (!q.wantAdditional()) {
         return;
     }
@@ -64,31 +65,27 @@ getAdditional(Query& q, RRsetPtr rrset) {
     RdataIteratorPtr it = rrset->getRdataIterator();
     for (it->first(); !it->isLast(); it->next()) {
         const Rdata& rd(it->getCurrent());
-        QueryTaskPtr newtask = QueryTaskPtr();
-
         if (rrset->getType() == RRType::NS()) {
             const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
-
-            newtask = QueryTaskPtr(new QueryTask(ns.getNSName(), q.qclass(),
-                                                 Section::ADDITIONAL(),
-                                                 QueryTask::GLUE_QUERY,
-                                                 QueryTask::GETADDITIONAL)); 
+            q.tasks().push(QueryTaskPtr(
+                               new QueryTask(ns.getNSName(), q.qclass(),
+                                             Section::ADDITIONAL(),
+                                             QueryTask::GLUE_QUERY,
+                                             QueryTask::GETADDITIONAL))); 
         } else if (rrset->getType() == RRType::MX()) {
             const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
-            newtask = QueryTaskPtr(new QueryTask(mx.getMXName(), q.qclass(),
-                                                 Section::ADDITIONAL(),
-                                                 QueryTask::NOGLUE_QUERY,
-                                                 QueryTask::GETADDITIONAL)); 
-        }
-        if (newtask) {
-            q.tasks().push(newtask);
+            q.tasks().push(QueryTaskPtr(
+                               new QueryTask(mx.getMXName(), q.qclass(),
+                                             Section::ADDITIONAL(),
+                                             QueryTask::NOGLUE_QUERY,
+                                             QueryTask::GETADDITIONAL))); 
         }
     }
 }
 
 // Synthesize a CNAME answer, for the benefit of clients that don't
 // understand DNAME
-static void
+void
 synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
     RdataIteratorPtr it = rrset->getRdataIterator();
 
@@ -117,9 +114,8 @@ synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
 
 // Add a task to the query task queue to look up the data pointed
 // to by a CNAME record
-static void
-chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
-{
+void
+chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
     RdataIteratorPtr it = rrset->getRdataIterator();
 
     // More than one CNAME RR in the RRset is illegal, so we only have
@@ -143,7 +139,7 @@ chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
 }
 
 // Perform the query specified in a QueryTask object
-static DataSrc::Result
+DataSrc::Result
 doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
             RRsetList& target)
 {
@@ -171,9 +167,8 @@ doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
 }
 
 // Copy referral information into the authority section of a message
-static inline void
-copyAuth(Query& q, RRsetList& auth)
-{
+inline void
+copyAuth(Query& q, RRsetList& auth) {
     BOOST_FOREACH(RRsetPtr rrset, auth) {
         if (rrset->getType() == RRType::DNAME()) {
             continue;
@@ -187,11 +182,11 @@ copyAuth(Query& q, RRsetList& auth)
 }
 
 // Query for referrals (i.e., NS/DS or DNAME) at a given name
-static inline bool
-refQuery(const Name& name, Query& q, const DataSrc* ds, const Name* zonename,
-         RRsetList& target)
+inline bool
+refQuery(const Name& name, const RRClass& qclass, const DataSrc* ds,
+         const Name* zonename, RRsetList& target)
 {
-    QueryTask newtask(name, q.qclass(), QueryTask::REF_QUERY);
+    QueryTask newtask(name, qclass, QueryTask::REF_QUERY);
 
     if (doQueryTask(ds, zonename, newtask, target) != DataSrc::SUCCESS) {
         // Lookup failed
@@ -208,18 +203,18 @@ refQuery(const Name& name, Query& q, const DataSrc* ds, const Name* zonename,
 
 // Match downward, from the zone apex to the query name, looking for
 // referrals.
-static inline bool
+inline bool
 hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
               QueryTaskPtr task)
 {
-    int nlen = task->qname.getLabelCount();
-    int diff = nlen - zonename->getLabelCount();
+    const int nlen = task->qname.getLabelCount();
+    const int diff = nlen - zonename->getLabelCount();
     if (diff > 1) {
         bool found = false;
         RRsetList ref;
         for (int i = diff; i > 1; --i) {
             const Name sub(task->qname.split(i - 1, nlen - i));
-            if (refQuery(sub, q, ds, zonename, ref)) {
+            if (refQuery(sub, q.qclass(), ds, zonename, ref)) {
                 found = true;
                 break;
             }
@@ -267,7 +262,7 @@ hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
     return (false);
 }
 
-static inline DataSrc::Result
+inline DataSrc::Result
 addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
     Message& m = q.message();
     RRsetList soa;
@@ -284,7 +279,7 @@ addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
     return (DataSrc::SUCCESS);
 }
 
-static inline DataSrc::Result
+inline DataSrc::Result
 addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
         const Name& zonename, const DataSrc* ds)
 {
@@ -302,7 +297,7 @@ addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
     return (DataSrc::SUCCESS);
 }
 
-static inline DataSrc::Result
+inline DataSrc::Result
 getNsec3(const DataSrc* ds, const Name& zonename, const RRClass& qclass,
          string& hash, RRsetPtr& target)
 {
@@ -312,7 +307,7 @@ getNsec3(const DataSrc* ds, const Name& zonename, const RRClass& qclass,
     return (DataSrc::SUCCESS);
 }
 
-static ConstNsec3ParamPtr
+ConstNsec3ParamPtr
 getNsec3Param(Query& q, const DataSrc* ds, const Name& zonename) {
     DataSrc::Result result;
     RRsetList nsec3param;
@@ -345,7 +340,7 @@ getNsec3Param(Query& q, const DataSrc* ds, const Name& zonename) {
                                               np.getSalt())));
 }
 
-static inline DataSrc::Result
+inline DataSrc::Result
 proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
         const Name& zonename, const bool wildcard)
 {
@@ -354,7 +349,7 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
     if (nsec3 != NULL) {
         // Attach the NSEC3 record covering the QNAME
         RRsetPtr rrset;
-        string hash1(nsec3->getHash(task->qname)), hash2;
+        string hash1(nsec3->getHash(task->qname));
         RETERR(getNsec3(ds, zonename, q.qclass(), hash1, rrset));
         m.addRRset(Section::AUTHORITY(), rrset, true);
 
@@ -365,8 +360,9 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
 
         // Find the closest provable enclosing name for QNAME
         Name enclosure(zonename);
-        int nlen = task->qname.getLabelCount();
-        int diff = nlen - enclosure.getLabelCount();
+        const int nlen = task->qname.getLabelCount();
+        const int diff = nlen - enclosure.getLabelCount();
+        string hash2;
         for (int i = 1; i <= diff; ++i) {
             enclosure = task->qname.split(i, nlen - i);
             string nodehash(nsec3->getHash(enclosure));
@@ -424,7 +420,7 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
 }
 
 // Attempt a wildcard lookup
-static inline DataSrc::Result
+inline DataSrc::Result
 tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
             const Name* zonename, bool& found)
 {
@@ -502,7 +498,7 @@ tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
             }
 
             RRsetList auth;
-            if (! refQuery(*zonename, q, ds, zonename, auth)) {
+            if (!refQuery(*zonename, q.qclass(), ds, zonename, auth)) {
                 return (DataSrc::ERROR);
             }
 
@@ -512,13 +508,13 @@ tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
 
     return (DataSrc::SUCCESS);
 }
+} // end of anonymous namespace
 
 //
 // doQuery: Processes a query.
 // 
 void
-DataSrc::doQuery(Query& q)
-{
+DataSrc::doQuery(Query& q) {
     Message& m = q.message();
     vector<RRsetPtr> additional;
 
@@ -543,7 +539,7 @@ DataSrc::doQuery(Query& q)
         // Find the closest enclosing zone for which we are authoritative,
         // and the concrete data source which is authoritative for it.
         // (Note that RRtype DS queries need to go to the parent.)
-        int nlabels = task->qname.getLabelCount() - 1;
+        const int nlabels = task->qname.getLabelCount() - 1;
         NameMatch match(nlabels != 0 && task->qtype == RRType::DS() ?
                         task->qname.split(1, task->qname.getLabelCount() - 1) :
                         task->qname);
@@ -618,7 +614,8 @@ DataSrc::doQuery(Query& q)
                     // Add the NS records for the enclosing zone to
                     // the authority section.
                     RRsetList auth;
-                    if (!refQuery(*zonename, q, datasource, zonename, auth)) {
+                    if (!refQuery(*zonename, q.qclass(), datasource, zonename,
+                                  auth)) {
                         m.setRcode(Rcode::SERVFAIL());
                         return;
                     }
@@ -661,7 +658,8 @@ DataSrc::doQuery(Query& q)
             if (task->state == QueryTask::GETANSWER) {
                 RRsetList auth;
                 m.clearHeaderFlag(MessageFlag::AA());
-                if (!refQuery(task->qname, q, datasource, zonename, auth)) {
+                if (!refQuery(task->qname, q.qclass(), datasource, zonename,
+                              auth)) {
                     m.setRcode(Rcode::SERVFAIL());
                     return;
                 }
@@ -806,8 +804,7 @@ DataSrc::findReferral(const Name& qname, const RRClass& qclass,
     }
 
     flags = 0;
-    r = findExactRRset(qname, qclass, RRType::DNAME(), target, flags,
-                       zonename);
+    r = findExactRRset(qname, qclass, RRType::DNAME(), target, flags, zonename);
     if (r == SUCCESS && flags == 0) {
         dname = true;
     } else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
@@ -824,8 +821,7 @@ DataSrc::findReferral(const Name& qname, const RRClass& qclass,
 }
 
 void
-MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src)
-{
+MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src) {
     if (getClass() != RRClass::ANY() && data_src->getClass() != getClass()) {
         isc_throw(Unexpected, "class mismatch");
     }
@@ -834,8 +830,7 @@ MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src)
 }
 
 void
-MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src)
-{
+MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src) {
     std::vector<ConstDataSrcPtr>::iterator it, itr;
     for (it = data_sources.begin(); it != data_sources.end(); it++) {
         if (*it == data_src) {
@@ -859,14 +854,12 @@ MetaDataSrc::findClosestEnclosure(NameMatch& match, const RRClass& qclass) const
     }
 }
 
-NameMatch::~NameMatch()
-{
+NameMatch::~NameMatch() {
     delete closest_name_;
 }
 
 void
-NameMatch::update(const DataSrc& new_source, const Name& container)
-{
+NameMatch::update(const DataSrc& new_source, const Name& container) {
     if (closest_name_ == NULL) {
         closest_name_ = new Name(container);
         best_source_ = &new_source;
@@ -875,14 +868,14 @@ NameMatch::update(const DataSrc& new_source, const Name& container)
 
     if (container.compare(*closest_name_).getRelation() ==
         NameComparisonResult::SUBDOMAIN) {
-        Name* newname = new Name(container);
+        const Name* newname = new Name(container);
         delete closest_name_;
         closest_name_ = newname;
         best_source_ = &new_source;
     }
 }
 
-Nsec3Param::Nsec3Param(uint8_t a, uint8_t f, uint16_t i,
+Nsec3Param::Nsec3Param(const uint8_t a, const uint8_t f, const uint16_t i,
                        const std::vector<uint8_t>& s) :
     algorithm_(a), flags_(f), iterations_(i), salt_(s)
 {}
@@ -893,7 +886,7 @@ Nsec3Param::getHash(const Name& name) const {
     name.toWire(buf);
 
     uint8_t digest[SHA1_HASHSIZE];
-    uint8_t* input = (uint8_t*) buf.getData();
+    const uint8_t* input = static_cast<const uint8_t*>(buf.getData());
     size_t inlength = buf.getLength();
     const uint8_t saltlen = salt_.size();
 

+ 1 - 1
src/lib/auth/data_source.h

@@ -38,7 +38,7 @@ class RRset;
 class RRsetList;
 }
 
-namespace auth {
+namespace datasrc {
 
 class NameMatch;
 class Query;

+ 1 - 1
src/lib/auth/query.cc

@@ -26,7 +26,7 @@
 using namespace isc::dns;
 
 namespace isc {
-namespace auth {
+namespace datasrc {
 
 QueryTask::QueryTask(const isc::dns::Name& n, const isc::dns::RRClass& c,
                      const isc::dns::RRType& t, const isc::dns::Section& sect) :

+ 1 - 1
src/lib/auth/query.h

@@ -28,7 +28,7 @@
 
 namespace isc {
 
-namespace auth {
+namespace datasrc {
 
 // An individual task to be carried out by the query logic
 class QueryTask {

+ 7 - 7
src/lib/auth/sqlite3_datasrc.cc

@@ -32,7 +32,7 @@ using namespace isc::dns;
 using namespace isc::dns::rdata;
 
 namespace isc {
-namespace auth {
+namespace datasrc {
 
 struct Sqlite3Parameters {
     Sqlite3Parameters() :  db_(NULL), version_(-1),
@@ -330,7 +330,7 @@ int
 Sqlite3DataSrc::findClosest(const Name& name, unsigned int* position) const {
     const unsigned int nlabels = name.getLabelCount();
     for (unsigned int i = 0; i < nlabels; ++i) {
-        Name matchname(name.split(i, nlabels - i));
+        const Name matchname(name.split(i, nlabels - i));
         const int rc = hasExactZone(matchname.toText().c_str());
         if (rc >= 0) {
             if (position != NULL) {
@@ -563,7 +563,7 @@ Sqlite3DataSrc::init(const isc::data::ElementPtr config) {
     if (config && config->contains("database_file")) {
         open(config->get("database_file")->stringValue());
     } else {
-        isc_throw(DataSourceError, "No sqlite3 database file specified");
+        isc_throw(DataSourceError, "No SQLite database file specified");
     }
     return (SUCCESS);
 }
@@ -621,7 +621,7 @@ sqlite3_stmt*
 prepare(sqlite3* const db, const char* const statement) {
     sqlite3_stmt* prepared = NULL;
     if (sqlite3_prepare_v2(db, statement, -1, &prepared, NULL) != SQLITE_OK) { 
-        isc_throw(Sqlite3Error, "could not prepare sqlite3 statement: " <<
+        isc_throw(Sqlite3Error, "Could not prepare SQLite statement: " <<
                   statement);
     }
     return (prepared);
@@ -668,13 +668,13 @@ checkAndSetupSchema(Sqlite3Initializer* initializer) {
 void
 Sqlite3DataSrc::open(const string& name) {
     if (dbparameters->db_ != NULL) {
-        isc_throw(DataSourceError, "Duplicate Sqlite3 open with " << name);
+        isc_throw(DataSourceError, "Duplicate SQLite open with " << name);
     }
 
     Sqlite3Initializer initializer;
 
     if (sqlite3_open(name.c_str(), &initializer.params_.db_) != 0) {
-        isc_throw(Sqlite3Error, "Cannot open Sqlite3 database file: " << name);
+        isc_throw(Sqlite3Error, "Cannot open SQLite database file: " << name);
     }
 
     checkAndSetupSchema(&initializer);
@@ -688,7 +688,7 @@ DataSrc::Result
 Sqlite3DataSrc::close(void) {
     if (dbparameters->db_ == NULL) {
         isc_throw(DataSourceError,
-                  "Sqlite3 data source is being closed before open");
+                  "SQLite data source is being closed before open");
     }
 
     // XXX: sqlite3_finalize() could fail.  What should we do in that case?

+ 1 - 1
src/lib/auth/sqlite3_datasrc.h

@@ -32,7 +32,7 @@ class RRType;
 class RRsetList;
 }
 
-namespace auth {
+namespace datasrc {
 
 class Query;
 struct Sqlite3Parameters;

+ 2 - 2
src/lib/auth/static_datasrc.cc

@@ -34,7 +34,7 @@ using namespace isc::dns;
 using namespace isc::dns::rdata;
 
 namespace isc {
-namespace auth {
+namespace datasrc {
 
 // This class stores the "static" data for the built-in static data source.
 // Since it's static, it could be literally static, i.e, defined as static
@@ -94,7 +94,7 @@ StaticDataSrcImpl::StaticDataSrcImpl() :
 
     version = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                  RRType::TXT(), RRTTL(0)));
-    version->addRdata(generic::TXT("BIND10 0.0.0 (pre-alpha)"));
+    version->addRdata(generic::TXT(PACKAGE_STRING));
 
     version_ns = RRsetPtr(new RRset(version_name, RRClass::CH(),
                                     RRType::NS(), RRTTL(0)));

+ 1 - 1
src/lib/auth/static_datasrc.h

@@ -37,7 +37,7 @@ class RRType;
 class RRsetList;
 }
 
-namespace auth {
+namespace datasrc {
 
 class Query;
 class NameMatch;

+ 6 - 4
src/lib/auth/tests/Makefile.am

@@ -1,5 +1,6 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/lib/dns
+AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(srcdir)/testdata\"
 
 CLEANFILES = *.gcno *.gcda
 
@@ -7,7 +8,8 @@ TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES = run_unittests.cc
-run_unittests_SOURCES += unittest_util.h unittest_util.cc
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
+run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
 run_unittests_SOURCES += datasrc_unittest.cc
 run_unittests_SOURCES += sqlite3_unittest.cc
 run_unittests_SOURCES += static_unittest.cc
@@ -17,7 +19,7 @@ run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD = $(GTEST_LDADD)
 run_unittests_LDADD += $(SQLITE_LIBS)
-run_unittests_LDADD += $(top_builddir)/src/lib/auth/.libs/libauth.a 
+run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/.libs/libdatasrc.a 
 run_unittests_LDADD += $(top_builddir)/src/lib/dns/.libs/libdns.a 
 run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.a 
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/.libs/libexceptions.a
@@ -26,11 +28,11 @@ endif
 noinst_PROGRAMS = $(TESTS)
 
 EXTRA_DIST =  testdata/brokendb.sqlite3
-EXTRA_DIST += testdata/example2.com
-EXTRA_DIST += testdata/example2.com.sqlite3
 EXTRA_DIST += testdata/example.com.signed
 EXTRA_DIST += testdata/example.org
 EXTRA_DIST += testdata/example.org.sqlite3
+EXTRA_DIST += testdata/example2.com
+EXTRA_DIST += testdata/example2.com.sqlite3
 EXTRA_DIST += testdata/mkbrokendb.c
 EXTRA_DIST += testdata/q_cname
 EXTRA_DIST += testdata/q_cname_ext

+ 40 - 26
src/lib/auth/tests/datasrc_unittest.cc

@@ -34,23 +34,23 @@
 
 #include <cc/data.h>
 
-#include <auth/query.h>
-#include <auth/sqlite3_datasrc.h>
-#include <auth/static_datasrc.h>
+#include <datasrc/query.h>
+#include <datasrc/sqlite3_datasrc.h>
+#include <datasrc/static_datasrc.h>
 
-#include "unittest_util.h"
+#include <dns/tests/unittest_util.h>
 #include "test_datasrc.h"
 
 using isc::UnitTestUtil;
 using namespace std;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
-using namespace isc::auth;
+using namespace isc::datasrc;
 using namespace isc::data;
 
 namespace {
 const ElementPtr SQLITE_DBFILE_EXAMPLE = Element::createFromString(
-    "{ \"database_file\": \"testdata/example.org.sqlite3\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/example.org.sqlite3\"}");
 
 class DataSrcTest : public ::testing::Test {
 protected:
@@ -192,7 +192,7 @@ TEST_F(DataSrcTest, QueryClassAny) {
 }
 
 TEST_F(DataSrcTest, NSQuery) {
-    readAndProcessQuery("testdata/q_example_ns");
+    readAndProcessQuery("q_example_ns");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
@@ -214,7 +214,7 @@ TEST_F(DataSrcTest, NSQuery) {
 }
 
 TEST_F(DataSrcTest, NxRRset) {
-    readAndProcessQuery("testdata/q_example_ptr");
+    readAndProcessQuery("q_example_ptr");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 4, 0);
 
@@ -225,7 +225,7 @@ TEST_F(DataSrcTest, NxRRset) {
 }
 
 TEST_F(DataSrcTest, Nxdomain) {
-    readAndProcessQuery("testdata/q_glork");
+    readAndProcessQuery("q_glork");
 
     headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 6, 0);
 
@@ -238,7 +238,7 @@ TEST_F(DataSrcTest, Nxdomain) {
 }
 
 TEST_F(DataSrcTest, NxZone) {
-    readAndProcessQuery("testdata/q_spork");
+    readAndProcessQuery("q_spork");
 
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
 
@@ -249,7 +249,7 @@ TEST_F(DataSrcTest, NxZone) {
 }
 
 TEST_F(DataSrcTest, Wildcard) {
-    readAndProcessQuery("testdata/q_wild_a");
+    readAndProcessQuery("q_wild_a");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 6, 6);
 
@@ -305,14 +305,14 @@ TEST_F(DataSrcTest, WildcardNodata) {
 
     // Check that a query for a data type not covered by the wildcard
     // returns NOERROR
-    readAndProcessQuery("testdata/q_wild_aaaa");
+    readAndProcessQuery("q_wild_aaaa");
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 2, 0);
 }
 
 TEST_F(DataSrcTest, WildcardCname) {
     // Check that wildcard answers containing CNAMES are followed
     // correctly
-    readAndProcessQuery("testdata/q_wild2_a");
+    readAndProcessQuery("q_wild2_a");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 6, 6);
 
@@ -380,7 +380,7 @@ TEST_F(DataSrcTest, WildcardCname) {
 TEST_F(DataSrcTest, WildcardCnameNodata) {
     // A wildcard containing a CNAME whose target does not include
     // data of this type.
-    readAndProcessQuery("testdata/q_wild2_aaaa");
+    readAndProcessQuery("q_wild2_aaaa");
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 0);
 
     RRsetIterator rit = msg.beginSection(Section::ANSWER());
@@ -411,7 +411,7 @@ TEST_F(DataSrcTest, WildcardCnameNodata) {
 
 TEST_F(DataSrcTest, WildcardCnameNxdomain) {
     // A wildcard containing a CNAME whose target does not exist
-    readAndProcessQuery("testdata/q_wild3_a");
+    readAndProcessQuery("q_wild3_a");
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 6, 0);
 
     RRsetIterator rit = msg.beginSection(Section::ANSWER());
@@ -447,7 +447,7 @@ TEST_F(DataSrcTest, WildcardCnameNxdomain) {
     EXPECT_EQ(RRClass::IN(), rrset->getClass());
 }
 TEST_F(DataSrcTest, AuthDelegation) {
-    readAndProcessQuery("testdata/q_sql1");
+    readAndProcessQuery("q_sql1");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
@@ -493,7 +493,7 @@ TEST_F(DataSrcTest, AuthDelegation) {
 }
 
 TEST_F(DataSrcTest, Dname) {
-    readAndProcessQuery("testdata/q_dname");
+    readAndProcessQuery("q_dname");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 5, 4, 6);
 
@@ -541,7 +541,7 @@ TEST_F(DataSrcTest, Dname) {
 }
 
 TEST_F(DataSrcTest, Cname) {
-    readAndProcessQuery("testdata/q_cname");
+    readAndProcessQuery("q_cname");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 0, 0);
 
@@ -559,7 +559,7 @@ TEST_F(DataSrcTest, Cname) {
 }
 
 TEST_F(DataSrcTest, CnameInt) {
-    readAndProcessQuery("testdata/q_cname_int");
+    readAndProcessQuery("q_cname_int");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
@@ -585,7 +585,7 @@ TEST_F(DataSrcTest, CnameInt) {
 }
 
 TEST_F(DataSrcTest, CnameExt) {
-    readAndProcessQuery("testdata/q_cname_ext");
+    readAndProcessQuery("q_cname_ext");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
@@ -609,7 +609,7 @@ TEST_F(DataSrcTest, CnameExt) {
 }
 
 TEST_F(DataSrcTest, Delegation) {
-    readAndProcessQuery("testdata/q_subzone");
+    readAndProcessQuery("q_subzone");
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
@@ -639,7 +639,7 @@ TEST_F(DataSrcTest, Delegation) {
 }
 
 TEST_F(DataSrcTest, NSDelegation) {
-    readAndProcessQuery("testdata/q_subzone_ns");
+    readAndProcessQuery("q_subzone_ns");
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
@@ -671,12 +671,12 @@ TEST_F(DataSrcTest, NSDelegation) {
 TEST_F(DataSrcTest, ANYZonecut) {
     // An ANY query at a zone cut should behave the same as any other
     // delegation
-    readAndProcessQuery("testdata/q_subzone_any");
+    readAndProcessQuery("q_subzone_any");
 
 }
 
 TEST_F(DataSrcTest, NSECZonecut) {
-    readAndProcessQuery("testdata/q_subzone_nsec");
+    readAndProcessQuery("q_subzone_nsec");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
@@ -704,7 +704,7 @@ TEST_F(DataSrcTest, NSECZonecut) {
 }
 
 TEST_F(DataSrcTest, DNAMEZonecut) {
-    readAndProcessQuery("testdata/q_subzone_dname");
+    readAndProcessQuery("q_subzone_dname");
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
     RRsetIterator rit = msg.beginSection(Section::AUTHORITY());
@@ -733,7 +733,7 @@ TEST_F(DataSrcTest, DNAMEZonecut) {
 }
 
 TEST_F(DataSrcTest, DS) {
-    readAndProcessQuery("testdata/q_subzone_ds");
+    readAndProcessQuery("q_subzone_ds");
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 3, 4, 6);
 
@@ -842,4 +842,18 @@ TEST_F(DataSrcTest, AddRemoveDataSrc) {
     ds.removeDataSrc(tsp);
     EXPECT_EQ(0, ds.dataSrcCount());
 }
+
+#if 0                           // currently fails
+TEST_F(DataSrcTest, synthesizedCnameTooLong) {
+    // qname has the possible max length (255 octets).  it matches a DNAME,
+    // and the synthesized CNAME would exceed the valid length.
+    createAndProcessQuery(
+        Name("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde."
+             "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde."
+             "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde."
+             "0123456789abcdef0123456789abcdef0123456789a.dname.example.org."),
+        RRClass::IN(), RRType::A());
+}
+#endif
+
 }

+ 2 - 2
src/lib/auth/tests/query_unittest.cc

@@ -20,12 +20,12 @@
 #include <dns/rrtype.h>
 #include <dns/rrclass.h>
 
-#include <auth/query.h>
+#include <datasrc/query.h>
 
 namespace {
 
 using namespace isc::dns;
-using namespace isc::auth;
+using namespace isc::datasrc;
 
 
 class QueryTest : public ::testing::Test {

+ 4 - 0
src/lib/auth/tests/run_unittests.cc

@@ -16,9 +16,13 @@
 
 #include <gtest/gtest.h>
 
+#include <dns/tests/unittest_util.h>
+
 int
 main(int argc, char* argv[])
 {
     ::testing::InitGoogleTest(&argc, argv);
+    isc::UnitTestUtil::addDataPath(TEST_DATA_DIR);
+
     return (RUN_ALL_TESTS());
 }

+ 9 - 9
src/lib/auth/tests/sqlite3_unittest.cc

@@ -32,25 +32,25 @@
 #include <dns/rrsetlist.h>
 #include <cc/data.h>
 
-#include <auth/query.h>
-#include <auth/data_source.h>
-#include <auth/sqlite3_datasrc.h>
+#include <datasrc/query.h>
+#include <datasrc/data_source.h>
+#include <datasrc/sqlite3_datasrc.h>
 
 using namespace std;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
-using namespace isc::auth;
+using namespace isc::datasrc;
 using namespace isc::data;
 
 namespace {
 ElementPtr SQLITE_DBFILE_EXAMPLE = Element::createFromString(
-    "{ \"database_file\": \"testdata/test.sqlite3\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/test.sqlite3\"}");
 ElementPtr SQLITE_DBFILE_EXAMPLE2 = Element::createFromString(
-    "{ \"database_file\": \"testdata/test2.sqlite3\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/example2.com.sqlite3\"}");
 ElementPtr SQLITE_DBFILE_EXAMPLE_ROOT = Element::createFromString(
-    "{ \"database_file\": \"testdata/test-root.sqlite3\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/test-root.sqlite3\"}");
 ElementPtr SQLITE_DBFILE_BROKENDB = Element::createFromString(
-    "{ \"database_file\": \"testdata/brokendb.sqlite3\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/brokendb.sqlite3\"}");
 ElementPtr SQLITE_DBFILE_MEMORY = Element::createFromString(
     "{ \"database_file\": \":memory:\"}");
 
@@ -59,7 +59,7 @@ ElementPtr SQLITE_DBFILE_MEMORY = Element::createFromString(
 // so to test a failure case the create operation should also fail.
 // The "nodir", a non existent directory, is inserted for this purpose.
 ElementPtr SQLITE_DBFILE_NOTEXIST = Element::createFromString(
-    "{ \"database_file\": \"testdata/nodir/notexist\"}");
+    "{ \"database_file\": \"" TEST_DATA_DIR "/nodir/notexist\"}");
 
 const string sigdata_common(" 20100322084538 20100220084538 "
                             "33495 example.com. FAKEFAKEFAKEFAKE");

+ 9 - 7
src/lib/auth/tests/static_unittest.cc

@@ -18,6 +18,8 @@
 #include <string>
 #include <vector>
 
+#include "config.h"
+
 #include <gtest/gtest.h>
 
 #include <dns/name.h>
@@ -29,14 +31,14 @@
 #include <dns/rrsetlist.h>
 #include <cc/data.h>
 
-#include <auth/query.h>
-#include <auth/data_source.h>
-#include <auth/static_datasrc.h>
+#include <datasrc/query.h>
+#include <datasrc/data_source.h>
+#include <datasrc/static_datasrc.h>
 
 using namespace std;
 using namespace isc::dns;
 using namespace isc::dns::rdata;
-using namespace isc::auth;
+using namespace isc::datasrc;
 
 namespace {
 class StaticDataSourceTest : public ::testing::Test {
@@ -47,9 +49,9 @@ protected:
                              rrclass(RRClass::CH()), rrtype(RRType::TXT()),
                              rrttl(RRTTL(0)), find_flags(0), matched_rdata(0)
     {
-        // XXX: the following values can change as release/developers change,
-        // in which case the test code must be updated accordingly.
-        version_data.push_back("BIND10 0.0.0 (pre-alpha)");
+        // version.bind is answered with package name+version
+        // (defined as PACKAGE_STRING in config.h)
+        version_data.push_back(PACKAGE_STRING);
 
         // XXX: in addition, the order the following items matter.
         authors_data.push_back("Evan Hunt");

+ 3 - 3
src/lib/auth/tests/test_datasrc.cc

@@ -18,10 +18,10 @@
 
 #include <cassert>
 
-#include "unittest_util.h"
+#include <dns/tests/unittest_util.h>
 #include "test_datasrc.h"
 
-#include <auth/data_source.h>
+#include <datasrc/data_source.h>
 
 #include <dns/buffer.h>
 #include <dns/messagerenderer.h>
@@ -42,7 +42,7 @@ using namespace isc::dns;
 using namespace isc::dns::rdata;
 
 namespace isc {
-namespace auth {
+namespace datasrc {
 
 namespace {
 const Name example("example.com");

+ 2 - 2
src/lib/auth/tests/test_datasrc.h

@@ -19,7 +19,7 @@
 
 #include <gtest/gtest.h>
 
-#include <auth/data_source.h>
+#include <datasrc/data_source.h>
 
 namespace isc {
 
@@ -30,7 +30,7 @@ class RRType;
 class RRsetList;
 }
 
-namespace auth {
+namespace datasrc {
 class Query;
 
 class TestDataSrc : public DataSrc {

src/lib/auth/tests/testdata/brokendb.sqlite3 → src/lib/datasrc/tests/testdata/brokendb.sqlite3


src/lib/auth/tests/testdata/example.com.signed → src/lib/datasrc/tests/testdata/example.com.signed


+ 1 - 0
src/lib/auth/tests/testdata/example.org

@@ -10,3 +10,4 @@ www.example.org. A 192.0.2.1
 mail.example.org. A 192.0.2.10
 sub.example.org. NS ns.sub.example.org.
 ns.sub.example.org. A 192.0.2.101
+dname.example.org. DNAME dname.example.info.

BIN
src/lib/auth/tests/testdata/example.org.sqlite3


src/lib/auth/tests/testdata/example2.com → src/lib/datasrc/tests/testdata/example2.com


src/lib/auth/tests/testdata/example2.com.sqlite3 → src/lib/datasrc/tests/testdata/example2.com.sqlite3


src/lib/auth/tests/testdata/mkbrokendb.c → src/lib/datasrc/tests/testdata/mkbrokendb.c


src/lib/auth/tests/testdata/q_cname → src/lib/datasrc/tests/testdata/q_cname


+ 0 - 0
src/lib/auth/tests/testdata/q_cname_ext


Some files were not shown because too many files changed in this diff