Browse Source

[trac751]Merge branch 'master' into trac751

Conflicts:
	src/lib/Makefile.am
	src/lib/resolve/recursive_query.h
Ocean Wang 14 years ago
parent
commit
262ac6c6fc
96 changed files with 13098 additions and 520 deletions
  1. 267 240
      ChangeLog
  2. 7 0
      configure.ac
  3. 5 1
      doc/Doxyfile
  4. 1 1
      src/bin/Makefile.am
  5. 1 1
      src/bin/auth/Makefile.am
  6. 36 0
      src/bin/auth/common.cc
  7. 10 1
      src/bin/auth/common.h
  8. 2 14
      src/bin/auth/main.cc
  9. 6 0
      src/bin/auth/tests/Makefile.am
  10. 96 0
      src/bin/auth/tests/common_unittest.cc
  11. 38 11
      src/bin/bind10/bind10.8
  12. 51 8
      src/bin/bind10/bind10.xml
  13. 2 1
      src/bin/bind10/tests/Makefile.am
  14. 18 0
      src/bin/sockcreator/Makefile.am
  15. 49 0
      src/bin/sockcreator/README
  16. 10 16
      src/lib/xfr/python_xfr.cc
  17. 151 0
      src/bin/sockcreator/sockcreator.cc
  18. 100 0
      src/bin/sockcreator/sockcreator.h
  19. 25 0
      src/bin/sockcreator/tests/Makefile.am
  20. 22 0
      src/bin/sockcreator/tests/run_unittests.cc
  21. 273 0
      src/bin/sockcreator/tests/sockcreator_tests.cc
  22. 2 2
      src/bin/xfrout/tests/Makefile.am
  23. 32 0
      src/bin/xfrout/tests/xfrout_test.py
  24. 25 16
      src/bin/xfrout/xfrout.py.in
  25. 1 1
      src/lib/Makefile.am
  26. 1 1
      src/lib/datasrc/tests/rbtree_unittest.cc
  27. 105 27
      src/lib/dns/buffer.h
  28. 7 4
      src/lib/dns/python/edns_python.cc
  29. 22 13
      src/lib/dns/python/message_python.cc
  30. 12 4
      src/lib/dns/python/messagerenderer_python.cc
  31. 42 12
      src/lib/dns/python/name_python.cc
  32. 1 1
      src/lib/dns/python/question_python.cc
  33. 5 5
      src/lib/dns/python/rcode_python.cc
  34. 6 5
      src/lib/dns/python/rrclass_python.cc
  35. 6 2
      src/lib/dns/python/rrttl_python.cc
  36. 6 6
      src/lib/dns/python/rrtype_python.cc
  37. 6 7
      src/lib/dns/python/tests/edns_python_test.py
  38. 19 9
      src/lib/dns/python/tests/message_python_test.py
  39. 5 0
      src/lib/dns/python/tests/messagerenderer_python_test.py
  40. 16 3
      src/lib/dns/python/tests/name_python_test.py
  41. 1 1
      src/lib/dns/python/tests/question_python_test.py
  42. 13 6
      src/lib/dns/python/tests/rcode_python_test.py
  43. 7 2
      src/lib/dns/python/tests/rrclass_python_test.py
  44. 8 2
      src/lib/dns/python/tests/rrttl_python_test.py
  45. 10 6
      src/lib/dns/python/tests/rrtype_python_test.py
  46. 2 1
      src/lib/dns/rdata.cc
  47. 11 0
      src/lib/dns/rdata.h
  48. 124 0
      src/lib/dns/rdata/generic/rp_17.cc
  49. 88 0
      src/lib/dns/rdata/generic/rp_17.h
  50. 1 1
      src/lib/dns/rdata/template.cc
  51. 1 1
      src/lib/dns/rdata/template.h
  52. 1 0
      src/lib/dns/tests/Makefile.am
  53. 49 0
      src/lib/dns/tests/buffer_unittest.cc
  54. 162 0
      src/lib/dns/tests/rdata_rp_unittest.cc
  55. 8 0
      src/lib/dns/tests/testdata/Makefile.am
  56. 32 3
      src/lib/dns/tests/testdata/gen-wiredata.py.in
  57. 6 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec
  58. 12 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec
  59. 7 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec
  60. 7 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec
  61. 7 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec
  62. 7 0
      src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec
  63. 8 0
      src/lib/dns/tests/testdata/rdata_rp_toWire1.spec
  64. 14 0
      src/lib/dns/tests/testdata/rdata_rp_toWire2.spec
  65. 23 8
      src/lib/resolve/recursive_query.cc
  66. 43 4
      src/lib/resolve/recursive_query.h
  67. 16 1
      src/lib/resolve/tests/recursive_query_unittest_2.cc
  68. 3 0
      src/lib/util/Makefile.am
  69. 16 0
      src/lib/util/io/Makefile.am
  70. 70 0
      src/lib/util/io/fd.cc
  71. 61 0
      src/lib/util/io/fd.h
  72. 10 8
      src/lib/xfr/fd_share.cc
  73. 65 0
      src/lib/util/io/fd_share.h
  74. 22 9
      src/lib/xfr/fdshare_python.cc
  75. 25 0
      src/lib/util/io/tests/Makefile.am
  76. 74 0
      src/lib/util/io/tests/fd_share_tests.cc
  77. 66 0
      src/lib/util/io/tests/fd_tests.cc
  78. 22 0
      src/lib/util/io/tests/run_unittests.cc
  79. 9 0
      src/lib/util/unittests/Makefile.am
  80. 5 0
      src/lib/util/unittests/README
  81. 145 0
      src/lib/util/unittests/fork.cc
  82. 52 0
      src/lib/util/unittests/fork.h
  83. 3 11
      src/lib/xfr/Makefile.am
  84. 0 42
      src/lib/xfr/fd_share.h
  85. 3 2
      src/lib/xfr/xfrout_client.cc
  86. 27 0
      tools/query_cmp/README
  87. 394 0
      tools/query_cmp/queries/dquery01
  88. 316 0
      tools/query_cmp/queries/dquery01_no-type
  89. 317 0
      tools/query_cmp/queries/dquery01_non-terminal
  90. 316 0
      tools/query_cmp/queries/dquery01_nxdomain
  91. 285 0
      tools/query_cmp/src/lib/compare_rrset.py
  92. 284 0
      tools/query_cmp/src/lib/handledns.py
  93. 93 0
      tools/query_cmp/src/lib/read_query.py
  94. 102 0
      tools/query_cmp/src/query_two_server.py
  95. 1298 0
      tools/query_cmp/zonefile/example.com.txt
  96. 6858 0
      tools/query_cmp/zonefile/example.com.txt.signed

File diff suppressed because it is too large
+ 267 - 240
ChangeLog


+ 7 - 0
configure.ac

@@ -624,6 +624,8 @@ AC_CONFIG_FILES([Makefile
                  src/bin/auth/benchmarks/Makefile
                  src/bin/resolver/Makefile
                  src/bin/resolver/tests/Makefile
+                 src/bin/sockcreator/Makefile
+                 src/bin/sockcreator/tests/Makefile
                  src/bin/xfrin/Makefile
                  src/bin/xfrin/tests/Makefile
                  src/bin/xfrout/Makefile
@@ -694,6 +696,10 @@ AC_CONFIG_FILES([Makefile
                  src/lib/server_common/tests/Makefile
                  tests/Makefile
                  tests/system/Makefile
+                 src/lib/util/Makefile
+                 src/lib/util/io/Makefile
+                 src/lib/util/io/tests/Makefile
+                 src/lib/util/unittests/Makefile
                ])
 AC_OUTPUT([doc/version.ent
            src/bin/cfgmgr/b10-cfgmgr.py
@@ -708,6 +714,7 @@ AC_OUTPUT([doc/version.ent
            src/bin/xfrout/xfrout.py
            src/bin/xfrout/xfrout.spec.pre
            src/bin/xfrout/tests/xfrout_test
+           src/bin/xfrout/tests/xfrout_test.py
            src/bin/xfrout/run_b10-xfrout.sh
            src/bin/resolver/resolver.spec.pre
            src/bin/resolver/spec_config.h.pre

+ 5 - 1
doc/Doxyfile

@@ -568,7 +568,11 @@ WARN_LOGFILE           =
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/bin/resolver ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas ../src/lib/testutils ../src/lib/cache ../src/lib/server_common/
+INPUT                  = ../src/lib/cc ../src/lib/config ../src/lib/dns \
+    ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth \
+    ../src/bin/resolver ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ \
+    ../src/lib/nsas ../src/lib/testutils ../src/lib/cache \
+    ../src/lib/server_common/ ../src/bin/sockcreator/ ../src/lib/util/
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

+ 1 - 1
src/bin/Makefile.am

@@ -1,4 +1,4 @@
 SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
-	usermgr zonemgr stats tests resolver
+	usermgr zonemgr stats tests resolver sockcreator
 
 check-recursive: all-recursive

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

@@ -41,7 +41,7 @@ b10_auth_SOURCES += auth_srv.cc auth_srv.h
 b10_auth_SOURCES += change_user.cc change_user.h
 b10_auth_SOURCES += auth_config.cc auth_config.h
 b10_auth_SOURCES += command.cc command.h
-b10_auth_SOURCES += common.h
+b10_auth_SOURCES += common.h common.cc
 b10_auth_SOURCES += statistics.cc statistics.h
 b10_auth_SOURCES += main.cc
 b10_auth_LDADD =  $(top_builddir)/src/lib/datasrc/libdatasrc.la

+ 36 - 0
src/bin/auth/common.cc

@@ -0,0 +1,36 @@
+// Copyright (C) 2009-2011  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.
+
+#include <auth/common.h>
+#include <auth/spec_config.h>
+#include <stdlib.h>
+
+using std::string;
+
+string getXfroutSocketPath() {
+    if (getenv("B10_FROM_BUILD") != NULL) {
+        if (getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) {
+            return (string(getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) +
+                    "/auth_xfrout_conn");
+        } else {
+            return (string(getenv("B10_FROM_BUILD")) + "/auth_xfrout_conn");
+        }
+    } else {
+        if (getenv("BIND10_XFROUT_SOCKET_FILE")) {
+            return (getenv("BIND10_XFROUT_SOCKET_FILE"));
+        } else {
+            return (UNIX_SOCKET_FILE);
+        }
+    }
+}

+ 10 - 1
src/bin/auth/common.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2011  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
@@ -29,6 +29,15 @@ public:
     {}
 };
 
+/// \short Get the path of socket to talk to xfrout
+///
+/// It takes some environment variables into account (B10_FROM_BUILD,
+/// B10_FROM_SOURCE_LOCALSTATEDIR and BIND10_XFROUT_SOCKET_FILE). It
+/// also considers the installation prefix.
+///
+/// The logic should be the same as in b10-xfrout, so they find each other.
+std::string getXfroutSocketPath();
+
 #endif // __COMMON_H
 
 // Local Variables:

+ 2 - 14
src/bin/auth/main.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2009-2011  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
@@ -124,19 +124,7 @@ main(int argc, char* argv[]) {
     bool xfrin_session_established = false; // XXX (see Trac #287)
     bool statistics_session_established = false; // XXX (see Trac #287)
     ModuleCCSession* config_session = NULL;
-    string xfrout_socket_path;
-    if (getenv("B10_FROM_BUILD") != NULL) {
-        if (getenv("B10_FROM_SOURCE_LOCALSTATEDIR")) {
-            xfrout_socket_path = string("B10_FROM_SOURCE_LOCALSTATEDIR") +
-                "/auth_xfrout_conn";
-        } else {
-            xfrout_socket_path = string(getenv("B10_FROM_BUILD")) +
-                "/auth_xfrout_conn";
-        }
-    } else {
-        xfrout_socket_path = UNIX_SOCKET_FILE;
-    }
-    XfroutClient xfrout_client(xfrout_socket_path);
+    XfroutClient xfrout_client(getXfroutSocketPath());
     try {
         string specfile;
         if (getenv("B10_FROM_BUILD")) {

+ 6 - 0
src/bin/auth/tests/Makefile.am

@@ -1,4 +1,5 @@
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/dns -I$(top_srcdir)/src/bin
 AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
 AM_CPPFLAGS += $(BOOST_INCLUDES)
@@ -16,6 +17,8 @@ CLEANFILES = *.gcno *.gcda
 
 TESTS =
 if HAVE_GTEST
+
+BUILT_SOURCES = ../spec_config.h
 TESTS += run_unittests
 run_unittests_SOURCES = $(top_srcdir)/src/lib/dns/tests/unittest_util.h
 run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
@@ -24,10 +27,13 @@ run_unittests_SOURCES += ../query.h ../query.cc
 run_unittests_SOURCES += ../change_user.h ../change_user.cc
 run_unittests_SOURCES += ../auth_config.h ../auth_config.cc
 run_unittests_SOURCES += ../command.h ../command.cc
+run_unittests_SOURCES += ../common.h ../common.cc
+run_unittests_SOURCES += ../spec_config.h
 run_unittests_SOURCES += ../statistics.h ../statistics.cc
 run_unittests_SOURCES += auth_srv_unittest.cc
 run_unittests_SOURCES += config_unittest.cc
 run_unittests_SOURCES += command_unittest.cc
+run_unittests_SOURCES += common_unittest.cc
 run_unittests_SOURCES += query_unittest.cc
 run_unittests_SOURCES += change_user_unittest.cc
 run_unittests_SOURCES += statistics_unittest.cc

+ 96 - 0
src/bin/auth/tests/common_unittest.cc

@@ -0,0 +1,96 @@
+// Copyright (C) 2011  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.
+
+#include <gtest/gtest.h>
+#include <auth/common.h>
+#include <auth/spec_config.h>
+#include <vector>
+#include <string>
+#include <cstdio>
+#include <boost/foreach.hpp>
+
+using std::pair;
+using std::vector;
+using std::string;
+
+namespace {
+
+class Paths : public ::testing::Test {
+private:
+    typedef pair<string, string*> Environ;
+    vector<Environ> restoreEnviron;
+public:
+    void TearDown() {
+        // Restore the original environment
+        BOOST_FOREACH(const Environ &env, restoreEnviron) {
+            if (env.second == NULL) {
+                EXPECT_EQ(0, unsetenv(env.first.c_str())) <<
+                    "Couldn't restore environment, results of other tests"
+                    "are uncertain";
+            } else {
+                EXPECT_EQ(0, setenv(env.first.c_str(), env.second->c_str(),
+                                    1)) << "Couldn't restore environment, "
+                    "results of other tests are uncertain";
+            }
+        }
+    }
+protected:
+    // Sets a temporary value into environment. If value is empty, it deletes
+    // the variable from environment (just for simplicity).
+    void setEnv(const string& name, const string& value) {
+        // Backup the original environment
+        char* env(getenv(name.c_str()));
+        restoreEnviron.push_back(Environ(name, env == NULL ? NULL :
+                                         new string(env)));
+        // Set the new value
+        if (value.empty()) {
+            EXPECT_EQ(0, unsetenv(name.c_str()));
+        } else {
+            EXPECT_EQ(0, setenv(name.c_str(), value.c_str(), 1));
+        }
+    }
+    // Test getXfroutSocketPath under given environment
+    void testXfrout(const string& fromBuild, const string& localStateDir,
+                    const string& socketFile, const string& expected)
+    {
+        setEnv("B10_FROM_BUILD", fromBuild);
+        setEnv("B10_FROM_SOURCE_LOCALSTATEDIR", localStateDir);
+        setEnv("BIND10_XFROUT_SOCKET_FILE", socketFile);
+        EXPECT_EQ(expected, getXfroutSocketPath());
+    }
+};
+
+// Test that when we have no special environment, we get the default from prefix
+TEST_F(Paths, xfroutNoEnv) {
+    testXfrout("", "", "", UNIX_SOCKET_FILE);
+}
+
+// Override by B10_FROM_BUILD
+TEST_F(Paths, xfroutFromBuild) {
+    testXfrout("/from/build", "", "/wrong/path",
+               "/from/build/auth_xfrout_conn");
+}
+
+// Override by B10_FROM_SOURCE_LOCALSTATEDIR
+TEST_F(Paths, xfroutLocalStatedir) {
+    testXfrout("/wrong/path", "/state/dir", "/wrong/path",
+               "/state/dir/auth_xfrout_conn");
+}
+
+// Override by BIND10_XFROUT_SOCKET_FILE explicitly
+TEST_F(Paths, xfroutFromEnv) {
+    testXfrout("", "", "/the/path/to/file", "/the/path/to/file");
+}
+
+}

File diff suppressed because it is too large
+ 38 - 11
src/bin/bind10/bind10.8


+ 51 - 8
src/bin/bind10/bind10.xml

@@ -20,7 +20,7 @@
 <refentry>
 
   <refentryinfo>
-    <date>February 22, 2011</date>
+    <date>March 31, 2011</date>
   </refentryinfo>
 
   <refmeta>
@@ -44,16 +44,21 @@
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>bind10</command>
+      <arg><option>-c <replaceable>config-filename</replaceable></option></arg>
       <arg><option>-m <replaceable>file</replaceable></option></arg>
       <arg><option>-n</option></arg>
+      <arg><option>-p <replaceable>data_path</replaceable></option></arg>
       <arg><option>-u <replaceable>user</replaceable></option></arg>
       <arg><option>-v</option></arg>
-      <arg><option>-c<replaceable>config-filename</replaceable></option></arg>
-      <arg><option>-p<replaceable>data_path</replaceable></option></arg>
+      <arg><option>--brittle</option></arg>
+      <arg><option>--cmdctl-port</option> <replaceable>port</replaceable></arg>
+      <arg><option>--config-file</option> <replaceable>config-filename</replaceable></arg>
+      <arg><option>--data-path</option> <replaceable>directory</replaceable></arg>
       <arg><option>--msgq-socket-file <replaceable>file</replaceable></option></arg>
       <arg><option>--no-cache</option></arg>
-      <arg><option>--user <replaceable>user</replaceable></option></arg>
+      <arg><option>--pid-file</option> <replaceable>filename</replaceable></arg>
       <arg><option>--pretty-name <replaceable>name</replaceable></option></arg>
+      <arg><option>--user <replaceable>user</replaceable></option></arg>
       <arg><option>--verbose</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
@@ -82,9 +87,24 @@
     <para>The arguments are as follows:</para>
 
     <variablelist>
+
+      <varlistentry>
+        <term>
+          <option>--brittle</option>
+        </term>
+        <listitem>
+          <para>
+	    Shutdown if any of the child processes of
+	    <command>bind10</command> exit.  This is intended to
+	    help developers debug the server, and should not be
+	    used in production.
+          </para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>
-          <option>-c</option><replaceable>config-filename</replaceable>,
+          <option>-c</option> <replaceable>config-filename</replaceable>,
           <option>--config-file</option> <replaceable>config-filename</replaceable>
         </term>
         <listitem>
@@ -97,8 +117,22 @@
 
       <varlistentry>
         <term>
-          <option>-p</option><replaceable>data-path</replaceable>,
-          <option>--data-path</option> <replaceable>data-path</replaceable>
+          <option>--cmdctl-port</option> <replaceable>port</replaceable>
+        </term>
+        <listitem>
+	  <para>The <command>b10-cmdctl</command> daemon will listen
+	    on this port.
+	    (See
+	    <refentrytitle>b10-cmdctl</refentrytitle><manvolnum>8</manvolnum>
+            for the default.)
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>-p</option> <replaceable>directory</replaceable>,
+          <option>--data-path</option> <replaceable>directory</replaceable>
         </term>
         <listitem>
           <para>The path where BIND 10 programs look for various data files.
@@ -134,7 +168,6 @@
 
       <varlistentry>
         <term><option>-u</option> <replaceable>user</replaceable>, <option>--user</option> <replaceable>name</replaceable></term>
-
         <listitem>
           <para>The username for <command>bind10</command> to run as.
 <!-- TODO: example more detail. -->
@@ -145,6 +178,16 @@
       </varlistentry>
 
       <varlistentry>
+        <term><option>--pid-file</option> <replaceable>filename</replaceable></term>
+        <listitem>
+          <para>If defined, the PID of the <command>bind10</command> is stored
+             in this file.
+             This is used for testing purposes.
+          </para>
+         </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><option>--pretty-name <replaceable>name</replaceable></option></term>
 
         <listitem>

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

@@ -1,5 +1,6 @@
 PYCOVERAGE_RUN = @PYCOVERAGE_RUN@
 #PYTESTS = args_test.py bind10_test.py
+# NOTE: this has a generated test found in the builddir
 PYTESTS = bind10_test.py
 EXTRA_DIST = $(PYTESTS)
 
@@ -14,5 +15,5 @@ endif
 	echo Running test: $$pytest ; \
 	env PYTHONPATH=$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/bin/bind10 \
 	BIND10_MSGQ_SOCKET_FILE=$(abs_top_builddir)/msgq_socket \
-		$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
+		$(PYCOVERAGE_RUN) $(abs_builddir)/$$pytest || exit ; \
 	done

+ 18 - 0
src/bin/sockcreator/Makefile.am

@@ -0,0 +1,18 @@
+SUBDIRS = tests
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+
+CLEANFILES = *.gcno *.gcda
+
+pkglibexec_PROGRAMS = b10-sockcreator
+
+b10_sockcreator_SOURCES = sockcreator.cc sockcreator.h main.cc
+b10_sockcreator_LDADD = $(top_builddir)/src/lib/util/io/libutil_io.la

+ 49 - 0
src/bin/sockcreator/README

@@ -0,0 +1,49 @@
+The socket creator
+==================
+
+The only thing we need higher rights than standard user is binding sockets to
+ports lower than 1024. So we will have a separate process that keeps the
+rights, while the rests drop them for security reasons.
+
+This process is the socket creator. Its goal is to be as simple as possible
+and to contain as little code as possible to minimise the amount of code
+running with higher privileges (to minimize the number of bugs and make
+checking/auditing it easier). It uses low-level OS API instead of some
+fancy library for that reason. It has only fixed-length reads so there's no
+place for buffer overruns.
+
+Protocol
+--------
+
+It talks with whoever started it by its stdin/stdout. It reads simple
+binary protocol from stdin and does what the commands ask. Command is a single
+byte (usually from the printable range, so it is easier to debug and guess
+what it does), followed by parameters.
+
+Note that as send_fd and recv_fd works only with unix domain socket, it's stdio
+must be a socket, not pipe.
+
+* 'T': It has no parameters. It asks the socket creator to terminate.
+
+* 'S' 'U|T' '4|6' port address: Asks it to create a port. First parameter
+  tels the socket type (either UDP or TCP). The second one is address family
+  (either IPv4 or IPv6). Then there's 2 bytes of the port number, in the
+  network byte order. The last one is either 4 or 16 bytes of address, as
+  they would be passed to bind (note that both parameters are already prepared,
+  like hton called on them).
+
+  The answer to this is either 'S' directly followed by the socket (using
+  sendmsg) if it is successful. If it fails, 'E' is returned instead, followed
+  by either 'S' or 'B' (either socket() or bind() call failed). Then there is
+  one int (architecture-dependent length and endianess), which is the errno
+  value after the failure.
+
+The creator may also send these messages at any time (but not in the middle
+of another message):
+
+* 'F': A fatal error has been detected. It is followed by one byte of error
+  condition code and then the creator terminates with non-zero status.
+
+  The conditions are:
+  * 'I': Invalid input (eg. someone sent a wrong letter and it does not
+    understand it).

+ 10 - 16
src/lib/xfr/python_xfr.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011  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
@@ -12,21 +12,15 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <boost/python.hpp>
-#include <boost/python/class.hpp>
-#include <boost/python/module.hpp>
-#include <boost/python/def.hpp>
-#include <boost/python/exception_translator.hpp>
-#include <boost/python/return_internal_reference.hpp>
-#include <boost/python/copy_const_reference.hpp>
-#include <boost/shared_ptr.hpp>
+#include "sockcreator.h"
 
-#include <xfr/fd_share.h>
+using namespace isc::socket_creator;
 
-using namespace isc::xfr;
-using namespace boost::python;
-
-BOOST_PYTHON_MODULE(bind10_xfr) {
-    def("recv_fd", &recv_fd);
-    def("send_fd", &send_fd);
+int
+main() {
+    /*
+     * TODO Maybe use some OS-specific caps interface and drop everything
+     * but ability to bind ports? It would be nice.
+     */
+    return run(0, 1); // Read commands from stdin, output to stdout
 }

+ 151 - 0
src/bin/sockcreator/sockcreator.cc

@@ -0,0 +1,151 @@
+// Copyright (C) 2011  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.
+
+#include "sockcreator.h"
+
+#include <util/io/fd.h>
+
+#include <unistd.h>
+#include <cerrno>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+using namespace isc::util::io;
+
+namespace isc {
+namespace socket_creator {
+
+int
+get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len)
+{
+    int sock(socket(bind_addr->sa_family, type, 0));
+    if (sock == -1) {
+        return -1;
+    }
+    if (bind(sock, bind_addr, addr_len) == -1) {
+        return -2;
+    }
+    return sock;
+}
+
+// These are macros so they can exit the function
+#define READ(WHERE, HOW_MANY) do { \
+        size_t how_many = (HOW_MANY); \
+        if (read_data(input_fd, (WHERE), how_many) < how_many) { \
+            return 1; \
+        } \
+    } while (0)
+
+#define WRITE(WHAT, HOW_MANY) do { \
+        if (!write_data(output_fd, (WHAT), (HOW_MANY))) { \
+            return 2; \
+        } \
+    } while (0)
+
+#define DEFAULT \
+    default: /* Unrecognized part of protocol */ \
+        WRITE("FI", 2); \
+        return 3;
+
+int
+run(const int input_fd, const int output_fd, const get_sock_t get_sock,
+    const send_fd_t send_fd)
+{
+    for (;;) {
+        // Read the command
+        char command;
+        READ(&command, 1);
+        switch (command) {
+            case 'T': // The "terminate" command
+                return 0;
+            case 'S': { // Create a socket
+                // Read what type of socket they want
+                char type[2];
+                READ(type, 2);
+                // Read the address they ask for
+                struct sockaddr *addr(NULL);
+                size_t addr_len(0);
+                struct sockaddr_in addr_in;
+                struct sockaddr_in6 addr_in6;
+                switch (type[1]) { // The address family
+                    /*
+                     * Here are some casts. They are required by C++ and
+                     * the low-level interface (they are implicit in C).
+                     */
+                    case '4':
+                        addr = static_cast<struct sockaddr *>(
+                            static_cast<void *>(&addr_in));
+                        addr_len = sizeof addr_in;
+                        memset(&addr_in, 0, sizeof addr_in);
+                        addr_in.sin_family = AF_INET;
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in.sin_port)), 2);
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in.sin_addr.s_addr)), 4);
+                        break;
+                    case '6':
+                        addr = static_cast<struct sockaddr *>(
+                            static_cast<void *>(&addr_in6));
+                        addr_len = sizeof addr_in6;
+                        memset(&addr_in6, 0, sizeof addr_in6);
+                        addr_in6.sin6_family = AF_INET6;
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in6.sin6_port)), 2);
+                        READ(static_cast<char *>(static_cast<void *>(
+                            &addr_in6.sin6_addr.s6_addr)), 16);
+                        break;
+                    DEFAULT
+                }
+                int sock_type;
+                switch (type[0]) { // Translate the type
+                    case 'T':
+                        sock_type = SOCK_STREAM;
+                        break;
+                    case 'U':
+                        sock_type = SOCK_DGRAM;
+                        break;
+                    DEFAULT
+                }
+                int result(get_sock(sock_type, addr, addr_len));
+                if (result >= 0) { // We got the socket
+                    WRITE("S", 1);
+                    // FIXME: Check the output and write a test for it
+                    send_fd(output_fd, result);
+                } else {
+                    WRITE("E", 1);
+                    switch (result) {
+                        case -1:
+                            WRITE("S", 1);
+                            break;
+                        case -2:
+                            WRITE("B", 1);
+                            break;
+                        default:
+                            return 4;
+                    }
+                    int error(errno);
+                    WRITE(static_cast<char *>(static_cast<void *>(&error)),
+                        sizeof error);
+                }
+                break;
+            }
+            DEFAULT
+        }
+    }
+}
+
+} // End of the namespaces
+}

+ 100 - 0
src/bin/sockcreator/sockcreator.h

@@ -0,0 +1,100 @@
+// Copyright (C) 2011  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.
+
+/**
+ * \file sockcreator.h
+ * \short Socket creator functionality.
+ *
+ * This module holds the functionality of the socket creator. It is
+ * a separate module from main to ease up the tests.
+ */
+
+#ifndef __SOCKCREATOR_H
+#define __SOCKCREATOR_H 1
+
+#include <util/io/fd_share.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+namespace isc {
+namespace socket_creator {
+
+/**
+ * \short Create a socket and bind it.
+ *
+ * This is just a bundle of socket() and bind() calls. The sa_family of
+ * bind_addr is used to determine the domain of the socket.
+ *
+ * \return The file descriptor of the newly created socket, if everything
+ *     goes well. A negative number is returned if an error occurs -
+ *     -1 if the socket() call fails or -2 if bind() fails. In case of error,
+ *     errno is set (or better, left intact from socket() or bind()).
+ * \param type The type of socket to create (SOCK_STREAM, SOCK_DGRAM, etc).
+ * \param bind_addr The address to bind.
+ * \param addr_len The actual length of bind_addr.
+ */
+int
+get_sock(const int type, struct sockaddr *bind_addr, const socklen_t addr_len);
+
+/**
+ * Type of the get_sock function, to pass it as parameter.
+ */
+typedef
+int
+(*get_sock_t)(const int, struct sockaddr *, const socklen_t);
+
+/**
+ * Type of the send_fd() function, so it can be passed as a parameter.
+ */
+typedef
+int
+(*send_fd_t)(const int, const int);
+
+/**
+ * \short Infinite loop parsing commands and returning the sockets.
+ *
+ * This reads commands and socket descriptions from the input_fd
+ * file descriptor, creates sockets and writes the results (socket or
+ * error) to output_fd.
+ *
+ * Current errors are:
+ * - 1: Read error
+ * - 2: Write error
+ * - 3: Protocol error (unknown command, etc)
+ * - 4: Some internal inconsistency detected
+ *
+ * It terminates either if a command asks it to or when unrecoverable
+ * error happens.
+ *
+ * \return Like a return value of a main - 0 means everything OK, anything
+ *     else is error.
+ * \param input_fd Here is where it reads the commads.
+ * \param output_fd Here is where it writes the results.
+ * \param get_sock_fun The function that is used to create the sockets.
+ *     This should be left on the default value, the parameter is here
+ *     for testing purposes.
+ * \param send_fd_fun The function that is used to send the socket over
+ *     a file descriptor. This should be left on the default value, it is
+ *     here for testing purposes.
+ */
+int
+run(const int input_fd, const int output_fd,
+    const get_sock_t get_sock_fun = get_sock,
+    const send_fd_t send_fd_fun = isc::util::io::send_fd);
+
+} // End of the namespaces
+}
+
+#endif // __SOCKCREATOR_H

+ 25 - 0
src/bin/sockcreator/tests/Makefile.am

@@ -0,0 +1,25 @@
+CLEANFILES = *.gcno *.gcda
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = ../sockcreator.cc ../sockcreator.h
+run_unittests_SOURCES += sockcreator_tests.cc
+run_unittests_SOURCES += run_unittests.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libutil_io.la
+run_unittests_LDADD += \
+	$(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+endif
+
+noinst_PROGRAMS = $(TESTS)

+ 22 - 0
src/bin/sockcreator/tests/run_unittests.cc

@@ -0,0 +1,22 @@
+// Copyright (C) 2011  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.
+
+#include <gtest/gtest.h>
+
+int
+main(int argc, char *argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+
+    return RUN_ALL_TESTS();
+}

+ 273 - 0
src/bin/sockcreator/tests/sockcreator_tests.cc

@@ -0,0 +1,273 @@
+// Copyright (C) 2011  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.
+
+#include "../sockcreator.h"
+
+#include <util/unittests/fork.h>
+#include <util/io/fd.h>
+
+#include <gtest/gtest.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <cstring>
+#include <cerrno>
+
+using namespace isc::socket_creator;
+using namespace isc::util::unittests;
+using namespace isc::util::io;
+
+namespace {
+
+/*
+ * Generic version of the creation of socket test. It just tries to
+ * create the socket and checks the result is not negative (eg.
+ * it is valid descriptor) and that it can listen.
+ *
+ * This is a macro so ASSERT_* does abort the TEST, not just the
+ * function inside.
+ */
+#define TEST_ANY_CREATE(SOCK_TYPE, ADDR_TYPE, ADDR_FAMILY, FAMILY_FIELD, \
+    ADDR_SET, CHECK_SOCK) \
+    do { \
+        /*
+         * This should create an address that binds on all interfaces
+         * and lets the OS choose a free port.
+         */ \
+        struct ADDR_TYPE addr; \
+        memset(&addr, 0, sizeof addr); \
+        ADDR_SET(addr); \
+        addr.FAMILY_FIELD = ADDR_FAMILY; \
+        struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
+            static_cast<void *>(&addr)); \
+        \
+        int socket = get_sock(SOCK_TYPE, addr_ptr, sizeof addr); \
+        /* Provide even nice error message. */ \
+        ASSERT_GE(socket, 0) << "Couldn't create a socket of type " \
+            #SOCK_TYPE " and family " #ADDR_FAMILY ", failed with " \
+            << socket << " and error " << strerror(errno); \
+        CHECK_SOCK(ADDR_TYPE, socket); \
+        EXPECT_EQ(0, close(socket)); \
+    } while (0)
+
+// Just helper macros
+#define INADDR_SET(WHAT) do { WHAT.sin_addr.s_addr = INADDR_ANY; } while (0)
+#define IN6ADDR_SET(WHAT) do { WHAT.sin6_addr = in6addr_loopback; } while (0)
+// If the get_sock returned something useful, listen must work
+#define TCP_CHECK(UNUSED, SOCKET) do { \
+        EXPECT_EQ(0, listen(SOCKET, 1)); \
+    } while (0)
+// More complicated with UDP, so we send a packet to ourselfs and se if it
+// arrives
+#define UDP_CHECK(ADDR_TYPE, SOCKET) do { \
+        struct ADDR_TYPE addr; \
+        memset(&addr, 0, sizeof addr); \
+        struct sockaddr *addr_ptr = static_cast<struct sockaddr *>( \
+            static_cast<void *>(&addr)); \
+        \
+        socklen_t len = sizeof addr; \
+        ASSERT_EQ(0, getsockname(SOCKET, addr_ptr, &len)); \
+        ASSERT_EQ(5, sendto(SOCKET, "test", 5, 0, addr_ptr, sizeof addr)) << \
+            "Send failed with error " << strerror(errno) << " on socket " << \
+            SOCKET; \
+        char buffer[5]; \
+        ASSERT_EQ(5, recv(SOCKET, buffer, 5, 0)) << \
+            "Recv failed with error " << strerror(errno) << " on socket " << \
+            SOCKET; \
+        EXPECT_STREQ("test", buffer); \
+    } while (0)
+
+/*
+ * Several tests to ensure we can create the sockets.
+ */
+TEST(get_sock, udp4_create) {
+    TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in, AF_INET, sin_family, INADDR_SET,
+        UDP_CHECK);
+}
+
+TEST(get_sock, tcp4_create) {
+    TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in, AF_INET, sin_family, INADDR_SET,
+        TCP_CHECK);
+}
+
+TEST(get_sock, udp6_create) {
+    TEST_ANY_CREATE(SOCK_DGRAM, sockaddr_in6, AF_INET6, sin6_family,
+        IN6ADDR_SET, UDP_CHECK);
+}
+
+TEST(get_sock, tcp6_create) {
+    TEST_ANY_CREATE(SOCK_STREAM, sockaddr_in6, AF_INET6, sin6_family,
+        IN6ADDR_SET, TCP_CHECK);
+}
+
+/*
+ * Try to ask the get_sock function some nonsense and test if it
+ * is able to report error.
+ */
+TEST(get_sock, fail_with_nonsense) {
+    struct sockaddr addr;
+    memset(&addr, 0, sizeof addr);
+    ASSERT_LT(get_sock(0, &addr, sizeof addr), 0);
+}
+
+/*
+ * Helper functions to pass to run during testing.
+ */
+int
+get_sock_dummy(const int type, struct sockaddr *addr, const socklen_t)
+{
+    int result(0);
+    int port(0);
+    /*
+     * We encode the type and address family into the int and return it.
+     * Lets ignore the port and address for now
+     * First bit is 1 if it is known type. Second tells if TCP or UDP.
+     * The familly is similar - third bit is known address family,
+     * the fourth is the family.
+     */
+    switch (type) {
+        case SOCK_STREAM:
+            result += 1;
+            break;
+        case SOCK_DGRAM:
+            result += 3;
+            break;
+    }
+    switch (addr->sa_family) {
+        case AF_INET:
+            result += 4;
+            port = static_cast<struct sockaddr_in *>(
+                static_cast<void *>(addr))->sin_port;
+            break;
+        case AF_INET6:
+            result += 12;
+            port = static_cast<struct sockaddr_in6 *>(
+                static_cast<void *>(addr))->sin6_port;
+            break;
+    }
+    /*
+     * The port should be 0xffff. If it's not, we change the result.
+     * The port of 0xbbbb means bind should fail and 0xcccc means
+     * socket should fail.
+     */
+    if (port != 0xffff) {
+        errno = 0;
+        if (port == 0xbbbb) {
+            return -2;
+        } else if (port == 0xcccc) {
+            return -1;
+        } else {
+            result += 16;
+        }
+    }
+    return result;
+}
+
+int
+send_fd_dummy(const int destination, const int what)
+{
+    /*
+     * Make sure it is 1 byte so we know the length. We do not use more during
+     * the test anyway.
+     */
+    char fd_data(what);
+    if (!write_data(destination, &fd_data, 1)) {
+        return -1;
+    } else {
+        return 0;
+    }
+}
+
+/*
+ * Generic test that it works, with various inputs and outputs.
+ * It uses different functions to create the socket and send it and pass
+ * data to it and check it returns correct data back, to see if the run()
+ * parses the commands correctly.
+ */
+void run_test(const char *input_data, const size_t input_size,
+    const char *output_data, const size_t output_size,
+    bool should_succeed = true)
+{
+    // Prepare the input feeder and output checker processes
+    int input_fd(0), output_fd(0);
+    pid_t input(provide_input(&input_fd, input_data, input_size)),
+        output(check_output(&output_fd, output_data, output_size));
+    ASSERT_NE(-1, input) << "Couldn't start input feeder";
+    ASSERT_NE(-1, output) << "Couldn't start output checker";
+    // Run the body
+    int result(run(input_fd, output_fd, get_sock_dummy, send_fd_dummy));
+    // Close the pipes
+    close(input_fd);
+    close(output_fd);
+    // Did it run well?
+    if (should_succeed) {
+        EXPECT_EQ(0, result);
+    } else {
+        EXPECT_NE(0, result);
+    }
+    // Check the subprocesses say everything is OK too
+    EXPECT_TRUE(process_ok(input));
+    EXPECT_TRUE(process_ok(output));
+}
+
+/*
+ * Check it terminates successfully when asked to.
+ */
+TEST(run, terminate) {
+    run_test("T", 1, NULL, 0);
+}
+
+/*
+ * Check it rejects incorrect input.
+ */
+TEST(run, bad_input) {
+    run_test("XXX", 3, "FI", 2, false);
+}
+
+/*
+ * Check it correctly parses queries to create sockets.
+ */
+TEST(run, sockets) {
+    run_test(
+        "SU4\xff\xff\0\0\0\0" // This has 9 bytes
+        "ST4\xff\xff\0\0\0\0" // This has 9 bytes
+        "ST6\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" // This has 21 bytes
+        "SU6\xff\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" // This has 21 bytes
+        "T", 61,
+        "S\x07S\x05S\x0dS\x0f", 8);
+}
+
+/*
+ * Check if failures of get_socket are handled correctly.
+ */
+TEST(run, bad_sockets) {
+    // We need to construct the answer, but it depends on int length.
+    size_t int_len(sizeof(int));
+    size_t result_len(4 + 2 * int_len);
+    char result[4 + sizeof(int) * 2];
+    // Both errno parts should be 0
+    memset(result, 0, result_len);
+    // Fill the 2 control parts
+    strcpy(result, "EB");
+    strcpy(result + 2 + int_len, "ES");
+    // Run the test
+    run_test(
+        "SU4\xbb\xbb\0\0\0\0"
+        "SU4\xcc\xcc\0\0\0\0"
+        "T", 19,
+        result, result_len);
+}
+
+}

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

@@ -6,7 +6,7 @@ EXTRA_DIST = $(PYTESTS)
 # required by loadable python modules.
 LIBRARY_PATH_PLACEHOLDER =
 if SET_ENV_LIBRARY_PATH
-LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/xfr/.libs:$$$(ENV_LIBRARY_PATH)
+LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/util/io/.libs:$$$(ENV_LIBRARY_PATH)
 endif
 
 # test using command-line arguments, so use check-local target instead of TESTS
@@ -18,7 +18,7 @@ if ENABLE_PYTHON_COVERAGE
 endif
 	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/python:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
+	env PYTHONPATH=$(abs_top_builddir)/src/bin/xfrout:$(abs_top_srcdir)/src/lib/python:$(abs_top_builddir)/src/lib/python:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/util/io/.libs \
 	$(LIBRARY_PATH_PLACEHOLDER) \
 	$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
 	done

+ 32 - 0
src/bin/xfrout/tests/xfrout_test.py

@@ -21,6 +21,7 @@ import os
 from isc.cc.session import *
 from pydnspp import *
 from xfrout import *
+import xfrout
 
 # our fake socket, where we can read and insert messages
 class MySocket():
@@ -433,5 +434,36 @@ class TestUnixSockServer(unittest.TestCase):
         sys.stdout = old_stdout
         os.rmdir(dir_name)
 
+class TestInitialization(unittest.TestCase):
+    def setEnv(self, name, value):
+        if value is None:
+            if name in os.environ:
+                del os.environ[name]
+        else:
+            os.environ[name] = value
+
+    def setUp(self):
+        self._oldSocket = os.getenv("BIND10_XFROUT_SOCKET_FILE")
+        self._oldFromBuild = os.getenv("B10_FROM_BUILD")
+
+    def tearDown(self):
+        self.setEnv("B10_FROM_BUILD", self._oldFromBuild)
+        self.setEnv("BIND10_XFROUT_SOCKET_FILE", self._oldSocket)
+        # Make sure even the computed values are back
+        xfrout.init_paths()
+
+    def testNoEnv(self):
+        self.setEnv("B10_FROM_BUILD", None)
+        self.setEnv("BIND10_XFROUT_SOCKET_FILE", None)
+        xfrout.init_paths()
+        self.assertEqual(xfrout.UNIX_SOCKET_FILE,
+                         "@@LOCALSTATEDIR@@/auth_xfrout_conn")
+
+    def testProvidedSocket(self):
+        self.setEnv("B10_FROM_BUILD", None)
+        self.setEnv("BIND10_XFROUT_SOCKET_FILE", "The/Socket/File")
+        xfrout.init_paths()
+        self.assertEqual(xfrout.UNIX_SOCKET_FILE, "The/Socket/File")
+
 if __name__== "__main__":
     unittest.main()

+ 25 - 16
src/bin/xfrout/xfrout.py.in

@@ -37,29 +37,38 @@ from optparse import OptionParser, OptionValueError
 from isc.util import socketserver_mixin
 
 try:
-    from libxfr_python import *
+    from libutil_io_python import *
     from pydnspp import *
 except ImportError as e:
     # C++ loadable module may not be installed; even so the xfrout process
     # must keep running, so we warn about it and move forward.
-    sys.stderr.write('[b10-xfrout] failed to import DNS or XFR module: %s\n' % str(e))
+    sys.stderr.write('[b10-xfrout] failed to import DNS or isc.util.io module: %s\n' % str(e))
 
 isc.util.process.rename()
 
-if "B10_FROM_BUILD" in os.environ:
-    SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
-    AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
-    if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ:
-        UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"] + \
-            "/auth_xfrout_conn"
+def init_paths():
+    global SPECFILE_PATH
+    global AUTH_SPECFILE_PATH
+    global UNIX_SOCKET_FILE
+    if "B10_FROM_BUILD" in os.environ:
+        SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/xfrout"
+        AUTH_SPECFILE_PATH = os.environ["B10_FROM_BUILD"] + "/src/bin/auth"
+        if "B10_FROM_SOURCE_LOCALSTATEDIR" in os.environ:
+            UNIX_SOCKET_FILE = os.environ["B10_FROM_SOURCE_LOCALSTATEDIR"] + \
+                "/auth_xfrout_conn"
+        else:
+            UNIX_SOCKET_FILE = os.environ["B10_FROM_BUILD"] + "/auth_xfrout_conn"
     else:
-        UNIX_SOCKET_FILE = os.environ["B10_FROM_BUILD"] + "/auth_xfrout_conn"
-else:
-    PREFIX = "@prefix@"
-    DATAROOTDIR = "@datarootdir@"
-    SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
-    AUTH_SPECFILE_PATH = SPECFILE_PATH
-    UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_xfrout_conn"
+        PREFIX = "@prefix@"
+        DATAROOTDIR = "@datarootdir@"
+        SPECFILE_PATH = "@datadir@/@PACKAGE@".replace("${datarootdir}", DATAROOTDIR).replace("${prefix}", PREFIX)
+        AUTH_SPECFILE_PATH = SPECFILE_PATH
+        if "BIND10_XFROUT_SOCKET_FILE" in os.environ:
+            UNIX_SOCKET_FILE = os.environ["BIND10_XFROUT_SOCKET_FILE"]
+        else:
+            UNIX_SOCKET_FILE = "@@LOCALSTATEDIR@@/auth_xfrout_conn"
+
+init_paths()
 
 SPECFILE_LOCATION = SPECFILE_PATH + "/xfrout.spec"
 AUTH_SPECFILE_LOCATION = AUTH_SPECFILE_PATH + os.sep + "auth.spec"
@@ -376,7 +385,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn, ThreadingUnixStreamServer):
             # This may happen when one xfrout process try to connect to
             # xfrout unix socket server, to check whether there is another
             # xfrout running.
-            if sock_fd == XFR_FD_RECEIVE_FAIL:
+            if sock_fd == FD_COMM_ERROR:
                 self._log.log_message("error", "Failed to receive the file descriptor for XFR connection")
             return
 

+ 1 - 1
src/lib/Makefile.am

@@ -1,2 +1,2 @@
-SUBDIRS = exceptions dns cc config python xfr bench log asiolink \
+SUBDIRS = exceptions dns cc config util python xfr bench log asiolink \
           asiodns nsas cache resolve testutils datasrc server_common

+ 1 - 1
src/lib/datasrc/tests/rbtree_unittest.cc

@@ -398,7 +398,7 @@ TEST_F(RBTreeTest, getLastComparedNode) {
     EXPECT_EQ(static_cast<void*>(NULL), chain.getLastComparedNode());
     chain.clear();
 
-    const RBNode<int>* expected_node;
+    const RBNode<int>* expected_node = NULL;
 
     // Exact match case.  The returned node should be last compared.
     EXPECT_EQ(RBTree<int>::EXACTMATCH,

+ 105 - 27
src/lib/dns/buffer.h

@@ -15,6 +15,8 @@
 #ifndef __BUFFER_H
 #define __BUFFER_H 1
 
+#include <stdlib.h>
+#include <cstring>
 #include <vector>
 
 #include <string.h>
@@ -286,15 +288,58 @@ public:
     /// \brief Constructor from the initial size of the buffer.
     ///
     /// \param len The initial length of the buffer in bytes.
-    OutputBuffer(size_t len) { data_.reserve(len); }
+    OutputBuffer(size_t len) :
+        buffer_(NULL),
+        size_(0),
+        allocated_(len)
+    {
+        // We use malloc and free instead of C++ new[] and delete[].
+        // This way we can use realloc, which may in fact do it without a copy.
+        buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+        if (buffer_ == NULL && len != 0) {
+            throw std::bad_alloc();
+        }
+    }
+
+    /// \brief Copy constructor
+    OutputBuffer(const OutputBuffer& other) :
+        buffer_(NULL),
+        size_(other.size_),
+        allocated_(other.allocated_)
+    {
+        buffer_ = static_cast<uint8_t*>(malloc(allocated_));
+        if (buffer_ == NULL && allocated_ != 0) {
+            throw std::bad_alloc();
+        }
+        memcpy(buffer_, other.buffer_, size_);
+    }
+
+    /// \brief Destructor
+    ~ OutputBuffer() {
+        free(buffer_);
+    }
     //@}
 
+    /// \brief Assignment operator
+    OutputBuffer& operator =(const OutputBuffer& other) {
+        uint8_t* newbuff(static_cast<uint8_t*>(malloc(other.allocated_)));
+        if (newbuff == NULL && other.allocated_ != 0) {
+            throw std::bad_alloc();
+        }
+        free(buffer_);
+        buffer_ = newbuff;
+        size_ = other.size_;
+        allocated_ = other.allocated_;
+        memcpy(buffer_, other.buffer_, size_);
+        return (*this);
+    }
+
     ///
     /// \name Getter Methods
     ///
     //@{
     /// \brief Return the current capacity of the buffer.
-    size_t getCapacity() const { return (data_.capacity()); }
+    size_t getCapacity() const { return (allocated_); }
     /// \brief Return a pointer to the head of the data stored in the buffer.
     ///
     /// The caller can assume that the subsequent \c getLength() bytes are
@@ -302,21 +347,21 @@ public:
     ///
     /// Note: The pointer returned by this method may be invalidated after a
     /// subsequent write operation.
-    const void* getData() const { return (&data_[0]); }
+    const void* getData() const { return (buffer_); }
     /// \brief Return the length of data written in the buffer.
-    size_t getLength() const { return (data_.size()); }
+    size_t getLength() const { return (size_); }
     /// \brief Return the value of the buffer at the specified position.
     ///
     /// \c pos must specify the valid position of the buffer; otherwise an
     /// exception class of \c InvalidBufferPosition will be thrown.
     ///
     /// \param pos The position in the buffer to be returned.
-    const uint8_t& operator[](size_t pos) const
+    uint8_t operator[](size_t pos) const
     {
-        if (pos >= data_.size()) {
+        if (pos >= size_) {
             isc_throw(InvalidBufferPosition, "read at invalid position");
         }
-        return (data_[pos]);
+        return (buffer_[pos]);
     }
     //@}
 
@@ -330,7 +375,10 @@ public:
     /// This method is provided as a shortcut to make a hole in the buffer
     /// that is to be filled in later, e.g, by \ref writeUint16At().
     /// \param len The length of the gap to be inserted in bytes.
-    void skip(size_t len) { data_.insert(data_.end(), len, 0); }
+    void skip(size_t len) {
+        ensureAllocated(size_ + len);
+        size_ += len;
+    }
 
     /// \brief Trim the specified length of data from the end of the buffer.
     ///
@@ -341,20 +389,23 @@ public:
     /// \param len The length of data that should be trimmed.
     void trim(size_t len)
     {
-        if (len > data_.size()) {
+        if (len > size_) {
             isc_throw(OutOfRange, "trimming too large from output buffer");
         }
-        data_.resize(data_.size() - len);
+        size_ -= len;
     }
     /// \brief Clear buffer content.
     ///
     /// This method can be used to re-initialize and reuse the buffer without
     /// constructing a new one.
-    void clear() { data_.clear(); }
+    void clear() { size_ = 0; }
     /// \brief Write an unsigned 8-bit integer into the buffer.
     ///
     /// \param data The 8-bit integer to be written into the buffer.
-    void writeUint8(uint8_t data) { data_.push_back(data); }
+    void writeUint8(uint8_t data) {
+        ensureAllocated(size_ + 1);
+        buffer_[size_ ++] = data;
+    }
 
     /// \brief Write an unsigned 8-bit integer into the buffer.
     ///
@@ -365,10 +416,10 @@ public:
     /// \param data The 8-bit integer to be written into the buffer.
     /// \param pos The position in the buffer to write the data.
     void writeUint8At(uint8_t data, size_t pos) {
-        if (pos + sizeof(data) > data_.size()) {
+        if (pos + sizeof(data) > size_) {
             isc_throw(InvalidBufferPosition, "write at invalid position");
         }
-        data_[pos] = data;
+        buffer_[pos] = data;
     }
 
     /// \brief Write an unsigned 16-bit integer in host byte order into the
@@ -377,8 +428,9 @@ public:
     /// \param data The 16-bit integer to be written into the buffer.
     void writeUint16(uint16_t data)
     {
-        data_.push_back(static_cast<uint8_t>((data & 0xff00U) >> 8));
-        data_.push_back(static_cast<uint8_t>(data & 0x00ffU));
+        ensureAllocated(size_ + sizeof(data));
+        buffer_[size_ ++] = static_cast<uint8_t>((data & 0xff00U) >> 8);
+        buffer_[size_ ++] = static_cast<uint8_t>(data & 0x00ffU);
     }
     /// \brief Write an unsigned 16-bit integer in host byte order at the
     /// specified position of the buffer in network byte order.
@@ -393,12 +445,12 @@ public:
     /// \param pos The beginning position in the buffer to write the data.
     void writeUint16At(uint16_t data, size_t pos)
     {
-        if (pos + sizeof(data) > data_.size()) {
+        if (pos + sizeof(data) > size_) {
             isc_throw(InvalidBufferPosition, "write at invalid position");
         }
 
-        data_[pos] = static_cast<uint8_t>((data & 0xff00U) >> 8);
-        data_[pos + 1] = static_cast<uint8_t>(data & 0x00ffU);
+        buffer_[pos] = static_cast<uint8_t>((data & 0xff00U) >> 8);
+        buffer_[pos + 1] = static_cast<uint8_t>(data & 0x00ffU);
     }
     /// \brief Write an unsigned 32-bit integer in host byte order
     /// into the buffer in network byte order.
@@ -406,10 +458,11 @@ public:
     /// \param data The 32-bit integer to be written into the buffer.
     void writeUint32(uint32_t data)
     {
-        data_.push_back(static_cast<uint8_t>((data & 0xff000000) >> 24));
-        data_.push_back(static_cast<uint8_t>((data & 0x00ff0000) >> 16));
-        data_.push_back(static_cast<uint8_t>((data & 0x0000ff00) >> 8));
-        data_.push_back(static_cast<uint8_t>(data & 0x000000ff));
+        ensureAllocated(size_ + sizeof(data));
+        buffer_[size_ ++] = static_cast<uint8_t>((data & 0xff000000) >> 24);
+        buffer_[size_ ++] = static_cast<uint8_t>((data & 0x00ff0000) >> 16);
+        buffer_[size_ ++] = static_cast<uint8_t>((data & 0x0000ff00) >> 8);
+        buffer_[size_ ++] = static_cast<uint8_t>(data & 0x000000ff);
     }
     /// \brief Copy an arbitrary length of data into the buffer.
     ///
@@ -419,13 +472,38 @@ public:
     /// \param len The length of the data in bytes.
     void writeData(const void *data, size_t len)
     {
-        const uint8_t* cp = static_cast<const uint8_t*>(data);
-        data_.insert(data_.end(), cp, cp + len);
+        ensureAllocated(size_ + len);
+        memcpy(buffer_ + size_, data, len);
+        size_ += len;
     }
     //@}
-    
+
 private:
-    std::vector<uint8_t> data_;
+    // The actual data
+    uint8_t* buffer_;
+    // How many bytes are used
+    size_t size_;
+    // How many bytes do we have preallocated (eg. the capacity)
+    size_t allocated_;
+    // Make sure at last needed_size bytes are allocated in the buffer
+    void ensureAllocated(size_t needed_size) {
+        if (allocated_ < needed_size) {
+            // Guess some bigger size
+            size_t new_size = (allocated_ == 0) ? 1024 : allocated_;
+            while (new_size < needed_size) {
+                new_size *= 2;
+            }
+            // Allocate bigger space
+            uint8_t* new_buffer_(static_cast<uint8_t*>(realloc(buffer_,
+                new_size)));
+            if (new_buffer_ == NULL) {
+                // If it fails, the original block is left intact by it
+                throw std::bad_alloc();
+            }
+            buffer_ = new_buffer_;
+            allocated_ = new_size;
+        }
+    }
 };
 
 /// \brief Pointer-like types pointing to \c InputBuffer or \c OutputBuffer

+ 7 - 4
src/lib/dns/python/edns_python.cc

@@ -297,12 +297,15 @@ EDNS_getUDPSize(const s_EDNS* const self) {
 
 PyObject*
 EDNS_setUDPSize(s_EDNS* self, PyObject* args) {
-    unsigned int size;
-    if (!PyArg_ParseTuple(args, "I", &size)) {
+    long size;
+    if (!PyArg_ParseTuple(args, "l", &size)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "No valid type in set_udp_size argument");
         return (NULL);
     }
-    if (size > 65535) {
-        PyErr_SetString(PyExc_OverflowError,
+    if (size < 0 || size > 0xffff) {
+        PyErr_SetString(PyExc_ValueError,
                         "UDP size is not an unsigned 16-bit integer");
         return (NULL);
     }

+ 22 - 13
src/lib/dns/python/message_python.cc

@@ -226,9 +226,9 @@ static PyTypeObject message_type = {
 
 static int
 Message_init(s_Message* self, PyObject* args) {
-    unsigned int i;
-    
-    if (PyArg_ParseTuple(args, "I", &i)) {
+    int i;
+
+    if (PyArg_ParseTuple(args, "i", &i)) {
         PyErr_Clear();
         if (i == Message::PARSE) {
             self->message = new Message(Message::PARSE);
@@ -274,17 +274,17 @@ Message_getHeaderFlag(s_Message* self, PyObject* args) {
 
 static PyObject*
 Message_setHeaderFlag(s_Message* self, PyObject* args) {
-    int messageflag;
+    long messageflag;
     PyObject *on = Py_True;
 
-    if (!PyArg_ParseTuple(args, "i|O!", &messageflag, &PyBool_Type, &on)) {
+    if (!PyArg_ParseTuple(args, "l|O!", &messageflag, &PyBool_Type, &on)) {
         PyErr_Clear();
         PyErr_SetString(PyExc_TypeError,
                         "no valid type in set_header_flag argument");
         return (NULL);
     }
-    if (messageflag < 0) {
-        PyErr_SetString(PyExc_TypeError, "invalid Message header flag");
+    if (messageflag < 0 || messageflag > 0xffff) {
+        PyErr_SetString(PyExc_ValueError, "Message header flag out of range");
         return (NULL);
     }
 
@@ -310,10 +310,19 @@ Message_getQid(s_Message* self) {
 
 static PyObject*
 Message_setQid(s_Message* self, PyObject* args) {
-    uint16_t id;
-    if (!PyArg_ParseTuple(args, "H", &id)) {
+    long id;
+    if (!PyArg_ParseTuple(args, "l", &id)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "no valid type in set_qid argument");
         return (NULL);
     }
+    if (id < 0 || id > 0xffff) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Message id out of range");
+        return (NULL);
+    }
+
     try {
         self->message->setQid(id);
         Py_RETURN_NONE;
@@ -565,9 +574,9 @@ Message_addQuestion(s_Message* self, PyObject* args) {
 static PyObject*
 Message_addRRset(s_Message* self, PyObject* args) {
     PyObject *sign = Py_False;
-    unsigned int section;
+    int section;
     s_RRset* rrset;
-    if (!PyArg_ParseTuple(args, "IO!|O!", &section, &rrset_type, &rrset,
+    if (!PyArg_ParseTuple(args, "iO!|O!", &section, &rrset_type, &rrset,
                           &PyBool_Type, &sign)) {
         return (NULL);
     }
@@ -591,8 +600,8 @@ Message_addRRset(s_Message* self, PyObject* args) {
 
 static PyObject*
 Message_clear(s_Message* self, PyObject* args) {
-    unsigned int i;
-    if (PyArg_ParseTuple(args, "I", &i)) {
+    int i;
+    if (PyArg_ParseTuple(args, "i", &i)) {
         PyErr_Clear();
         if (i == Message::PARSE) {
             self->message->clear(Message::PARSE);

+ 12 - 4
src/lib/dns/python/messagerenderer_python.cc

@@ -178,8 +178,16 @@ static PyObject*
 MessageRenderer_setLengthLimit(s_MessageRenderer* self,
                                PyObject* args)
 {
-    unsigned int lengthlimit;
-    if (!PyArg_ParseTuple(args, "I", &lengthlimit)) {
+    long lengthlimit;
+    if (!PyArg_ParseTuple(args, "l", &lengthlimit)) {
+        PyErr_Clear();
+        PyErr_SetString(PyExc_TypeError,
+                        "No valid type in set_length_limit argument");
+        return (NULL);
+    }
+    if (lengthlimit < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "MessageRenderer length limit out of range");
         return (NULL);
     }
     self->messagerenderer->setLengthLimit(lengthlimit);
@@ -190,8 +198,8 @@ static PyObject*
 MessageRenderer_setCompressMode(s_MessageRenderer* self,
                                PyObject* args)
 {
-    unsigned int mode;
-    if (!PyArg_ParseTuple(args, "I", &mode)) {
+    int mode;
+    if (!PyArg_ParseTuple(args, "i", &mode)) {
         return (NULL);
     }
 

+ 42 - 12
src/lib/dns/python/name_python.cc

@@ -321,14 +321,20 @@ Name_init(s_Name* self, PyObject* args) {
     PyObject* bytes_obj;
     const char* bytes;
     Py_ssize_t len;
-    unsigned int position = 0;
+    long position = 0;
 
     // It was not a string (see comment above), so try bytes, and
     // create with buffer object
-    if (PyArg_ParseTuple(args, "O|IO!", &bytes_obj, &position,
+    if (PyArg_ParseTuple(args, "O|lO!", &bytes_obj, &position,
                          &PyBool_Type, &downcase) &&
                          PyObject_AsCharBuffer(bytes_obj, &bytes, &len) != -1) {
         try {
+            if (position < 0) {
+                // Throw IndexError here since name index should be unsigned
+                PyErr_SetString(PyExc_IndexError,
+                                "Name index shouldn't be negative");
+                return (-1);
+            }
             InputBuffer buffer(bytes, len);
 
             buffer.setPosition(position);
@@ -363,10 +369,17 @@ Name_destroy(s_Name* self) {
 
 static PyObject*
 Name_at(s_Name* self, PyObject* args) {
-    unsigned int pos;
-    if (!PyArg_ParseTuple(args, "I", &pos)) {
+    int pos;
+    if (!PyArg_ParseTuple(args, "i", &pos)) {
+        return (NULL);
+    }
+    if (pos < 0) {
+        // Throw IndexError here since name index should be unsigned
+        PyErr_SetString(PyExc_IndexError,
+                        "name index shouldn't be negative");
         return (NULL);
     }
+
     try {
         return (Py_BuildValue("I", self->name->at(pos)));
     } catch (const isc::OutOfRange&) {
@@ -405,10 +418,10 @@ static PyObject*
 Name_toWire(s_Name* self, PyObject* args) {
     PyObject* bytes;
     s_MessageRenderer* mr;
-    
+
     if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
         PyObject* bytes_o = bytes;
-        
+
         OutputBuffer buffer(Name::MAX_WIRE);
         self->name->toWire(buffer);
         PyObject* name_bytes = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());
@@ -457,12 +470,18 @@ Name_equals(s_Name* self, PyObject* args) {
         Py_RETURN_FALSE;
 }
 
-static PyObject* 
+static PyObject*
 Name_split(s_Name* self, PyObject* args) {
-    unsigned int first, n;
+    int first, n;
     s_Name* ret = NULL;
-    
-    if (PyArg_ParseTuple(args, "II", &first, &n)) {
+
+    if (PyArg_ParseTuple(args, "ii", &first, &n)) {
+        if (first < 0 || n < 0) {
+            // Throw IndexError here since name index should be unsigned
+            PyErr_SetString(PyExc_IndexError,
+                            "name index shouldn't be negative");
+            return (NULL);
+        }
         ret = PyObject_New(s_Name, &name_type);
         if (ret != NULL) {
             ret->name = NULL;
@@ -477,7 +496,14 @@ Name_split(s_Name* self, PyObject* args) {
                 return (NULL);
             }
         }
-    } else if (PyArg_ParseTuple(args, "I", &n)) {
+    } else if (PyArg_ParseTuple(args, "i", &n)) {
+        PyErr_Clear();
+        if (n < 0) {
+            // Throw IndexError here since name index should be unsigned
+            PyErr_SetString(PyExc_IndexError,
+                            "name index shouldn't be negative");
+            return (NULL);
+        }
         ret = PyObject_New(s_Name, &name_type);
         if (ret != NULL) {
             ret->name = NULL;
@@ -493,6 +519,10 @@ Name_split(s_Name* self, PyObject* args) {
             }
         }
     }
+
+    PyErr_Clear();
+    PyErr_SetString(PyExc_TypeError,
+                    "No valid type in split argument");
     return (ret);
 }
 #include <iostream>
@@ -502,7 +532,7 @@ Name_split(s_Name* self, PyObject* args) {
 // It is translated to a function that gets 3 arguments, an object,
 // an object to compare to, and an operator.
 //
-static PyObject* 
+static PyObject*
 Name_richcmp(s_Name* self, s_Name* other, int op) {
     bool c;
 

+ 1 - 1
src/lib/dns/python/question_python.cc

@@ -169,7 +169,7 @@ Question_init(s_Question* self, PyObject* args) {
     }
 
     self->question = QuestionPtr();
-    
+
     PyErr_Clear();
     PyErr_SetString(PyExc_TypeError,
                     "no valid type in constructor argument");

+ 5 - 5
src/lib/dns/python/rcode_python.cc

@@ -171,18 +171,18 @@ PyTypeObject rcode_type = {
 
 int
 Rcode_init(s_Rcode* const self, PyObject* args) {
-    int code = 0;
+    long code = 0;
     int ext_code = 0;
 
-    if (PyArg_ParseTuple(args, "i", &code)) {
+    if (PyArg_ParseTuple(args, "l", &code)) {
         if (code < 0 || code > 0xffff) {
-            PyErr_SetString(PyExc_OverflowError, "Rcode out of range");
+            PyErr_SetString(PyExc_ValueError, "Rcode out of range");
             return (-1);
         }
         ext_code = -1;
-    } else if (PyArg_ParseTuple(args, "ii", &code, &ext_code)) {
+    } else if (PyArg_ParseTuple(args, "li", &code, &ext_code)) {
         if (code < 0 || code > 0xff || ext_code < 0 || ext_code > 0xff) {
-            PyErr_SetString(PyExc_OverflowError, "Rcode out of range");
+            PyErr_SetString(PyExc_ValueError, "Rcode out of range");
             return (-1);
         }
     } else {

+ 6 - 5
src/lib/dns/python/rrclass_python.cc

@@ -152,7 +152,7 @@ static PyTypeObject rrclass_type = {
 static int
 RRClass_init(s_RRClass* self, PyObject* args) {
     const char* s;
-    unsigned int i;
+    long i;
     PyObject* bytes = NULL;
     // The constructor argument can be a string ("IN"), an integer (1),
     // or a sequence of numbers between 0 and 65535 (wire code)
@@ -165,10 +165,11 @@ RRClass_init(s_RRClass* self, PyObject* args) {
         if (PyArg_ParseTuple(args, "s", &s)) {
             self->rrclass = new RRClass(s);
             return (0);
-        } else if (PyArg_ParseTuple(args, "I", &i)) {
-            PyErr_Clear();
-            if (i > 65535) {
-                PyErr_SetString(po_InvalidRRClass, "RR class number too high");
+        } else if (PyArg_ParseTuple(args, "l", &i)) {
+            if (i < 0 || i > 0xffff) {
+                PyErr_Clear();
+                PyErr_SetString(PyExc_ValueError,
+                                "RR class number out of range");
                 return (-1);
             }
             self->rrclass = new RRClass(i);

+ 6 - 2
src/lib/dns/python/rrttl_python.cc

@@ -145,7 +145,7 @@ static PyTypeObject rrttl_type = {
 static int
 RRTTL_init(s_RRTTL* self, PyObject* args) {
     const char* s;
-    unsigned long i;
+    long long i;
     PyObject* bytes = NULL;
     // The constructor argument can be a string ("1234"), an integer (1),
     // or a sequence of numbers between 0 and 255 (wire code)
@@ -158,8 +158,12 @@ RRTTL_init(s_RRTTL* self, PyObject* args) {
         if (PyArg_ParseTuple(args, "s", &s)) {
             self->rrttl = new RRTTL(s);
             return (0);
-        } else if (PyArg_ParseTuple(args, "I", &i)) {
+        } else if (PyArg_ParseTuple(args, "L", &i)) {
             PyErr_Clear();
+            if (i < 0 || i > 0xffffffff) {
+                PyErr_SetString(PyExc_ValueError, "RR TTL number out of range");
+                return (-1);
+            }
             self->rrttl = new RRTTL(i);
             return (0);
         } else if (PyArg_ParseTuple(args, "O", &bytes) &&

+ 6 - 6
src/lib/dns/python/rrtype_python.cc

@@ -182,7 +182,7 @@ static PyTypeObject rrtype_type = {
 static int
 RRType_init(s_RRType* self, PyObject* args) {
     const char* s;
-    unsigned int i;
+    long i;
     PyObject* bytes = NULL;
     // The constructor argument can be a string ("A"), an integer (1),
     // or a sequence of numbers between 0 and 65535 (wire code)
@@ -195,10 +195,10 @@ RRType_init(s_RRType* self, PyObject* args) {
         if (PyArg_ParseTuple(args, "s", &s)) {
             self->rrtype = new RRType(s);
             return (0);
-        } else if (PyArg_ParseTuple(args, "I", &i)) {
+        } else if (PyArg_ParseTuple(args, "l", &i)) {
             PyErr_Clear();
-            if (i > 65535) {
-                PyErr_SetString(po_InvalidRRType, "RR Type number too high");
+            if (i < 0 || i > 0xffff) {
+                PyErr_SetString(PyExc_ValueError, "RR Type number out of range");
                 return (-1);
             }
             self->rrtype = new RRType(i);
@@ -259,10 +259,10 @@ static PyObject*
 RRType_toWire(s_RRType* self, PyObject* args) {
     PyObject* bytes;
     s_MessageRenderer* mr;
-    
+
     if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
         PyObject* bytes_o = bytes;
-        
+
         OutputBuffer buffer(2);
         self->rrtype->toWire(buffer);
         PyObject* n = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());

+ 6 - 7
src/lib/dns/python/tests/edns_python_test.py

@@ -62,17 +62,16 @@ class EDNSTest(unittest.TestCase):
         edns = EDNS()
         edns.set_udp_size(511)
         self.assertEqual(511, edns.get_udp_size())
-        edns.set_udp_size(0)
-        self.assertEqual(0, edns.get_udp_size())
-        edns.set_udp_size(65535)
-        self.assertEqual(65535, edns.get_udp_size())
-
         self.assertRaises(TypeError, edns.set_udp_size, "wrong")
 
         # Range check.  We need to do this at the binding level, so we need
         # explicit tests for it.
-        self.assertRaises(OverflowError, edns.set_udp_size, 65536)
-        self.assertRaises(OverflowError, edns.set_udp_size, -1)
+        edns.set_udp_size(0)
+        self.assertEqual(0, edns.get_udp_size())
+        edns.set_udp_size(65535)
+        self.assertEqual(65535, edns.get_udp_size())
+        self.assertRaises(ValueError, edns.set_udp_size, 0x10000)
+        self.assertRaises(ValueError, edns.set_udp_size, -1)
 
     def test_get_version(self):
         self.assertEqual(EDNS.SUPPORTED_VERSION, EDNS().get_version())

+ 19 - 9
src/lib/dns/python/tests/message_python_test.py

@@ -80,8 +80,10 @@ class MessageTest(unittest.TestCase):
                                         "2001:db8::134"))
 
         self.bogus_section = Message.SECTION_ADDITIONAL + 1
+        self.bogus_below_section = Message.SECTION_QUESTION - 1
 
     def test_init(self):
+        self.assertRaises(TypeError, Message, -1)
         self.assertRaises(TypeError, Message, 3)
         self.assertRaises(TypeError, Message, "wrong")
 
@@ -109,22 +111,28 @@ class MessageTest(unittest.TestCase):
         self.assertRaises(InvalidParameter, self.r.set_header_flag, 0)
         self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x7000)
         self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x0800)
-        self.assertRaises(InvalidParameter, self.r.set_header_flag, 0x10000)
-        self.assertRaises(TypeError, self.r.set_header_flag, 0x80000000)
-        # this would cause overflow and result in a "valid" flag
-        self.assertRaises(TypeError, self.r.set_header_flag,
-                          Message.HEADERFLAG_AA | 0x100000000)
-        self.assertRaises(TypeError, self.r.set_header_flag, -1)
-
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_header_flag, Message.HEADERFLAG_AA)
 
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertRaises(ValueError, self.r.set_header_flag, 0x10000)
+        self.assertRaises(ValueError, self.r.set_header_flag, -1)
+
     def test_set_qid(self):
         self.assertRaises(TypeError, self.r.set_qid, "wrong")
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_qid, 123)
         self.r.set_qid(1234)
         self.assertEqual(1234, self.r.get_qid())
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.r.set_qid(0)
+        self.assertEqual(0, self.r.get_qid())
+        self.r.set_qid(0xffff)
+        self.assertEqual(0xffff, self.r.get_qid())
+        self.assertRaises(ValueError, self.r.set_qid, -1)
+        self.assertRaises(ValueError, self.r.set_qid, 0x10000)
 
     def test_set_rcode(self):
         self.assertRaises(TypeError, self.r.set_rcode, "wrong")
@@ -135,7 +143,7 @@ class MessageTest(unittest.TestCase):
 
         self.assertRaises(InvalidMessageOperation,
                           self.p.set_rcode, rcode)
-        
+
         self.assertRaises(InvalidMessageOperation, self.p.get_rcode)
 
     def test_set_opcode(self):
@@ -197,7 +205,7 @@ class MessageTest(unittest.TestCase):
 
         self.assertRaises(InvalidMessageOperation, self.p.add_rrset,
                           Message.SECTION_ANSWER, self.rrset_a)
-        
+
         self.assertFalse(compare_rrset_list(section_rrset, self.r.get_section(Message.SECTION_ANSWER)))
         self.assertEqual(0, self.r.get_rr_count(Message.SECTION_ANSWER))
         self.r.add_rrset(Message.SECTION_ANSWER, self.rrset_a)
@@ -239,6 +247,8 @@ class MessageTest(unittest.TestCase):
                           Message.SECTION_ANSWER, self.rrset_a)
         self.assertRaises(OverflowError, self.r.add_rrset,
                           self.bogus_section, self.rrset_a)
+        self.assertRaises(OverflowError, self.r.add_rrset,
+                          self.bogus_below_section, self.rrset_a)
 
     def test_clear(self):
         self.assertEqual(None, self.r.clear(Message.PARSE))

+ 5 - 0
src/lib/dns/python/tests/messagerenderer_python_test.py

@@ -98,6 +98,11 @@ class MessageRendererTest(unittest.TestCase):
         renderer.set_length_limit(1024)
         self.assertEqual(1024, renderer.get_length_limit())
         self.assertRaises(TypeError, renderer.set_length_limit, "wrong")
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        renderer.set_length_limit(0)
+        self.assertEqual(0, renderer.get_length_limit())
+        self.assertRaises(ValueError, renderer.set_length_limit, -1)
 
     def test_messagerenderer_set_compress_mode(self):
         renderer = MessageRenderer()

+ 16 - 3
src/lib/dns/python/tests/name_python_test.py

@@ -95,11 +95,14 @@ class NameTest(unittest.TestCase):
         b = bytearray()
         b += b'\x07example'*32 + b'\x03com\x00'
         self.assertRaises(DNSMessageFORMERR, Name, b, 0)
+        self.assertRaises(IndexError, Name, b, -1)
 
     def test_at(self):
         self.assertEqual(7, self.name1.at(0))
         self.assertEqual(101, self.name1.at(1))
         self.assertRaises(IndexError, self.name1.at, 100)
+        self.assertRaises(IndexError, self.name1.at, 0x10000)
+        self.assertRaises(IndexError, self.name1.at, -1)
         self.assertRaises(TypeError, self.name1.at, "wrong")
 
     def test_get_length(self):
@@ -151,14 +154,25 @@ class NameTest(unittest.TestCase):
         self.assertEqual("completely.different.", s.to_text())
         self.assertRaises(TypeError, self.name1.split, "wrong", 1)
         self.assertRaises(TypeError, self.name1.split, 1, "wrong")
-        self.assertRaises(IndexError, self.name1.split, 123, 1)
-        self.assertRaises(IndexError, self.name1.split, 1, 123)
 
         s = self.name1.split(1)
         self.assertEqual("com.", s.to_text())
+
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertRaises(IndexError, self.name1.split, 123, 1)
+        self.assertRaises(IndexError, self.name1.split, 1, 123)
+        self.assertRaises(IndexError, self.name1.split, 0x10000, 5)
+        self.assertRaises(IndexError, self.name1.split, -1, -1)
+        self.assertRaises(IndexError, self.name1.split, 0, -1)
+        self.assertRaises(IndexError, self.name1.split, -1, 0x10000)
+
         s = self.name1.split(0)
         self.assertEqual("example.com.", s.to_text())
         self.assertRaises(IndexError, self.name1.split, 123)
+        self.assertRaises(IndexError, self.name1.split, 0x10000)
+        self.assertRaises(IndexError, self.name1.split, -123)
+        self.assertRaises(TypeError, self.name1.split, -1)
 
     def test_reverse(self):
         self.assertEqual("com.example.", self.name1.reverse().to_text())
@@ -169,7 +183,6 @@ class NameTest(unittest.TestCase):
         self.assertEqual("example.com.example.com.", self.name1.concatenate(self.name1).to_text())
         self.assertRaises(TypeError, self.name1.concatenate, "wrong")
         self.assertRaises(TooLongName, self.name1.concatenate, Name("example."*31))
-        
 
     def test_downcase(self):
         self.assertEqual("EXAMPLE.com.", self.name4.to_text())

+ 1 - 1
src/lib/dns/python/tests/question_python_test.py

@@ -45,7 +45,7 @@ class QuestionTest(unittest.TestCase):
     # tests below based on cpp unit tests
     # also tests get_name, get_class and get_type
     def test_from_wire(self):
-        
+
         q = question_from_wire("question_fromWire")
 
         self.assertEqual(self.example_name1, q.get_name())

+ 13 - 6
src/lib/dns/python/tests/rcode_python_test.py

@@ -23,12 +23,8 @@ from pydnspp import *
 class RcodeTest(unittest.TestCase):
     def test_init(self):
         self.assertRaises(TypeError, Rcode, "wrong")
-        self.assertRaises(OverflowError, Rcode, 65536)
-        self.assertEqual(Rcode(0).get_code(), 0)
-    
-        self.assertEqual(0, Rcode(0).get_code())
         self.assertEqual(0xfff, Rcode(0xfff).get_code()) # possible max code
-    
+
         # should fail on attempt of construction with an out of range code
         self.assertRaises(OverflowError, Rcode, 0x1000)
         self.assertRaises(OverflowError, Rcode, 0xffff)
@@ -38,7 +34,18 @@ class RcodeTest(unittest.TestCase):
         self.assertEqual(Rcode.BADVERS_CODE, Rcode(0, 1).get_code())
         self.assertEqual(0xfff, Rcode(0xf, 0xff).get_code())
         self.assertRaises(OverflowError, Rcode, 0x10, 0xff)
-        
+
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertEqual(Rcode(0).get_code(), 0)
+        self.assertEqual(Rcode(4095).get_code(), 4095)
+        self.assertEqual(Rcode(0, 0).get_code(), 0)
+        self.assertEqual(Rcode(0, 0).get_extended_code(), 0)
+        self.assertEqual(Rcode(15, 255).get_code(), 4095)
+        self.assertRaises(ValueError, Rcode, 65536)
+        self.assertRaises(ValueError, Rcode, 0x10, 0x100)
+        self.assertRaises(ValueError, Rcode, 0x100, 0x10)
+
     def test_constants(self):
         self.assertEqual(Rcode.NOERROR_CODE, Rcode(0).get_code())
         self.assertEqual(Rcode.FORMERR_CODE, Rcode(1).get_code())

+ 7 - 2
src/lib/dns/python/tests/rrclass_python_test.py

@@ -32,12 +32,17 @@ class RRClassTest(unittest.TestCase):
         b = bytearray(1)
         b[0] = 123
         self.assertRaises(TypeError, RRClass, b)
-        self.assertRaises(InvalidRRClass, RRClass, 65536)
         self.assertEqual(self.c1, RRClass(1))
         b = bytearray()
         self.c1.to_wire(b)
         self.assertEqual(self.c1, RRClass(b))
-        
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertRaises(ValueError, RRClass, 65536)
+        self.assertRaises(TypeError, RRClass, -1)
+        self.assertEqual(RRClass(65535).get_code(), 65535)
+        self.assertEqual(RRClass(0).get_code(), 0)
+
     def test_rrclass_to_text(self):
         self.assertEqual("IN", self.c1.to_text())
         self.assertEqual("IN", str(self.c1))

+ 8 - 2
src/lib/dns/python/tests/rrttl_python_test.py

@@ -25,7 +25,7 @@ class RRTTLTest(unittest.TestCase):
     def setUp(self):
         self.t1 = RRTTL(1)
         self.t2 = RRTTL(3600)
-        
+
     def test_init(self):
         self.assertRaises(InvalidRRTTL, RRTTL, "wrong")
         self.assertRaises(TypeError, RRTTL, Exception())
@@ -39,7 +39,13 @@ class RRTTLTest(unittest.TestCase):
         b[2] = 0
         b[3] = 15
         self.assertEqual(15, RRTTL(b).get_value())
-        
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertRaises(TypeError, RRTTL, -1)
+        self.assertRaises(ValueError, RRTTL, 4294967296)
+        self.assertEqual(0, RRTTL(0).get_value())
+        self.assertEqual(4294967295, RRTTL(4294967295).get_value())
+
     def test_rrttl_to_text(self):
         self.assertEqual("1", self.t1.to_text())
         self.assertEqual("1", str(self.t1))

+ 10 - 6
src/lib/dns/python/tests/rrtype_python_test.py

@@ -22,7 +22,7 @@ import os
 from pydnspp import *
 
 class TestModuleSpec(unittest.TestCase):
-    
+
     rrtype_1 = RRType(1)
     rrtype_0x80 = RRType(0x80);
     rrtype_0x800 = RRType(0x800);
@@ -32,24 +32,28 @@ class TestModuleSpec(unittest.TestCase):
 
 
     def test_init(self):
-        self.assertRaises(InvalidRRType, RRType, 65537)
         b = bytearray(b'\x00\x01')
         self.assertEqual(RRType("A"), RRType(b))
         b = bytearray(b'\x01')
         self.assertRaises(IncompleteRRType, RRType, b)
         self.assertRaises(TypeError, RRType, Exception)
-    
+        # Range check.  We need to do this at the binding level, so we need
+        # explicit tests for it.
+        self.assertRaises(ValueError, RRType, 65536)
+        self.assertRaises(TypeError, RRType, -1)
+        self.assertEqual("TYPE65535", RRType(65535).to_text());
+        self.assertEqual("TYPE0", RRType(0).to_text());
+
     def test_init_from_text(self):
         self.assertEqual("A", RRType("A").to_text())
         self.assertEqual("NS", RRType("NS").to_text());
         self.assertEqual("NS", str(RRType("NS")));
-    
         self.assertEqual("TYPE65535", RRType("TYPE65535").to_text());
-    
+
         self.assertEqual(53, RRType("TYPE00053").get_code());
 
         self.assertRaises(InvalidRRType, RRType, "TYPE000053");
-    
+
         self.assertRaises(InvalidRRType, RRType, "TYPE");
         self.assertRaises(InvalidRRType, RRType, "TYPE-1");
         self.assertRaises(InvalidRRType, RRType, "TYPExxx");

+ 2 - 1
src/lib/dns/rdata.cc

@@ -66,7 +66,8 @@ createRdata(const RRType& rrtype, const RRClass& rrclass,
                                                    len);
                                                    
     if (buffer.getPosition() - old_pos != len) {
-        isc_throw(InvalidRdataLength, "RDLENGTH mismatch");
+        isc_throw(InvalidRdataLength, "RDLENGTH mismatch: " <<
+                  buffer.getPosition() - old_pos << " != " << len);
     }
 
     return (rdata);

+ 11 - 0
src/lib/dns/rdata.h

@@ -161,6 +161,7 @@ public:
     ///
     /// \return A string representation of \c Rdata.
     virtual std::string toText() const = 0;
+
     /// \brief Render the \c Rdata in the wire format into a buffer.
     ///
     /// This is a pure virtual method without the definition; the actual
@@ -169,6 +170,7 @@ public:
     ///
     /// \param buffer An output buffer to store the wire data.
     virtual void toWire(OutputBuffer& buffer) const = 0;
+
     /// \brief Render the \c Rdata in the wire format into a
     /// \c MessageRenderer object.
     ///
@@ -251,6 +253,7 @@ public:
     /// \param rdata_string A string of textual representation of generic
     /// RDATA.
     explicit Generic(const std::string& rdata_string);
+
     ///
     /// \brief Constructor from wire-format data.
     ///
@@ -273,6 +276,7 @@ public:
     /// \c Rdata to parse.
     /// \param rdata_len The length in buffer of the \c Rdata.  In bytes.
     Generic(InputBuffer& buffer, size_t rdata_len);
+
     ///
     /// \brief The destructor.
     virtual ~Generic();
@@ -284,6 +288,7 @@ public:
     ///
     /// \param source A reference to a \c generic::Generic object to copy from.
     Generic(const Generic& source);
+
     ///
     /// \brief The assignment operator.
     ///
@@ -293,6 +298,7 @@ public:
     /// \param source A reference to a \c generic::Generic object to copy from.
     Generic& operator=(const Generic& source);
     //@}
+
     ///
     /// \name Converter methods
     ///
@@ -307,6 +313,7 @@ public:
     ///
     /// \return A string representation of \c generic::Generic.
     virtual std::string toText() const;
+
     ///
     /// \brief Render the \c generic::Generic in the wire format into a buffer.
     ///
@@ -317,6 +324,7 @@ public:
     ///
     /// \param buffer An output buffer to store the wire data.
     virtual void toWire(OutputBuffer& buffer) const;
+
     /// \brief Render the \c generic::Generic in the wire format into a
     /// \c MessageRenderer object.
     ///
@@ -329,6 +337,7 @@ public:
     /// output buffer in which the \c Generic object is to be stored.
     virtual void toWire(MessageRenderer& renderer) const;
     //@}
+
     ///
     /// \name Comparison method
     ///
@@ -421,6 +430,7 @@ std::ostream& operator<<(std::ostream& os, const Generic& rdata);
 /// object.
 RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
                      const std::string& rdata_string);
+
 /// \brief Create RDATA of a given pair of RR type and class from
 /// wire-format data.
 ///
@@ -444,6 +454,7 @@ RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
 /// object.
 RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
                      InputBuffer& buffer, size_t len);
+
 /// \brief Create RDATA of a given pair of RR type and class, copying
 /// of another RDATA of same kind.
 ///

+ 124 - 0
src/lib/dns/rdata/generic/rp_17.cc

@@ -0,0 +1,124 @@
+// Copyright (C) 2011  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.
+
+#include <string>
+#include <sstream>
+
+#include <dns/buffer.h>
+#include <dns/messagerenderer.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+
+using namespace std;
+using namespace isc::dns;
+
+// BEGIN_ISC_NAMESPACE
+// BEGIN_RDATA_NAMESPACE
+
+/// \brief Constructor from string.
+///
+/// \c rp_str must be formatted as follows:
+/// \code <mailbox name> <text name>
+/// \endcode
+/// where both fields must represent a valid domain name.
+///
+/// \exception InvalidRdataText The number of RDATA fields (must be 2) is
+/// incorrect.
+/// \exception Other The constructor of the \c Name class will throw if the
+/// given name is invalid.
+/// \exception std::bad_alloc Memory allocation for names fails.
+RP::RP(const std::string& rp_str) :
+    // We cannot construct both names in the initialization list due to the
+    // necessary text processing, so we have to initialize them with a dummy
+    // name and replace them later.
+    mailbox_(Name::ROOT_NAME()), text_(Name::ROOT_NAME())
+{
+    istringstream iss(rp_str);
+    string mailbox_str, text_str;
+    iss >> mailbox_str >> text_str;
+
+    // Validation: A valid RP RR must have exactly two fields.
+    if (iss.bad() || iss.fail()) {
+        isc_throw(InvalidRdataText, "Invalid RP text: " << rp_str);
+    }
+    if (!iss.eof()) {
+        isc_throw(InvalidRdataText, "Invalid RP text (redundant field): "
+                  << rp_str);
+    }
+
+    mailbox_ = Name(mailbox_str);
+    text_ = Name(text_str);
+}
+
+/// \brief Constructor from wire-format data.
+///
+/// This constructor doesn't check the validity of the second parameter (rdata
+/// length) for parsing.
+/// If necessary, the caller will check consistency.
+///
+/// \exception std::bad_alloc Memory allocation for names fails.
+/// \exception Other The constructor of the \c Name class will throw if the
+/// names in the wire is invalid.
+RP::RP(InputBuffer& buffer, size_t) : mailbox_(buffer), text_(buffer) {
+}
+
+/// \brief Copy constructor.
+///
+/// \exception std::bad_alloc Memory allocation fails in copying internal
+/// member variables (this should be very rare).
+RP::RP(const RP& other) :
+    Rdata(), mailbox_(other.mailbox_), text_(other.text_)
+{}
+
+/// \brief Convert the \c RP to a string.
+///
+/// The output of this method is formatted as described in the "from string"
+/// constructor (\c RP(const std::string&))).
+///
+/// \exception std::bad_alloc Internal resource allocation fails.
+///
+/// \return A \c string object that represents the \c RP object.
+std::string
+RP::toText() const {
+    return (mailbox_.toText() + " " + text_.toText());
+}
+
+void
+RP::toWire(OutputBuffer& buffer) const {
+    mailbox_.toWire(buffer);
+    text_.toWire(buffer);
+}
+
+void
+RP::toWire(MessageRenderer& renderer) const {
+    // Type RP is not "well-known", and name compression must be disabled
+    // per RFC3597.
+    renderer.writeName(mailbox_, false);
+    renderer.writeName(text_, false);
+}
+
+int
+RP::compare(const Rdata& other) const {
+    const RP& other_rp = dynamic_cast<const RP&>(other);
+
+    const int cmp = compareNames(mailbox_, other_rp.mailbox_);
+    if (cmp != 0) {
+        return (cmp);
+    }
+    return (compareNames(text_, other_rp.text_));
+}
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE

+ 88 - 0
src/lib/dns/rdata/generic/rp_17.h

@@ -0,0 +1,88 @@
+// Copyright (C) 2011  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.
+
+// BEGIN_HEADER_GUARD
+
+#include <string>
+
+#include <dns/name.h>
+#include <dns/rdata.h>
+
+// BEGIN_ISC_NAMESPACE
+
+// BEGIN_COMMON_DECLARATIONS
+// END_COMMON_DECLARATIONS
+
+// BEGIN_RDATA_NAMESPACE
+
+/// \brief \c rdata::generic::RP class represents the RP RDATA as defined in
+/// RFC1183.
+///
+/// This class implements the basic interfaces inherited from the abstract
+/// \c rdata::Rdata class, and provides trivial accessors specific to the
+/// RP RDATA.
+class RP : public Rdata {
+public:
+    // BEGIN_COMMON_MEMBERS
+    // END_COMMON_MEMBERS
+
+    /// We use the default copy constructor and assignment operator.
+
+    /// \brief Constructor from RDATA field parameters.
+    ///
+    /// The parameters are a straightforward mapping of %RP RDATA
+    /// fields as defined in RFC1183.
+    RP(const Name& mailbox, const Name& text) :
+        mailbox_(mailbox), text_(text)
+    {}
+
+    /// \brief Return the value of the mailbox field.
+    ///
+    /// This method normally does not throw an exception, but if resource
+    /// allocation for the returned \c Name object fails, a corresponding
+    /// standard exception will be thrown.
+    ///
+    /// \note
+    /// Unlike the case of some other RDATA classes (such as
+    /// \c NS::getNSName()), this method constructs a new \c Name object
+    /// and returns it, instead of returning a reference to a \c Name object
+    /// internally maintained in the class (which is a private member).
+    /// This is based on the observation that this method will be rarely used
+    /// and even when it's used it will not be in a performance context
+    /// (for example, a recursive resolver won't need this field in its
+    /// resolution process).  By returning a new object we have flexibility of
+    /// changing the internal representation without the risk of changing
+    /// the interface or method property.
+    /// The same note applies to the \c getText() method.
+    Name getMailbox() const { return (mailbox_); }
+
+    /// \brief Return the value of the text field.
+    ///
+    /// This method normally does not throw an exception, but if resource
+    /// allocation for the returned \c Name object fails, a corresponding
+    /// standard exception will be thrown.
+    Name getText() const { return (text_); }
+
+private:
+    Name mailbox_;
+    Name text_;
+};
+
+// END_RDATA_NAMESPACE
+// END_ISC_NAMESPACE
+// END_HEADER_GUARD
+
+// Local Variables:
+// mode: c++
+// End:

+ 1 - 1
src/lib/dns/rdata/template.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011  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

+ 1 - 1
src/lib/dns/rdata/template.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011  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

+ 1 - 0
src/lib/dns/tests/Makefile.am

@@ -39,6 +39,7 @@ run_unittests_SOURCES += rdata_nsec3_unittest.cc
 run_unittests_SOURCES += rdata_nsecbitmap_unittest.cc
 run_unittests_SOURCES += rdata_nsec3param_unittest.cc
 run_unittests_SOURCES += rdata_rrsig_unittest.cc
+run_unittests_SOURCES += rdata_rp_unittest.cc
 run_unittests_SOURCES += rdata_tsig_unittest.cc
 run_unittests_SOURCES += rrset_unittest.cc rrsetlist_unittest.cc
 run_unittests_SOURCES += question_unittest.cc

+ 49 - 0
src/lib/dns/tests/buffer_unittest.cc

@@ -190,4 +190,53 @@ TEST_F(BufferTest, outputBufferClear) {
     obuffer.clear();
     EXPECT_EQ(0, obuffer.getLength());
 }
+
+TEST_F(BufferTest, outputBufferCopy) {
+    obuffer.writeData(testdata, sizeof(testdata));
+
+    EXPECT_NO_THROW({
+        OutputBuffer copy(obuffer);
+        ASSERT_EQ(sizeof(testdata), copy.getLength());
+        for (int i = 0; i < sizeof(testdata); i ++) {
+            EXPECT_EQ(testdata[i], copy[i]);
+            if (i + 1 < sizeof(testdata)) {
+                obuffer.writeUint16At(0, i);
+            }
+            EXPECT_EQ(testdata[i], copy[i]);
+        }
+        obuffer.clear();
+        ASSERT_EQ(sizeof(testdata), copy.getLength());
+    });
+}
+
+TEST_F(BufferTest, outputBufferAssign) {
+    OutputBuffer another(0);
+    another.clear();
+    obuffer.writeData(testdata, sizeof(testdata));
+
+    EXPECT_NO_THROW({
+        another = obuffer;
+        ASSERT_EQ(sizeof(testdata), another.getLength());
+        for (int i = 0; i < sizeof(testdata); i ++) {
+            EXPECT_EQ(testdata[i], another[i]);
+            if (i + 1 < sizeof(testdata)) {
+                obuffer.writeUint16At(0, i);
+            }
+            EXPECT_EQ(testdata[i], another[i]);
+        }
+        obuffer.clear();
+        ASSERT_EQ(sizeof(testdata), another.getLength());
+    });
+}
+
+TEST_F(BufferTest, outputBufferZeroSize) {
+    // Some OSes might return NULL on malloc for 0 size, so check it works
+    EXPECT_NO_THROW({
+        OutputBuffer first(0);
+        OutputBuffer copy(first);
+        OutputBuffer second(0);
+        second = first;
+    });
+}
+
 }

+ 162 - 0
src/lib/dns/tests/rdata_rp_unittest.cc

@@ -0,0 +1,162 @@
+// Copyright (C) 2011  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.
+
+#include <string>
+
+#include <dns/buffer.h>
+#include <dns/exceptions.h>
+#include <dns/rdataclass.h>
+
+#include <gtest/gtest.h>
+
+#include <dns/tests/unittest_util.h>
+#include <dns/tests/rdata_unittest.h>
+
+using isc::UnitTestUtil;
+using namespace std;
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+
+namespace {
+class Rdata_RP_Test : public RdataTest {
+protected:
+    Rdata_RP_Test() :
+        mailbox_name("root.example.com."),
+        text_name("rp-text.example.com."),
+        // this also serves as a test for "from text" constructor in a normal
+        // case.
+        rdata_rp("root.example.com. rp-text.example.com."),
+        obuffer(0), renderer(obuffer)
+    {}
+
+    const Name mailbox_name, text_name;
+    const generic::RP rdata_rp; // commonly used test RDATA
+    OutputBuffer obuffer;
+    MessageRenderer renderer;
+    vector<uint8_t> expected_wire;
+};
+
+TEST_F(Rdata_RP_Test, createFromText) {
+    EXPECT_EQ(mailbox_name, rdata_rp.getMailbox());
+    EXPECT_EQ(text_name, rdata_rp.getText());
+
+    // Invalid textual input cases follow:
+    // names are invalid
+    EXPECT_THROW(generic::RP("bad..name. rp-text.example.com"), EmptyLabel);
+    EXPECT_THROW(generic::RP("mailbox.example.com. bad..name"), EmptyLabel);
+
+    // missing field
+    EXPECT_THROW(generic::RP("mailbox.example.com."), InvalidRdataText);
+
+    // redundant field
+    EXPECT_THROW(generic::RP("mailbox.example.com. rp-text.example.com. "
+                             "redundant.example."), InvalidRdataText);
+}
+
+TEST_F(Rdata_RP_Test, createFromWire) {
+    RdataPtr rdata(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                        "rdata_rp_fromWire1.wire"));
+    EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox());
+    EXPECT_EQ(text_name, dynamic_cast<generic::RP&>(*rdata).getText());
+
+    // a similar test with names being compressed
+    rdata = rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                 "rdata_rp_fromWire2.wire", 30);
+    EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox());
+    EXPECT_EQ(Name("rp-text.example.net"),
+              dynamic_cast<generic::RP&>(*rdata).getText());
+}
+
+TEST_F(Rdata_RP_Test, badFromWire) {
+    // RDLEN is too short
+    EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                      "rdata_rp_fromWire3.wire"),
+                 InvalidRdataLength);
+
+    // RDLEN is too long
+    EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                      "rdata_rp_fromWire4.wire"),
+                 InvalidRdataLength);
+
+    // bogus mailbox name
+    EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                      "rdata_rp_fromWire5.wire"),
+                 DNSMessageFORMERR);
+
+    // bogus text name
+    EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(),
+                                      "rdata_rp_fromWire6.wire"),
+                 DNSMessageFORMERR);
+}
+
+TEST_F(Rdata_RP_Test, createFromParams) {
+    EXPECT_EQ(mailbox_name, generic::RP(mailbox_name, text_name).getMailbox());
+    EXPECT_EQ(text_name, generic::RP(mailbox_name, text_name).getText());
+}
+
+TEST_F(Rdata_RP_Test, toWireBuffer) {
+    // construct expected data
+    UnitTestUtil::readWireData("rdata_rp_toWire1.wire", expected_wire);
+
+    // construct actual data
+    rdata_rp.toWire(obuffer);
+
+    // then compare them
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+                        obuffer.getData(), obuffer.getLength(),
+                        &expected_wire[0], expected_wire.size());
+}
+
+TEST_F(Rdata_RP_Test, toWireRenderer) {
+    // similar to toWireBuffer, but names in RDATA could be compressed due to
+    // preceding names.  Actually they must not be compressed according to
+    // RFC3597, and this test checks that.
+
+    UnitTestUtil::readWireData("rdata_rp_toWire2.wire", expected_wire);
+
+    renderer.writeName(Name("a.example.com"));
+    renderer.writeName(Name("b.example.net"));
+    generic::RP(mailbox_name, Name("rp-text.example.net")).toWire(renderer);
+    EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
+                        renderer.getData(), renderer.getLength(),
+                        &expected_wire[0], expected_wire.size());
+}
+
+TEST_F(Rdata_RP_Test, toText) {
+    // there's not much to test for this method.  Only checking a simple case.
+    EXPECT_EQ("root.example.com. rp-text.example.com.", rdata_rp.toText());
+}
+
+TEST_F(Rdata_RP_Test, compare) {
+    // check reflexivity
+    EXPECT_EQ(0, rdata_rp.compare(rdata_rp));
+
+    // names must be compared in case-insensitive manner
+    EXPECT_EQ(0, rdata_rp.compare(generic::RP("ROOT.example.com. "
+                                              "rp-text.EXAMPLE.com.")));
+
+    // another RP whose mailbox name is larger than that of rdata_rp.
+    const generic::RP large1_rp("zzzz.example.com. rp-text.example.com.");
+    EXPECT_GT(0, rdata_rp.compare(large1_rp));
+    EXPECT_LT(0, large1_rp.compare(rdata_rp));
+
+    // yet another RP whose text name is larger than that of rdata_rp.
+    const generic::RP large2_rp("root.example.com. zzzzzzz.example.com.");
+    EXPECT_GT(0, rdata_rp.compare(large2_rp));
+    EXPECT_LT(0, large2_rp.compare(rdata_rp));
+
+    // comparison attempt between incompatible RR types should be rejected
+    EXPECT_THROW(rdata_rp.compare(*RdataTest::rdata_nomatch), bad_cast);
+}
+}

+ 8 - 0
src/lib/dns/tests/testdata/Makefile.am

@@ -16,6 +16,10 @@ BUILT_SOURCES += rdata_nsec3_fromWire10.wire rdata_nsec3_fromWire11.wire
 BUILT_SOURCES += rdata_nsec3_fromWire12.wire rdata_nsec3_fromWire13.wire
 BUILT_SOURCES += rdata_nsec3_fromWire14.wire rdata_nsec3_fromWire15.wire
 BUILT_SOURCES += rdata_rrsig_fromWire2.wire
+BUILT_SOURCES += rdata_rp_fromWire1.wire rdata_rp_fromWire2.wire
+BUILT_SOURCES += rdata_rp_fromWire3.wire rdata_rp_fromWire4.wire
+BUILT_SOURCES += rdata_rp_fromWire5.wire rdata_rp_fromWire6.wire
+BUILT_SOURCES += rdata_rp_toWire1.wire rdata_rp_toWire2.wire
 BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
 BUILT_SOURCES += rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
 BUILT_SOURCES += rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire
@@ -67,6 +71,10 @@ EXTRA_DIST += rdata_nsec3_fromWire12.spec rdata_nsec3_fromWire13.spec
 EXTRA_DIST += rdata_nsec3_fromWire14.spec rdata_nsec3_fromWire15.spec
 EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
 EXTRA_DIST += rdata_rrsig_fromWire2.spec
+EXTRA_DIST += rdata_rp_fromWire1.spec rdata_rp_fromWire2.spec
+EXTRA_DIST += rdata_rp_fromWire3.spec rdata_rp_fromWire4.spec
+EXTRA_DIST += rdata_rp_fromWire5.spec rdata_rp_fromWire6.spec
+EXTRA_DIST += rdata_rp_toWire1.spec rdata_rp_toWire2.spec
 EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec
 EXTRA_DIST += rdata_txt_fromWire1 rdata_txt_fromWire2.spec
 EXTRA_DIST += rdata_txt_fromWire3.spec rdata_txt_fromWire4.spec

+ 32 - 3
src/lib/dns/tests/testdata/gen-wiredata.py.in

@@ -90,7 +90,7 @@ def encode_name(name, absolute=True):
     for l in labels:
         if len(l) > 4 and l[0:4] == 'ptr=':
             # special meta-syntax for compression pointer
-            wire += ' %04x' % (0xc000 | int(l[4:]))
+            wire += '%04x' % (0xc000 | int(l[4:]))
             break
         if absolute or len(l) > 0:
             wire += '%02x' % len(l)
@@ -277,6 +277,34 @@ class TXT:
                                     ' ' if len(wirestring_list[i]) > 0 else '',
                                     wirestring_list[i]))
 
+class RP:
+    '''Implements rendering RP RDATA in the wire format.
+    Configurable parameters are as follows:
+    - rdlen: 16-bit RDATA length.  If omitted, the accurate value is auto
+      calculated and used; if negative, the RDLEN field will be omitted from
+      the output data.
+    - mailbox: The mailbox field.
+    - text: The text field.
+    All of these parameters have the default values and can be omitted.
+    '''
+    rdlen = None                # auto-calculate
+    mailbox = 'root.example.com'
+    text = 'rp-text.example.com'
+    def dump(self, f):
+        mailbox_wire = encode_name(self.mailbox)
+        text_wire = encode_name(self.text)
+        if self.rdlen is None:
+            self.rdlen = (len(mailbox_wire) + len(text_wire)) / 2
+        else:
+            self.rdlen = int(self.rdlen)
+        if self.rdlen >= 0:
+            f.write('\n# RP RDATA (RDLEN=%d)\n' % self.rdlen)
+            f.write('%04x\n' % self.rdlen)
+        else:
+            f.write('\n# RP RDATA (RDLEN omitted)\n')
+        f.write('# MAILBOX=%s TEXT=%s\n' % (self.mailbox, self.text))
+        f.write('%s %s\n' % (mailbox_wire, text_wire))
+
 class NSECBASE:
     '''Implements rendering NSEC/NSEC3 type bitmaps commonly used for
     these RRs.  The NSEC and NSEC3 classes will be inherited from this
@@ -461,8 +489,9 @@ def get_config_param(section):
                     'header' : (DNSHeader, header_xtables),
                     'question' : (DNSQuestion, question_xtables),
                     'edns' : (EDNS, {}), 'soa' : (SOA, {}), 'txt' : (TXT, {}),
-                    'rrsig' : (RRSIG, {}), 'nsec' : (NSEC, {}),
-                    'nsec3' : (NSEC3, {}), 'tsig' : (TSIG, {}) }
+                    'rp' : (RP, {}), 'rrsig' : (RRSIG, {}),
+                    'nsec' : (NSEC, {}), 'nsec3' : (NSEC3, {}),
+                    'tsig' : (TSIG, {}) }
     s = section
     m = re.match('^([^:]+)/\d+$', section)
     if m:

+ 6 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec

@@ -0,0 +1,6 @@
+#
+# A simplest form of RP: all default parameters
+#
+[custom]
+sections: rp
+[rp]

+ 12 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec

@@ -0,0 +1,12 @@
+#
+# A simplest form of RP: names are compressed.
+#
+[custom]
+sections: name/1:name/2:rp
+[name/1]
+name: a.example.com
+[name/2]
+name: b.example.net
+[rp]
+mailbox: root.ptr=2
+text: rp-text.ptr=17

+ 7 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec

@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but RDLEN is too short.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: 38

+ 7 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec

@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but RDLEN is too long.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: 40

+ 7 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec

@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but mailbox name is broken.
+#
+[custom]
+sections: rp
+[rp]
+mailbox: "01234567890123456789012345678901234567890123456789012345678901234"

+ 7 - 0
src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec

@@ -0,0 +1,7 @@
+#
+# RP-like RDATA but text name is broken.
+#
+[custom]
+sections: rp
+[rp]
+text: "01234567890123456789012345678901234567890123456789012345678901234"

+ 8 - 0
src/lib/dns/tests/testdata/rdata_rp_toWire1.spec

@@ -0,0 +1,8 @@
+#
+# A simplest form of RP for toWire test: all default parameters except rdlen,
+# which is to be omitted.
+#
+[custom]
+sections: rp
+[rp]
+rdlen: -1

+ 14 - 0
src/lib/dns/tests/testdata/rdata_rp_toWire2.spec

@@ -0,0 +1,14 @@
+#
+# A simple form of RP: names could be compressed (but MUST NOT).
+# rdlen is omitted for the "to wire" test.
+#
+[custom]
+sections: name/1:name/2:rp
+[name/1]
+name: a.example.com
+[name/2]
+name: b.example.net
+[rp]
+rdlen: -1
+mailbox: root.example.com
+text: rp-text.example.net

+ 23 - 8
src/lib/resolve/recursive_query.cc

@@ -59,19 +59,19 @@ RecursiveQuery::RecursiveQuery(DNSService& dns_service,
     const std::vector<std::pair<std::string, uint16_t> >& upstream,
     const std::vector<std::pair<std::string, uint16_t> >& upstream_root,
     int query_timeout, int client_timeout, int lookup_timeout,
-    unsigned retries) :
+    unsigned retries)
+    :
     dns_service_(dns_service),
     nsas_(nsas), cache_(cache),
     upstream_(new AddressVector(upstream)),
     upstream_root_(new AddressVector(upstream_root)),
     test_server_("", 0),
     query_timeout_(query_timeout), client_timeout_(client_timeout),
-    lookup_timeout_(lookup_timeout), retries_(retries)
+    lookup_timeout_(lookup_timeout), retries_(retries), rtt_recorder_()
 {
 }
 
 // Set the test server - only used for unit testing.
-
 void
 RecursiveQuery::setTestServer(const std::string& address, uint16_t port) {
     dlog("Setting test server to " + address + "(" +
@@ -80,6 +80,11 @@ RecursiveQuery::setTestServer(const std::string& address, uint16_t port) {
     test_server_.second = port;
 }
 
+// Set the RTT recorder - only used for testing
+void
+RecursiveQuery::setRttRecorder(boost::shared_ptr<RttRecorder>& recorder) {
+    rtt_recorder_ = recorder;
+}
 
 namespace {
 
@@ -225,6 +230,10 @@ private:
     // event; we can cancel the NSAS callback safely.
     size_t outstanding_events_;
 
+    // RTT Recorder.  Used for testing, the RTTs of queries are
+    // sent to this object as well as being used to update the NSAS.
+    boost::shared_ptr<RttRecorder> rtt_recorder_;
+
     // perform a single lookup; first we check the cache to see
     // if we have a response for our query stored already. if
     // so, call handlerecursiveresponse(), if not, we call send()
@@ -483,7 +492,9 @@ public:
         int query_timeout, int client_timeout, int lookup_timeout,
         unsigned retries,
         isc::nsas::NameserverAddressStore& nsas,
-        isc::cache::ResolverCache& cache) :
+        isc::cache::ResolverCache& cache,
+        boost::shared_ptr<RttRecorder>& recorder)
+        :
         io_(io),
         question_(question),
         answer_message_(answer_message),
@@ -504,7 +515,8 @@ public:
         cur_zone_("."),
         nsas_callback_(new ResolverNSASCallback(this)),
         nsas_callback_out_(false),
-        outstanding_events_(0)
+        outstanding_events_(0),
+        rtt_recorder_(recorder)
     {
         // Setup the timer to stop trying (lookup_timeout)
         if (lookup_timeout >= 0) {
@@ -621,9 +633,11 @@ public:
                 rtt = 1000 * (cur_time.tv_sec - current_ns_qsent_time.tv_sec);
                 rtt += (cur_time.tv_usec - current_ns_qsent_time.tv_usec) / 1000;
             }
-
             dlog("RTT: " + boost::lexical_cast<std::string>(rtt));
             current_ns_address.updateRTT(rtt);
+            if (rtt_recorder_) {
+                rtt_recorder_->addRtt(rtt);
+            }
 
             try {
                 Message incoming(Message::PARSE);
@@ -741,7 +755,8 @@ RecursiveQuery::resolve(const QuestionPtr& question,
             new RunningQuery(io, *question, answer_message, upstream_,
                              test_server_, buffer, callback,
                              query_timeout_, client_timeout_,
-                             lookup_timeout_, retries_, nsas_, cache_);
+                             lookup_timeout_, retries_, nsas_,
+                             cache_, rtt_recorder_);
         }
     }
 }
@@ -794,7 +809,7 @@ RecursiveQuery::resolve(const Question& question,
             new RunningQuery(io, question, answer_message, upstream_,
                              test_server_, buffer, crs, query_timeout_,
                              client_timeout_, lookup_timeout_, retries_,
-                             nsas_, cache_);
+                             nsas_, cache_, rtt_recorder_);
         }
     }
 }

+ 43 - 4
src/lib/resolve/recursive_query.h

@@ -23,11 +23,41 @@
 
 namespace isc {
 namespace asiodns {
-/// \brief The \c RecursiveQuery class provides a layer of abstraction around
-/// the ASIO code that carries out an upstream query.
+
+/// \brief RTT Recorder
+///
+/// Used for testing, this class will hold the set of round-trip times to
+/// nameservers for the current recursive query.
+///
+/// A pointer to an object of this class is passed to RecursiveQuery which in
+/// turn passes it to the created RunningQuery class.  When a running query
+/// completes, its RTT is passed to the RTT Recorder object.
+class RttRecorder {
+public:
+    /// \brief Record Time
+    ///
+    /// Adds a round-trip time to the internal vector of times.
+    ///
+    /// \param RTT to record.
+    void addRtt(uint32_t rtt) {
+        rtt_.push_back(rtt);
+    }
+
+    /// \brief Return RTT Vector
+    std::vector<uint32_t> getRtt() const {
+        return rtt_;
+    }
+
+private:
+    std::vector<uint32_t>   rtt_;   ///< Stored round-trip times
+};
+
+
+/// \brief Recursive Query
 ///
-/// This design is very preliminary; currently it is only capable of
-/// handling simple forward requests to a single resolver.
+/// The \c RecursiveQuery class provides a layer of abstraction around
+/// the ASIO code that carries out an upstream query.
+
 class RecursiveQuery {
     ///
     /// \name Constructors
@@ -66,6 +96,14 @@ public:
                    unsigned retries = 3);
     //@}
 
+    /// \brief Set Round-Trip Time Recorder
+    ///
+    /// Sets the RTT recorder object.  This is not accessed directly, instead
+    /// it is passed to created RunningQuery objects.
+    ///
+    /// \param recorder Pointer to the RTT recorder object used to hold RTTs.
+    void setRttRecorder(boost::shared_ptr<RttRecorder>& recorder);
+
     /// \brief Initiate resolving
     ///
     /// When sendQuery() is called, a (set of) message(s) is sent
@@ -128,6 +166,7 @@ private:
     int client_timeout_;
     int lookup_timeout_;
     unsigned retries_;
+    boost::shared_ptr<RttRecorder>  rtt_recorder_;  ///< Round-trip time recorder
 };
 
 }      // namespace asiodns

+ 16 - 1
src/lib/resolve/tests/recursive_query_unittest_2.cc

@@ -17,6 +17,7 @@
 #include <iomanip>
 #include <iostream>
 #include <string>
+#include <vector>
 
 #include <gtest/gtest.h>
 #include <boost/bind.hpp>
@@ -651,13 +652,17 @@ TEST_F(RecursiveQueryTest2, Resolve) {
                           boost::bind(&RecursiveQueryTest2::tcpAcceptHandler,
                                       this, _1, 0));
 
-    // Set up the RecursiveQuery object.
+    // Set up the RecursiveQuery object. We will also test that it correctly records
+    // RTT times by setting up a RTT recorder object as well.
     std::vector<std::pair<std::string, uint16_t> > upstream;         // Empty
     std::vector<std::pair<std::string, uint16_t> > upstream_root;    // Empty
     RecursiveQuery query(dns_service_, *nsas_, cache_,
                          upstream, upstream_root);
     query.setTestServer(TEST_ADDRESS, TEST_PORT);
 
+    boost::shared_ptr<RttRecorder> recorder(new RttRecorder());
+    query.setRttRecorder(recorder);
+
     // Set up callback to receive notification that the query has completed.
     isc::resolve::ResolverInterface::CallbackPtr
         resolver_callback(new ResolverCallback(service_));
@@ -674,6 +679,16 @@ TEST_F(RecursiveQueryTest2, Resolve) {
     ResolverCallback* rc = static_cast<ResolverCallback*>(resolver_callback.get());
     EXPECT_TRUE(rc->getRun());
     EXPECT_TRUE(rc->getStatus());
+
+    // Finally, check that all the RTTs were "reasonable" (defined here as
+    // being below 2 seconds).  This is an explicit check to test that the
+    // variables in the RTT calculation are at least being initialized; if they
+    // weren't, we would expect some absurdly high answers.
+    vector<uint32_t> rtt = recorder->getRtt();
+    EXPECT_GT(rtt.size(), 0);
+    for (int i = 0; i < rtt.size(); ++i) {
+        EXPECT_LT(rtt[i], 2000);
+    }
 }
 
 } // namespace asiodns

+ 3 - 0
src/lib/util/Makefile.am

@@ -0,0 +1,3 @@
+SUBDIRS = io unittests io/tests
+# The io/tests is hack, because otherwise we can not order these directories
+# properly. Unittests use io and io/tests use unittest.

+ 16 - 0
src/lib/util/io/Makefile.am

@@ -0,0 +1,16 @@
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+lib_LTLIBRARIES = libutil_io.la
+libutil_io_la_SOURCES = fd.h fd.cc fd_share.h fd_share.cc
+libutil_io_la_CXXFLAGS = $(AM_CXXFLAGS) -fno-strict-aliasing
+
+CLEANFILES = *.gcno *.gcda
+
+pyexec_LTLIBRARIES = libutil_io_python.la
+# Python prefers .so, while some OSes (specifically MacOS) use a different
+# suffix for dynamic objects.  -module is necessary to work this around.
+libutil_io_python_la_LDFLAGS = -module
+libutil_io_python_la_SOURCES = fdshare_python.cc
+libutil_io_python_la_LIBADD = libutil_io.la
+libutil_io_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
+libutil_io_python_la_CXXFLAGS = $(AM_CXXFLAGS)

+ 70 - 0
src/lib/util/io/fd.cc

@@ -0,0 +1,70 @@
+// Copyright (C) 2011  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.
+
+#include "fd.h"
+
+#include <unistd.h>
+#include <cerrno>
+
+namespace isc {
+namespace util {
+namespace io {
+
+bool
+write_data(const int fd, const void *buffer_v, const size_t length) {
+    const unsigned char *buffer(static_cast<const unsigned char *>(buffer_v));
+    size_t rest(length);
+    // Just keep writing until all is written
+    while (rest) {
+        ssize_t written(write(fd, buffer, rest));
+        if (rest == -1) {
+            if (errno == EINTR) { // Just keep going
+                continue;
+            } else {
+                return false;
+            }
+        } else { // Wrote something
+            rest -= written;
+            buffer += written;
+        }
+    }
+    return true;
+}
+
+ssize_t
+read_data(const int fd, void *buffer_v, const size_t length) {
+    unsigned char *buffer(static_cast<unsigned char *>(buffer_v));
+    size_t rest(length), already(0);
+    while (rest) { // Stil something to read
+        ssize_t amount(read(fd, buffer, rest));
+        if (rest == -1) {
+            if (errno == EINTR) { // Continue on interrupted call
+                continue;
+            } else {
+                return -1;
+            }
+        } else if (amount) {
+            already += amount;
+            rest -= amount;
+            buffer += amount;
+        } else { // EOF
+            return already;
+        }
+    }
+    return already;
+}
+
+}
+}
+}

+ 61 - 0
src/lib/util/io/fd.h

@@ -0,0 +1,61 @@
+// Copyright (C) 2011  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.
+
+#ifndef __UTIL_IO_FD_H
+#define __UTIL_IO_FD_H 1
+
+#include <unistd.h>
+
+/**
+ * @file fd.h
+ * @short Wrappers around common unix fd manipulation functions.
+ */
+
+namespace isc {
+namespace util {
+namespace io {
+
+/*
+ * \short write() that writes everything.
+ * Wrapper around write(). The difference is, it never writes less data
+ * and looks successfull (eg. it blocks until all data are written).
+ * Retries on signals.
+ *
+ * \return True if sucessfull, false otherwise. The errno variable is left
+ *     intact.
+ * \param fd Where to write.
+ * \param data The buffer to write.
+ * \param length How much data is there to write.
+ */
+bool
+write_data(const int fd, const void *data, const size_t length);
+
+/*
+ * \short read() that reads everything.
+ * Wrapper around read(). It does not do short reads, if it returns less,
+ * it means there was EOF. It retries on signals.
+ *
+ * \return Number of bytes read or -1 on error.
+ * \param fd Where to read data from.
+ * \param data Where to put the data.
+ * \param length How many of them.
+ */
+ssize_t
+read_data(const int fd, void *buffer, const size_t length);
+
+}
+}
+}
+
+#endif // __UTIL_IO_FD_H

+ 10 - 8
src/lib/xfr/fd_share.cc

@@ -19,10 +19,11 @@
 #include <sys/socket.h>
 #include <sys/uio.h>
 #include <stdlib.h>             // for malloc and free
-#include <xfr/fd_share.h>
+#include "fd_share.h"
 
 namespace isc {
-namespace xfr {
+namespace util {
+namespace io {
 
 namespace {
 // Not all OSes support advanced CMSG macros: CMSG_LEN and CMSG_SPACE.
@@ -86,15 +87,15 @@ recv_fd(const int sock) {
     msghdr.msg_controllen = cmsg_space(sizeof(int));
     msghdr.msg_control = malloc(msghdr.msg_controllen);
     if (msghdr.msg_control == NULL) {
-        return (-1);
+        return (FD_OTHER_ERROR);
     }
 
     if (recvmsg(sock, &msghdr, 0) < 0) {
         free(msghdr.msg_control);
-        return (XFR_FD_RECEIVE_FAIL);
+        return (FD_COMM_ERROR);
     }
     const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
-    int fd = -1;
+    int fd = FD_OTHER_ERROR;
     if (cmsg != NULL && cmsg->cmsg_len == cmsg_len(sizeof(int)) &&
         cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
         fd = *(const int*)CMSG_DATA(cmsg);
@@ -119,7 +120,7 @@ send_fd(const int sock, const int fd) {
     msghdr.msg_controllen = cmsg_space(sizeof(int));
     msghdr.msg_control = malloc(msghdr.msg_controllen);
     if (msghdr.msg_control == NULL) {
-        return (-1);
+        return (FD_OTHER_ERROR);
     }
 
     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
@@ -130,8 +131,9 @@ send_fd(const int sock, const int fd) {
 
     const int ret = sendmsg(sock, &msghdr, 0);
     free(msghdr.msg_control);
-    return (ret >= 0 ? 0 : -1);
+    return (ret >= 0 ? 0 : FD_COMM_ERROR);
 }
 
-} // End for namespace xfr
+} // End for namespace io
+} // End for namespace util
 } // End for namespace isc

+ 65 - 0
src/lib/util/io/fd_share.h

@@ -0,0 +1,65 @@
+// Copyright (C) 2011  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.
+
+#ifndef FD_SHARE_H_
+#define FD_SHARE_H_
+
+/**
+ * \file fd_share.h
+ * \short Support to transfer file descriptors between processes.
+ * \todo This interface is very C-ish. Should we have some kind of exceptions?
+ */
+
+namespace isc {
+namespace util {
+namespace io {
+
+const int FD_COMM_ERROR = -2;
+const int FD_OTHER_ERROR = -1;
+
+/**
+ * \short Receives a file descriptor.
+ * This receives a file descriptor sent over an unix domain socket. This
+ * is the counterpart of send_fd().
+ *
+ * \return FD_COMM_ERROR when there's error receiving the socket, FD_OTHER_ERROR
+ *     when there's a different error.
+ * \param sock The unix domain socket to read from. Tested and it does
+ *     not work with a pipe.
+ */
+int recv_fd(const int sock);
+
+/**
+ * \short Sends a file descriptor.
+ * This sends a file descriptor over an unix domain socket. This is the
+ * counterpart of recv_fd().
+ *
+ * \return FD_COMM_ERROR when there's error sending the socket, FD_OTHER_ERROR
+ *     for all other possible errors.
+ * \param sock The unix domain socket to send to. Tested and it does not
+ *     work with a pipe.
+ * \param fd The file descriptor to send. It should work with any valid
+ *     file descriptor.
+ */
+int send_fd(const int sock, const int fd);
+
+} // End for namespace io
+} // End for namespace util
+} // End for namespace isc
+
+#endif
+
+// Local Variables:
+// mode: c++
+// End:

+ 22 - 9
src/lib/xfr/fdshare_python.cc

@@ -18,7 +18,7 @@
 
 #include <config.h>
 
-#include <xfr/fd_share.h>
+#include "fd_share.h"
 
 
 static PyObject*
@@ -27,7 +27,7 @@ fdshare_recv_fd(PyObject*, PyObject* args) {
     if (!PyArg_ParseTuple(args, "i", &sock)) {
         return (NULL);
     }
-    fd = isc::xfr::recv_fd(sock);
+    fd = isc::util::io::recv_fd(sock);
     return (Py_BuildValue("i", fd));
 }
 
@@ -37,7 +37,7 @@ fdshare_send_fd(PyObject*, PyObject* args) {
     if (!PyArg_ParseTuple(args, "ii", &sock, &fd)) {
         return (NULL);
     }
-    result = isc::xfr::send_fd(sock, fd);
+    result = isc::util::io::send_fd(sock, fd);
     return (Py_BuildValue("i", result));
 }
 
@@ -61,20 +61,33 @@ static PyModuleDef bind10_fdshare_python = {
 };
 
 PyMODINIT_FUNC
-PyInit_libxfr_python(void) {
-    PyObject* mod = PyModule_Create(&bind10_fdshare_python);
+PyInit_libutil_io_python(void) {
+    PyObject *mod = PyModule_Create(&bind10_fdshare_python);
     if (mod == NULL) {
         return (NULL);
     }
 
-    PyObject* XFR_FD_RECEIVE_FAIL = Py_BuildValue("i", isc::xfr::XFR_FD_RECEIVE_FAIL);
-    if (XFR_FD_RECEIVE_FAIL == NULL) {
+    PyObject* FD_COMM_ERROR = Py_BuildValue("i", isc::util::io::FD_COMM_ERROR);
+    if (FD_COMM_ERROR == NULL) {
         Py_XDECREF(mod);
         return (NULL);
     }
-    int ret = PyModule_AddObject(mod, "XFR_FD_RECEIVE_FAIL", XFR_FD_RECEIVE_FAIL);
+    int ret = PyModule_AddObject(mod, "FD_COMM_ERROR", FD_COMM_ERROR);
     if (-1 == ret) {
-        Py_XDECREF(XFR_FD_RECEIVE_FAIL);
+        Py_XDECREF(FD_COMM_ERROR);
+        Py_XDECREF(mod);
+        return (NULL);
+    }
+
+    PyObject* FD_OTHER_ERROR = Py_BuildValue("i",
+                                             isc::util::io::FD_OTHER_ERROR);
+    if (FD_OTHER_ERROR == NULL) {
+        Py_XDECREF(mod);
+        return (NULL);
+    }
+    ret = PyModule_AddObject(mod, "FD_OTHER_ERROR", FD_OTHER_ERROR);
+    if (-1 == ret) {
+        Py_XDECREF(FD_OTHER_ERROR);
         Py_XDECREF(mod);
         return (NULL);
     }

+ 25 - 0
src/lib/util/io/tests/Makefile.am

@@ -0,0 +1,25 @@
+CLEANFILES = *.gcno *.gcda
+
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+TESTS =
+if HAVE_GTEST
+TESTS += run_unittests
+run_unittests_SOURCES = run_unittests.cc
+run_unittests_SOURCES += fd_tests.cc
+run_unittests_SOURCES += fd_share_tests.cc
+
+run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
+run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/util/io/libutil_io.la
+run_unittests_LDADD += \
+	$(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+endif
+
+noinst_PROGRAMS = $(TESTS)

+ 74 - 0
src/lib/util/io/tests/fd_share_tests.cc

@@ -0,0 +1,74 @@
+// Copyright (C) 2011  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.
+
+#include "../fd.h"
+#include "../fd_share.h"
+
+#include <util/unittests/fork.h>
+
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <cstdio>
+
+using namespace isc::util::io;
+using namespace isc::util::unittests;
+
+namespace {
+
+// We test that we can transfer a pipe over other pipe
+TEST(FDShare, transfer) {
+    // Get a pipe and fork
+    int pipes[2];
+    ASSERT_NE(-1, socketpair(AF_UNIX, SOCK_STREAM, 0, pipes));
+    pid_t sender(fork());
+    ASSERT_NE(-1, sender);
+    if(sender) { // We are in parent
+        // Close the other side of pipe, we want only writible one
+        EXPECT_NE(-1, close(pipes[0]));
+        // Get a process to check data
+        int fd(0);
+        pid_t checker(check_output(&fd, "data", 4));
+        ASSERT_NE(-1, checker);
+        // Now, send the file descriptor, close it and close the pipe
+        EXPECT_NE(-1, send_fd(pipes[1], fd));
+        EXPECT_NE(-1, close(pipes[1]));
+        EXPECT_NE(-1, close(fd));
+        // Check both subprocesses ended well
+        EXPECT_TRUE(process_ok(sender));
+        EXPECT_TRUE(process_ok(checker));
+    } else { // We are in child. We do not use ASSERT here
+        // Close the write end, we only read
+        if(close(pipes[1])) {
+            exit(1);
+        }
+        // Get the file descriptor
+        int fd(recv_fd(pipes[0]));
+        if(fd == -1) {
+            exit(1);
+        }
+        // This pipe is not needed
+        if(close(pipes[0])) {
+            exit(1);
+        }
+        // Send "data" trough the received fd, close it and be done
+        if(!write_data(fd, "data", 4) || close(fd) == -1) {
+            exit(1);
+        }
+        exit(0);
+    }
+}
+
+}

+ 66 - 0
src/lib/util/io/tests/fd_tests.cc

@@ -0,0 +1,66 @@
+// Copyright (C) 2011  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.
+
+#include "../fd.h"
+
+#include <util/unittests/fork.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::util::io;
+using namespace isc::util::unittests;
+
+namespace {
+
+// Make sure the test is large enough and does not fit into one
+// read or write request
+const size_t TEST_DATA_SIZE = 8 * 1024 * 1024;
+
+class FDTest : public ::testing::Test {
+    public:
+        unsigned char *data, *buffer;
+        FDTest() :
+            // We do not care what is inside, we just need it to be the same
+            data(new unsigned char[TEST_DATA_SIZE]),
+            buffer(NULL)
+        { }
+        ~ FDTest() {
+            delete[] data;
+            delete[] buffer;
+        }
+};
+
+// Test we read what was sent
+TEST_F(FDTest, read) {
+    int read_pipe(0);
+    buffer = new unsigned char[TEST_DATA_SIZE];
+    pid_t feeder(provide_input(&read_pipe, data, TEST_DATA_SIZE));
+    ASSERT_GE(feeder, 0);
+    ssize_t received(read_data(read_pipe, buffer, TEST_DATA_SIZE));
+    EXPECT_TRUE(process_ok(feeder));
+    EXPECT_EQ(TEST_DATA_SIZE, received);
+    EXPECT_EQ(0, memcmp(data, buffer, received));
+}
+
+// Test we write the correct thing
+TEST_F(FDTest, write) {
+    int write_pipe(0);
+    pid_t checker(check_output(&write_pipe, data, TEST_DATA_SIZE));
+    ASSERT_GE(checker, 0);
+    EXPECT_TRUE(write_data(write_pipe, data, TEST_DATA_SIZE));
+    EXPECT_EQ(0, close(write_pipe));
+    EXPECT_TRUE(process_ok(checker));
+}
+
+}

+ 22 - 0
src/lib/util/io/tests/run_unittests.cc

@@ -0,0 +1,22 @@
+// Copyright (C) 2011  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.
+
+#include <gtest/gtest.h>
+
+int
+main(int argc, char *argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+
+    return RUN_ALL_TESTS();
+}

+ 9 - 0
src/lib/util/unittests/Makefile.am

@@ -0,0 +1,9 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
+AM_CXXFLAGS = $(B10_CXXFLAGS)
+
+lib_LTLIBRARIES = libutil_unittests.la
+libutil_unittests_la_SOURCES = fork.h fork.cc
+libutil_unittests_la_LIBADD = \
+	$(top_builddir)/src/lib/util/io/libutil_io.la
+
+CLEANFILES = *.gcno *.gcda

+ 5 - 0
src/lib/util/unittests/README

@@ -0,0 +1,5 @@
+This directory contains some code that is useful while writing various
+unittest code. It doesn't contain any code that would actually run in
+bind10.
+
+Because this is a test code, we do not test it explicitly.

+ 145 - 0
src/lib/util/unittests/fork.cc

@@ -0,0 +1,145 @@
+// Copyright (C) 2011  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.
+
+#include "fork.h"
+
+#include <util/io/fd.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <cerrno>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace isc::util::io;
+
+namespace {
+
+// Just a NOP function to ignore a signal but let it interrupt function.
+void no_handler(int) { }
+
+};
+
+namespace isc {
+namespace util {
+namespace unittests {
+
+bool
+process_ok(pid_t process) {
+    // Create a timeout
+    struct sigaction ignored, original;
+    memset(&ignored, 0, sizeof ignored);
+    ignored.sa_handler = no_handler;
+    if (sigaction(SIGALRM, &ignored, &original)) {
+        return false;
+    }
+    // It is long, but if everything is OK, it'll not happen
+    alarm(10);
+    int status;
+    int result(waitpid(process, &status, 0) == -1);
+    // Cancel the alarm and return the original handler
+    alarm(0);
+    if (sigaction(SIGALRM, &original, NULL)) {
+        return false;
+    }
+    // Check what we found out
+    if (result) {
+        if (errno == EINTR)
+            kill(process, SIGTERM);
+        return false;
+    }
+    return WIFEXITED(status) && WEXITSTATUS(status) == 0;
+}
+
+/*
+ * This creates a pipe, forks and feeds the pipe with given data.
+ * Used to provide the input in non-blocking/asynchronous way.
+ */
+pid_t
+provide_input(int *read_pipe, const void *input, const size_t length)
+{
+    int pipes[2];
+    if (pipe(pipes)) {
+        return -1;
+    }
+    *read_pipe = pipes[0];
+    pid_t pid(fork());
+    if (pid) { // We are in the parent
+        return pid;
+    } else { // This is in the child, just puth the data there
+        close(pipes[0]);
+        if (!write_data(pipes[1], input, length)) {
+            exit(1);
+        } else {
+            close(pipes[1]);
+            exit(0);
+        }
+    }
+}
+
+/*
+ * This creates a pipe, forks and reads the pipe and compares it
+ * with given data. Used to check output of run in asynchronous way.
+ */
+pid_t
+check_output(int *write_pipe, const void *output, const size_t length)
+{
+    int pipes[2];
+    if (pipe(pipes)) {
+        return -1;
+    }
+    *write_pipe = pipes[1];
+    pid_t pid(fork());
+    if (pid) { // We are in parent
+        close(pipes[0]);
+        return pid;
+    } else {
+        close(pipes[1]);
+        // We don't return the memory, but we're in tests and end this process
+        // right away.
+        unsigned char *buffer = new unsigned char[length + 1];
+        // Try to read one byte more to see if the output ends here
+        size_t got_length(read_data(pipes[0], buffer, length + 1));
+        bool ok(true);
+        if (got_length != length) {
+            fprintf(stderr, "Different length (expected %u, got %u)\n",
+                static_cast<unsigned>(length),
+                static_cast<unsigned>(got_length));
+            ok = false;
+        }
+        if(!ok || memcmp(buffer, output, length)) {
+            const unsigned char *output_c(static_cast<const unsigned char *>(
+                output));
+            // If they differ, print what we have
+            for(size_t i(0); i != got_length; ++ i) {
+                fprintf(stderr, "%02hhx", buffer[i]);
+            }
+            fprintf(stderr, "\n");
+            for(size_t i(0); i != length; ++ i) {
+                fprintf(stderr, "%02hhx", output_c[i]);
+            }
+            fprintf(stderr, "\n");
+            exit(1);
+        } else {
+            exit(0);
+        }
+    }
+}
+
+}
+}
+}

+ 52 - 0
src/lib/util/unittests/fork.h

@@ -0,0 +1,52 @@
+// Copyright (C) 2011  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.
+
+#ifndef __UTIL_UNITTESTS_FORK_H
+#define __UTIL_UNITTESTS_FORK_H 1
+
+#include <unistd.h>
+
+/**
+ * @file fork.h
+ * @short Help functions to fork the test case process.
+ * Various functions to fork a process and feed some data to pipe, check
+ * its output and such lives here.
+ */
+
+namespace isc {
+namespace util {
+namespace unittests {
+
+/**
+ * @short Checks that a process terminates correctly.
+ * Waits for a process to terminate (with a short timeout, this should be
+ * used whan the process is about tu terminate) and checks its exit code.
+ *
+ * @return True if the process terminates with 0, false otherwise.
+ * @param process The ID of process to wait for.
+ */
+bool
+process_ok(pid_t process);
+
+pid_t
+provide_input(int *read_pipe, const void *input, const size_t length);
+
+pid_t
+check_output(int *write_pipe, const void *output, const size_t length);
+
+} // End of the namespace
+}
+}
+
+#endif // __UTIL_UNITTESTS_FORK_H

+ 3 - 11
src/lib/xfr/Makefile.am

@@ -2,7 +2,7 @@ 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 += $(BOOST_INCLUDES)
 
-AM_CXXFLAGS = $(B10_CXXFLAGS) -Wno-strict-aliasing
+AM_CXXFLAGS = $(B10_CXXFLAGS)
 AM_CXXFLAGS += -Wno-unused-parameter # see src/lib/cc/Makefile.am
 if USE_CLANGPP
 AM_CXXFLAGS += -Wno-error
@@ -11,13 +11,5 @@ endif
 CLEANFILES = *.gcno *.gcda
 
 lib_LTLIBRARIES = libxfr.la
-libxfr_la_SOURCES = xfrout_client.h xfrout_client.cc 
-libxfr_la_SOURCES += fd_share.h fd_share.cc
-
-pyexec_LTLIBRARIES = libxfr_python.la
-# Python prefers .so, while some OSes (specifically MacOS) use a different
-# suffix for dynamic objects.  -module is necessary to work this around.
-libxfr_python_la_LDFLAGS = -module
-libxfr_python_la_SOURCES = fdshare_python.cc fd_share.cc fd_share.h
-libxfr_python_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
-libxfr_python_la_CXXFLAGS = $(AM_CXXFLAGS)
+libxfr_la_SOURCES = xfrout_client.h xfrout_client.cc
+libxfr_la_LIBADD = $(top_builddir)/src/lib/util/io/libutil_io.la

+ 0 - 42
src/lib/xfr/fd_share.h

@@ -1,42 +0,0 @@
-// 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.
-
-#ifndef FD_SHARE_H_
-#define FD_SHARE_H_
-
-namespace isc {
-namespace xfr {
-
-/// Failed to receive xfr socket descriptor "fd" on unix domain socket 'sock'
-const int XFR_FD_RECEIVE_FAIL = -2;
-
-// Receive socket descriptor on unix domain socket 'sock'.
-// Returned value is the socket descriptor received.
-// Returned XFR_FD_RECEIVE_FAIL if failed to receive xfr socket descriptor
-// Errors are indicated by a return value of -1.
-int recv_fd(const int sock);
-
-// Send socket descriptor "fd" to server over unix domain socket 'sock',
-// the connection from socket 'sock' to unix domain server should be established first.
-// Errors are indicated by a return value of -1.
-int send_fd(const int sock, const int fd);
-
-} // End for namespace xfr
-} // End for namespace isc
-
-#endif
-
-// Local Variables:
-// mode: c++
-// End:

+ 3 - 2
src/lib/xfr/xfrout_client.cc

@@ -20,10 +20,11 @@
 #include <unistd.h>
 #include <asio.hpp>
 
-#include <xfr/fd_share.h>
+#include <util/io/fd_share.h>
 #include <xfr/xfrout_client.h>
 
 using namespace std;
+using namespace isc::util::io;
 using asio::local::stream_protocol;
 
 namespace isc {
@@ -72,7 +73,7 @@ XfroutClient::sendXfroutRequestInfo(const int tcp_sock,
                                     const void* const msg_data,
                                     const uint16_t msg_len)
 {
-    if (-1 == send_fd(impl_->socket_.native(), tcp_sock)) {
+    if (send_fd(impl_->socket_.native(), tcp_sock) < 0) {
         isc_throw(XfroutError,
                   "Failed to send the socket file descriptor "
                   "to xfrout module");

+ 27 - 0
tools/query_cmp/README

@@ -0,0 +1,27 @@
+This is a tool to compare two DNS server's response to query.
+
+DIRECTORY STRUCTURE
+
+zonefile
+	The file under this directory is for the testee servers
+	to load before running the test, containing various types 
+	of RRs in the test cases. It is in bind9's format. One 
+	file is signed while the other is not, which you can choose.
+
+queries
+	The files under this directory are the input of the test,
+	involving various types of query cases.
+
+src
+	The scripts of this test.
+	It uses the dns python binding interface of bind10 from the 
+	source tree, so src/lib/dns/python/.libs must be added to 
+	PYTHONPATH environment variable ahead of running the tests.
+
+RUNNING
+
+e.g.
+cd src
+./query_two_server.py -u -f ../queries/dquery01 -s 10.10.1.1 -p 30000 -t 10.10.10.2 -q 30002 > bind10test_normal
+
+./query_two_server.py --help' for more details

+ 394 - 0
tools/query_cmp/queries/dquery01

@@ -0,0 +1,394 @@
+# Fields Description
+#
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT QNAME QTYPE QCLASS <answer> <authority> <additional>
+#  <answer>     := <rr1> .. <rrN>
+#  <rr>         := NAME TYPE CLASS TTL RDLENGTH <rdata>
+#  <rdata>      := ADDRESS |
+#                  NSDNAME |
+#                  MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |
+#                  ...
+#  <authority>  := <rr1> .. <rrN>
+#  <additional> := <rr1> .. <rrN>
+#
+# 
+#
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)
+# <query> ::= <header> <question>
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>
+#              <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>
+# <question> ::= <QNAME> <QTYPE> <QCLASS>
+#
+# <response> ::= <header> <question> <answer> <authority> <additional>
+# <answer> ::= <rrset>
+# <authority> ::= <rrset>
+# <additional> ::= <rrset>
+# <rrset> ::= { <rr> }
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>
+# <name> ::= <subdomain> | ""
+# <subdomain> ::= <label> | <subdomain> "." <label>
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
+# <let-dig-hyp> ::= <let-dig> | "-"
+# <let-dig> ::= <letter> | <digit>
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"
+# <digit> ::= "0" | .. | "9"
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | ..
+# <class> ::= IN | CH | HS | CS
+# <ttl> ::= <digit> | { <digit> }
+# <rdlength> ::= <digit> | { <digit> }
+# <rdata> ::= <address> |
+#             <nsdname> |
+#             <cname> |
+#             <preference> <exchange> |
+#             <ptrdname> |
+#             ...
+
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+3 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+4 0 0 0 0 1 0 0 0 0 0 1 0 0 0 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+6 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+7 0 0 0 0 1 0 0 0 0 0 1 0 0 0 B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a-record.example.com A IN
+
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+13 0 0 0 0 1 0 0 0 0 0 1 0 0 0 NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+14 0 0 0 0 1 0 0 0 0 0 1 0 0 0 N.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.multiple-type-ns-record.example.com a IN
+
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.example.com ANY IN
+
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.example.com ANY IN
+
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C10.example.com ANY IN
+
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C36.example.com ANY IN
+
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c.Example.coM ANY IN
+
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+
+44 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com A IN
+45 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com CNAME IN
+46 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com MX IN
+47 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA3.example.com ANY IN
+
+48 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com A IN
+49 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com CNAME IN
+50 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com MX IN
+51 0 0 0 0 1 0 0 0 0 0 1 0 0 0 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA1.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA2.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA4.example.com ANY IN
+
+52 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com A IN
+53 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com CNAME IN
+54 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com MX IN
+55 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.example.com ANY IN
+
+56 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com A IN
+57 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com CNAME IN
+58 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com MX IN
+59 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.1.example.com ANY IN
+
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 C12.name1.cn A IN
+
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com ANY IN
+
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example1.com ANY IN
+
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example2.com ANY IN
+
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example3.com ANY IN
+
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example4.com ANY IN
+
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example13.com ANY IN
+
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com NS IN
+
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example9.com ANY IN
+
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.noexist SOA IN
+
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+105 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com PTR IN
+106 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a-record.example.com PTR IN
+
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+113 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com MX IN
+114 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-mx-record.example.com MX IN
+
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+123 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com TXT IN
+124 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-txt-record.example.com TXT IN
+
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+133 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com AAAA IN
+134 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-aaaa-record.example.com AAAA IN
+
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+143 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com NAPTR IN
+144 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 6.8.e164.arpa NAPTR IN
+
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#153 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A6 IN
+#154 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-a6-record.example.com A6 IN
+
+# case 160-163
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.A.example.com ANY IN
+
+# case 164-167
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.exAmple.com ANY IN
+
+# case 168-171
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+
+# case 172-175
+172 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com DNAME IN
+173 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com ANY IN
+174 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+175 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com ANY IN
+
+# case 176-179
+176 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com DNAME IN
+177 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com ANY IN
+178 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com A IN
+179 0 0 0 0 1 0 0 0 0 0 1 0 0 0 D.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.example.com ANY IN
+
+# case 180-195
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.a.b.d1.example.com mx IN
+
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d45.example.com any IN
+
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.d1.example.com a IN
+
+# case 200-205
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+203 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com WKS IN
+204 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-wks-record.example.com WKS IN
+
+# case 210-215
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+213 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com HINFO IN
+214 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-hinfo-record.example.com HINFO IN
+
+# case 220-225
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+223 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com MINFO IN
+224 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-minfo-record.example.com MINFO IN
+
+# case 230-235
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+233 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com NSAP IN
+234 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-nsap-record.example.com NSAP IN
+
+# case 240-245
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+243 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com PX IN
+244 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-px-record.example.com PX IN
+
+# case 250-255
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+253 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com LOC IN
+254 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-loc-record.example.com LOC IN
+
+# case 260-265
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+263 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SRV IN
+264 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-srv-record.example.com SRV IN
+
+# case 270-275
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+273 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com KX IN
+274 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-kx-record.example.com KX IN
+
+# case 280-285
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+283 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com CERT IN
+284 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-cert-record.example.com CERT IN
+
+# case 290-295
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+293 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com APL IN
+294 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-apl-record.example.com APL IN
+
+# case 300-305
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+303 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SSHFP IN
+304 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-sshfp-record.example.com SSHFP IN
+
+# case 310-315
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+313 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com IPSECKEY IN
+314 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-ipseckey-record.example.com IPSECKEY IN
+
+# case 320-325
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#323 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com DHCID IN
+#324 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-dhcid-record.example.com DHCID IN
+
+# case 330-335
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+333 0 0 0 0 1 0 0 0 0 0 1 0 0 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC.DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com SPF IN
+334 0 0 0 0 1 0 0 0 0 0 1 0 0 0 A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.G.H.I.J.K.L.M.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 multiple-type-spf-record.example.com SPF IN
+
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 9.example.com A IN
+
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 www.sub-dname.example.com A IN
+
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 type-cname-answer.toobigudp.com TXT IN
+
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 authors.bind txt CH

+ 316 - 0
tools/query_cmp/queries/dquery01_no-type

@@ -0,0 +1,316 @@
+# Fields Description             
+#               
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT testa.no-type.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT testa.no-type.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>          
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>       
+# <rdata> := ADDRESS |           
+# NSDNAME |             
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |       
+# ...              
+# <authority> := <rr1> .. <rrN>          
+# <additional> := <rr1> .. <rrN>          
+#               
+#               
+#               
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)           
+# <query> ::= <header> <question>           
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>  
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>           
+# <question> ::= <QNAME> <QTYPE> <QCLASS>          
+#               
+# <response> ::= <header> <question> <answer> <authority> <additional>        
+# <answer> ::= <rrset>            
+# <authority> ::= <rrset>            
+# <additional> ::= <rrset>            
+# <rrset> ::= { <rr> }          
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>       
+# <name> ::= <subdomain> | ""          
+# <subdomain> ::= <label> | <subdomain> "." <label>        
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]      
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>         
+# <let-dig-hyp> ::= <let-dig> | "-"          
+# <let-dig> ::= <letter> | <digit>          
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"  
+# <digit> ::= "0" | .. | "9"        
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | testa.no-type...  
+# <class> ::= IN | CH | HS | CS      
+# <ttl> ::= <digit> | { <digit> }        
+# <rdlength> ::= <digit> | { <digit> }        
+# <rdata> ::= <address> |           
+# <nsdname> |             
+# <cname> |             
+# <preference> <exchange> |            
+# <ptrdname> |             
+# ...              
+               
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a-record.example.com A IN
+               
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.multiple-type-ns-record.example.com a IN
+               
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C.example.com ANY IN
+               
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.example.com ANY IN
+               
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C10.example.com ANY IN
+               
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C36.example.com ANY IN
+               
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c.Example.coM ANY IN
+               
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+               
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.C12.name1.cn A IN
+               
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com ANY IN
+               
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example1.com ANY IN
+               
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example2.com ANY IN
+               
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example3.com ANY IN
+               
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example4.com ANY IN
+               
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example13.com ANY IN
+               
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com NS IN
+               
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example9.com ANY IN
+               
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.noexist SOA IN
+               
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a-record.example.com PTR IN
+               
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-mx-record.example.com MX IN
+               
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-txt-record.example.com TXT IN
+               
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-aaaa-record.example.com AAAA IN
+               
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.6.8.e164.arpa NAPTR IN
+               
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-a6-record.example.com A6 IN
+               
+# case 160-163             
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.A.example.com ANY IN
+               
+# case 164-167             
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.exAmple.com ANY IN
+               
+# case 168-171             
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+               
+# case 180-195             
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.a.b.d1.example.com mx IN
+               
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d45.example.com any IN
+               
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.d1.example.com a IN
+               
+# case 200-205             
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-wks-record.example.com WKS IN
+               
+# case 210-215             
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-hinfo-record.example.com HINFO IN
+               
+# case 220-225             
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-minfo-record.example.com MINFO IN
+               
+# case 230-235             
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-nsap-record.example.com NSAP IN
+               
+# case 240-245             
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-px-record.example.com PX IN
+               
+# case 250-255             
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-loc-record.example.com LOC IN
+               
+# case 260-265             
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-srv-record.example.com SRV IN
+               
+# case 270-275             
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-kx-record.example.com KX IN
+               
+# case 280-285             
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-cert-record.example.com CERT IN
+               
+# case 290-295             
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-apl-record.example.com APL IN
+               
+# case 300-305             
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-sshfp-record.example.com SSHFP IN
+               
+# case 310-315             
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-ipseckey-record.example.com IPSECKEY IN
+               
+# case 320-325             
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-dhcid-record.example.com DHCID IN
+               
+# case 330-335             
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.multiple-type-spf-record.example.com SPF IN
+               
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.9.example.com A IN
+               
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.www.sub-dname.example.com A IN
+               
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.type-cname-answer.toobigudp.com TXT IN
+               
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 testa.no-type.authors.bind txt CH

+ 317 - 0
tools/query_cmp/queries/dquery01_non-terminal

@@ -0,0 +1,317 @@
+# Fields Description             
+#               
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT non-terminal.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT non-terminal.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>          
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>       
+# <rdata> := ADDRESS |           
+# NSDNAME |             
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |       
+# ...              
+# <authority> := <rr1> .. <rrN>          
+# <additional> := <rr1> .. <rrN>          
+#               
+#               
+#               
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)           
+# <query> ::= <header> <question>           
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>  
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>           
+# <question> ::= <QNAME> <QTYPE> <QCLASS>          
+#               
+# <response> ::= <header> <question> <answer> <authority> <additional>        
+# <answer> ::= <rrset>            
+# <authority> ::= <rrset>            
+# <additional> ::= <rrset>            
+# <rrset> ::= { <rr> }          
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>       
+# <name> ::= <subdomain> | ""          
+# <subdomain> ::= <label> | <subdomain> "." <label>        
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]      
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>         
+# <let-dig-hyp> ::= <let-dig> | "-"          
+# <let-dig> ::= <letter> | <digit>          
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"  
+# <digit> ::= "0" | .. | "9"        
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | non-terminal...  
+# <class> ::= IN | CH | HS | CS      
+# <ttl> ::= <digit> | { <digit> }        
+# <rdlength> ::= <digit> | { <digit> }        
+# <rdata> ::= <address> |           
+# <nsdname> |             
+# <cname> |             
+# <preference> <exchange> |            
+# <ptrdname> |             
+# ...              
+               
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a-record.example.com A IN
+               
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.multiple-type-ns-record.example.com a IN
+               
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C.example.com ANY IN
+               
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.example.com ANY IN
+               
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C10.example.com ANY IN
+               
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C36.example.com ANY IN
+               
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c.Example.coM ANY IN
+               
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+               
+               
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.C12.name1.cn A IN
+               
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com ANY IN
+               
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example1.com ANY IN
+               
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example2.com ANY IN
+               
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example3.com ANY IN
+               
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example4.com ANY IN
+               
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example13.com ANY IN
+               
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com NS IN
+               
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example9.com ANY IN
+               
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.noexist SOA IN
+               
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a-record.example.com PTR IN
+               
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-mx-record.example.com MX IN
+               
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-txt-record.example.com TXT IN
+               
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-aaaa-record.example.com AAAA IN
+               
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.6.8.e164.arpa NAPTR IN
+               
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-a6-record.example.com A6 IN
+               
+# case 160-163             
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.A.example.com ANY IN
+               
+# case 164-167             
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.exAmple.com ANY IN
+               
+# case 168-171             
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+               
+# case 180-195             
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.a.b.d1.example.com mx IN
+               
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d45.example.com any IN
+               
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.d1.example.com a IN
+               
+# case 200-205             
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-wks-record.example.com WKS IN
+               
+# case 210-215             
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-hinfo-record.example.com HINFO IN
+               
+# case 220-225             
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-minfo-record.example.com MINFO IN
+               
+# case 230-235             
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-nsap-record.example.com NSAP IN
+               
+# case 240-245             
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-px-record.example.com PX IN
+               
+# case 250-255             
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-loc-record.example.com LOC IN
+               
+# case 260-265             
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-srv-record.example.com SRV IN
+               
+# case 270-275             
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-kx-record.example.com KX IN
+               
+# case 280-285             
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-cert-record.example.com CERT IN
+               
+# case 290-295             
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-apl-record.example.com APL IN
+               
+# case 300-305             
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-sshfp-record.example.com SSHFP IN
+               
+# case 310-315             
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-ipseckey-record.example.com IPSECKEY IN
+               
+# case 320-325             
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-dhcid-record.example.com DHCID IN
+               
+# case 330-335             
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.multiple-type-spf-record.example.com SPF IN
+               
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.9.example.com A IN
+               
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.www.sub-dname.example.com A IN
+               
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.type-cname-answer.toobigudp.com TXT IN
+               
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 non-terminal.authors.bind txt CH

+ 316 - 0
tools/query_cmp/queries/dquery01_nxdomain

@@ -0,0 +1,316 @@
+# Fields Description             
+#               
+#query:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT nxdomain.QNAME QTYPE QCLASS
+#response:ID QR OPCODE AA TC RD RA Z AD CD RCODE QDCOUNT ANCOUNT NSCOUNT ARCOUNT nxdomain.QNAME QTYPE QCLASS
+# <answer> := <rr1> .. <rrN>          
+# <rr> := NAME TYPE CLASS TTL RDLENGTH <rdata>       
+# <rdata> := ADDRESS |           
+# NSDNAME |             
+# MNAME RNAME SERIAL REFRESH RETRY EXPIRE MINIMUM |       
+# ...              
+# <authority> := <rr1> .. <rrN>          
+# <additional> := <rr1> .. <rrN>          
+#               
+#               
+#               
+# Description in BNF (http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)           
+# <query> ::= <header> <question>           
+# <header> ::= <ID> <QR> <OPCODE> <AA> <TC> <RD> <RA> <Z> <AD> <CD> <RCODE>  
+# <QDCOUNT> <ANCOUNT> <NSCOUNT> <ARCOUNT>           
+# <question> ::= <QNAME> <QTYPE> <QCLASS>          
+#               
+# <response> ::= <header> <question> <answer> <authority> <additional>        
+# <answer> ::= <rrset>            
+# <authority> ::= <rrset>            
+# <additional> ::= <rrset>            
+# <rrset> ::= { <rr> }          
+# <rr> ::= <name> <type> <class> <ttl> <rdlength> <rdata>       
+# <name> ::= <subdomain> | ""          
+# <subdomain> ::= <label> | <subdomain> "." <label>        
+# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]      
+# <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>         
+# <let-dig-hyp> ::= <let-dig> | "-"          
+# <let-dig> ::= <letter> | <digit>          
+# <letter> ::= "a" | .. | "z" | "A" | .. | "Z"  
+# <digit> ::= "0" | .. | "9"        
+# <type> ::= A | NS | CNAME | SOA | PTR | MX | nxdomain...  
+# <class> ::= IN | CH | HS | CS      
+# <ttl> ::= <digit> | { <digit> }        
+# <rdlength> ::= <digit> | { <digit> }        
+# <rdata> ::= <address> |           
+# <nsdname> |             
+# <cname> |             
+# <preference> <exchange> |            
+# <ptrdname> |             
+# ...              
+               
+0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com A IN
+1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com A IN
+2 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+5 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE.example.com A IN
+8 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.M.example.com A IN
+9 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a-record.example.com A IN
+               
+10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.NS.example.com A IN
+11 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.nS.example.com A IN
+12 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+15 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.multiple-type-ns-record.example.com a IN
+               
+20 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com A IN
+21 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com CNAME IN
+22 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com MX IN
+23 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C.example.com ANY IN
+               
+24 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com A IN
+25 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com CNAME IN
+26 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com MX IN
+27 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.example.com ANY IN
+               
+28 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com A IN
+29 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com CNAME IN
+30 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com MX IN
+31 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C10.example.com ANY IN
+               
+32 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com A IN
+33 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com CNAME IN
+34 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com MX IN
+35 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C36.example.com ANY IN
+               
+36 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM A IN
+37 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM CNAME IN
+38 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM MX IN
+39 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c.Example.coM ANY IN
+               
+40 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com A IN
+41 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com CNAME IN
+42 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com MX IN
+43 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCA.example.com ANY IN
+               
+60 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C0.name1.cn A IN
+61 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.C12.name1.cn A IN
+               
+70 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com SOA IN
+71 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com ANY IN
+               
+72 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com SOA IN
+73 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com A IN
+74 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com NS IN
+75 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example1.com ANY IN
+               
+76 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com SOA IN
+77 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com A IN
+78 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com NS IN
+79 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example2.com ANY IN
+               
+80 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com SOA IN
+81 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com A IN
+82 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com NS IN
+83 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example3.com ANY IN
+               
+84 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com SOA IN
+85 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com A IN
+86 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com NS IN
+87 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example4.com ANY IN
+               
+88 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com SOA IN
+89 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com A IN
+90 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com NS IN
+91 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example13.com ANY IN
+               
+92 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com A IN
+93 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com ANY IN
+94 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com NS IN
+               
+95 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com SOA IN
+96 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com ns IN
+97 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example9.com ANY IN
+               
+98 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.example.com SOA IN
+99 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.noexist SOA IN
+               
+100 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.1.10.10.in-addr.arpA PTR IN
+101 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com PTR IN
+102 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.1.10.10.in-addr.arpa PTR IN
+103 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.examPle.com PTR IN
+104 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com PTR IN
+107 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.1.2.168.192.in-addr.arpa PTR IN
+108 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a-record.example.com PTR IN
+               
+110 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com MX IN
+111 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com MX IN
+112 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com MX IN
+115 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-mx-record.example.com MX IN
+               
+120 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com TXT IN
+121 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com TXT IN
+122 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com TXT IN
+125 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-txt-record.example.com TXT IN
+               
+130 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com AAAA IN
+131 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com AAAA IN
+132 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com AAAA IN
+135 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-aaaa-record.example.com AAAA IN
+               
+140 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com NAPTR IN
+141 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com NAPTR IN
+142 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NAPTR IN
+145 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.2.1.2.1.5.5.5.0.7.7.1.e164.arpa NAPTR IN
+146 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.b.e164.arpa NAPTR IN
+147 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.6.8.e164.arpa NAPTR IN
+               
+#150 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com A6 IN
+#151 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com A6 IN
+#152 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A6 IN
+#155 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-a6-record.example.com A6 IN
+               
+# case 160-163             
+160 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com DNAME IN
+161 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com ANY IN
+162 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.A.example.com A IN
+163 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.A.example.com ANY IN
+               
+# case 164-167             
+164 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.exAmple.com DNAME IN
+165 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.exAmple.com ANY IN
+166 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.exAmple.com A IN
+167 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.exAmple.com ANY IN
+               
+# case 168-171             
+168 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DNAME IN
+169 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+170 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com A IN
+171 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com ANY IN
+               
+# case 180-195             
+180 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d0.example.com a IN
+181 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d1.example.com a IN
+182 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d2.example.com a IN
+183 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d4.example.com a IN
+184 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d5.example.com a IN
+185 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.ns.d0.example.com a IN
+186 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.b.d1.example.com a IN
+187 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.a.b.d1.example.com mx IN
+               
+188 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d10.example.com a IN
+189 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d20.example.com a IN
+190 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d30.example.com a IN
+191 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d40.example.com a IN
+192 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d50.example.com a IN
+193 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.c45.example.com any IN
+194 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.d45.example.com any IN
+195 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.noexist.d45.example.com any IN
+196 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d45.example.com any IN
+               
+197 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.d72.example.com a IN
+198 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.d1.example.com a IN
+               
+# case 200-205             
+200 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com WKS IN
+201 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com WKS IN
+202 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com WKS IN
+205 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-wks-record.example.com WKS IN
+               
+# case 210-215             
+210 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com HINFO IN
+211 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com HINFO IN
+212 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com HINFO IN
+215 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-hinfo-record.example.com HINFO IN
+               
+# case 220-225             
+220 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com MINFO IN
+221 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com MINFO IN
+222 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com MINFO IN
+225 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-minfo-record.example.com MINFO IN
+               
+# case 230-235             
+230 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com NSAP IN
+231 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com NSAP IN
+232 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com NSAP IN
+235 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-nsap-record.example.com NSAP IN
+               
+# case 240-245             
+240 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com PX IN
+241 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com PX IN
+242 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com PX IN
+245 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-px-record.example.com PX IN
+               
+# case 250-255             
+250 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com LOC IN
+251 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com LOC IN
+252 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com LOC IN
+255 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-loc-record.example.com LOC IN
+               
+# case 260-265             
+260 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SRV IN
+261 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SRV IN
+262 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SRV IN
+265 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-srv-record.example.com SRV IN
+               
+# case 270-275             
+270 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com KX IN
+271 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com KX IN
+272 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com KX IN
+275 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-kx-record.example.com KX IN
+               
+# case 280-285             
+280 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com CERT IN
+281 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com CERT IN
+282 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com CERT IN
+285 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-cert-record.example.com CERT IN
+               
+# case 290-295             
+290 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com APL IN
+291 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com APL IN
+292 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com APL IN
+295 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-apl-record.example.com APL IN
+               
+# case 300-305             
+300 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SSHFP IN
+301 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SSHFP IN
+302 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SSHFP IN
+305 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-sshfp-record.example.com SSHFP IN
+               
+# case 310-315             
+310 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com IPSECKEY IN
+311 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com IPSECKEY IN
+312 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com IPSECKEY IN
+315 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-ipseckey-record.example.com IPSECKEY IN
+               
+# case 320-325             
+#320 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com DHCID IN
+#321 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com DHCID IN
+#322 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com DHCID IN
+#325 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-dhcid-record.example.com DHCID IN
+               
+# case 330-335             
+330 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.A.example.com SPF IN
+331 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.a.example.com SPF IN
+332 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.example.com SPF IN
+335 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.multiple-type-spf-record.example.com SPF IN
+               
+360 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.0.example.com A IN
+361 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.9.example.com A IN
+               
+370 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.sub-cname.example.com A IN
+371 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.www.sub-dname.example.com A IN
+               
+381 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-a-answer.toobigudp.com A IN
+382 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-a-authority.toobigudp.com A IN
+383 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.toobigudp.com NS IN
+384 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-txt-answer.toobigudp.com TXT IN
+385 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-txt-authority.toobigudp.com TXT IN
+386 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-cname-answer.toobigudp.com A IN
+387 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.type-cname-answer.toobigudp.com TXT IN
+               
+390 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com DNSKEY IN
+391 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com RRSIG IN
+392 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com NSEC IN
+393 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.example.com DS IN
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.authors.bind txt CH
+#0x1000 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.version.bind txt CH
+#0x1001 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.hostname.bind txt CH
+#0x1002 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.id.server txt CH
+#0x1003 0 0 0 0 1 0 0 0 0 0 1 0 0 0 nxdomain.authors.bind txt CH

+ 285 - 0
tools/query_cmp/src/lib/compare_rrset.py

@@ -0,0 +1,285 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011  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.
+
+import struct
+from pydnspp import *
+
+# Some position parameters used in the formatted output report.
+POS_TOTAL = 80
+POS_TITLE = 14
+POS_LEFT = int((POS_TOTAL - POS_TITLE) / 2)
+
+def get_header_field(msg):
+	header = {}
+	header['id'] = msg.get_qid()
+	header['qr'] = msg.get_header_flag(Message.HEADERFLAG_QR)
+	header['opcode'] = msg.get_opcode()
+	header['aa'] = msg.get_header_flag(Message.HEADERFLAG_AA)
+	header['tc'] = msg.get_header_flag(Message.HEADERFLAG_TC)
+	header['rd'] = msg.get_header_flag(Message.HEADERFLAG_RD)
+	header['ra'] = msg.get_header_flag(Message.HEADERFLAG_RA)
+	header['ad'] = msg.get_header_flag(Message.HEADERFLAG_AD)
+	header['cd'] = msg.get_header_flag(Message.HEADERFLAG_CD)
+	#header['rcode'] = dns.rcode.from_flags(msg.flags, msg.ednsflags)
+	header['rcode'] = msg.get_rcode()	
+
+	header['qdcount'] = msg.get_rr_count(Message.SECTION_QUESTION)
+	header['ancount'] = msg.get_rr_count(Message.SECTION_ANSWER)
+	header['nscount'] = msg.get_rr_count(Message.SECTION_AUTHORITY)
+	header['arcount'] = msg.get_rr_count(Message.SECTION_ADDITIONAL)
+
+	return header
+
+def header_cmp(buf, msg1, msg2, diff):
+	""" Compare the header of msg1 and msg2. 
+
+	@param buf: the formatted difference for output. 
+	@type buf: dict
+	@param diff: the key is each flag in the header, the value is 
+		     True for different and False for same
+	@type diff: dict
+	"""
+	
+	header1 = get_header_field(msg1)
+	header2 = get_header_field(msg2)
+
+	list = ['id', 'qr', 'opcode', 'aa', 'tc', 'rd', \
+		'ra', 'ad', 'cd', 'rcode', 'qdcount', 'ancount', \
+		'nscount', 'arcount']
+
+	for header in list:
+		diff[header] = header1[header] != header2[header]
+		
+	buf['header'] = ''
+	for key in list:
+		if diff[key]:
+			buf['header'] = buf['header'] + \
+				'%-*s%-*s%-*s\n' % (POS_TITLE, key, \
+				POS_LEFT, header1[key], POS_LEFT, \
+				header2[key])
+
+	for key in diff.keys():
+		if diff[key]: return(False)
+
+	return(True)
+
+
+def output(sect, buf, rrset, isleft):
+	""" Format and return the rrset according to which section 
+		and which message it belongs to. 
+
+	@param sect: section name
+	@type sect: string
+	@param buf: passed by parameter, to store the formatted string
+	@param buf: dict
+	@param rrset: the rrset to be formatted
+	@type rrset: RRset 
+	@param isleft: to be compared, the report has the content corresponding to 
+			the 1st message printed on the left, while the one corresponding
+			to the 2nd message on the right. This is a flag to which one it is.
+	@type isleft: BOOL
+	"""
+
+	if not sect in buf:
+		buf[sect] = ''
+	if sect == 'question':
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'name')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * POS_LEFT
+		buf[sect] = buf[sect] + rrset.get_name().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'class')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * POS_LEFT
+		buf[sect] = buf[sect] + rrset.get_class().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'type')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * POS_LEFT
+		buf[sect] = buf[sect] + rrset.get_type().to_text() + "\n"
+
+	else:
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'ttl')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+		buf[sect] = buf[sect] + rrset.get_ttl().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'name')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+		buf[sect] = buf[sect] + rrset.get_name().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'class')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+		buf[sect] = buf[sect] + rrset.get_class().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'type')
+		if not isleft:
+			buf[sect] = buf[sect] + ' ' * int(POS_LEFT)
+		buf[sect] = buf[sect] + rrset.get_type().to_text() + "\n"
+
+		buf[sect] = buf[sect] + '%-*s' % (POS_TITLE, 'rdata')
+
+		i = 0
+		rdata = rrset.get_rdata()
+		for item in rdata:
+			if i > 0:
+                                buf[sect] = buf[sect] + ' ' * POS_TITLE
+			if not isleft:
+				buf[sect] = buf[sect] + ' ' * POS_LEFT
+			buf[sect] = buf[sect] + item.to_text() + "\n"
+			i = i + 1
+
+	buf[sect] = buf[sect] + "\n"
+
+def array_cmp(sectname, buf, rlist1, rlist2):
+	""" Compare each entry of the question section of rlist1 and rlist2.
+	    Compare each RRset of the sectname section (can be answer, authority, 
+	    additional) of rlist1 and rlist2.
+	    
+	@param buf: store the formatted output of difference
+	@type: dict
+	"""
+
+	diff_flag = True
+	while len(rlist1) > 0:
+		rr1 = rlist1.pop()
+		find2 = False
+		for rr2 in rlist2:
+			if sectname == 'question':
+				res = question_cmp(rr1, rr2)
+			else:
+				res = rr_cmp(rr1, rr2)
+			if res:
+				find2 = True
+				rlist2.remove(rr2)
+				break
+		if not find2:
+			output(sectname, buf, rr1, True)
+			diff_flag = False
+
+	while len(rlist2) > 0:
+		rr2 = rlist2.pop()
+		output(sectname, buf, rr2, False)
+		diff_flag = False
+	return(diff_flag)
+
+def question_cmp(rra, rrb):
+	if rra.get_name() != rrb.get_name(): return(False)
+	if rra.get_class() != rrb.get_class(): return(False)
+	if rra.get_type() != rrb.get_type(): return(False)
+	return(True)
+
+def rr_cmp(rra, rrb):
+	""" Compare two rrsets: rra and rrb """
+
+	if rra.get_name() != rrb.get_name(): return(False)
+	if rra.get_class() != rrb.get_class(): return(False)
+	if rra.get_type() != rrb.get_type(): return(False)
+	if rra.get_ttl() != rrb.get_ttl(): return(False)
+	rdata_a = rra.get_rdata()
+	rdata_b = rrb.get_rdata()
+	rdata_al = len(rdata_a)
+	rdata_bl = len(rdata_b)
+
+	if rdata_al != rdata_bl: 
+		return(False)
+
+	cmp_flag = False
+	# Iterate rdata in rrset a, find if there is same rdata in rrset b
+	for ra in rdata_a:
+		for rb in rdata_b:
+			if ra.to_text() == rb.to_text():
+				cmp_flag = True
+				rdata_b.remove(rb)
+				break
+		if not cmp_flag:
+			break
+	return(cmp_flag)
+
+def resp_casecmp(msg1, msg2, num):
+	""" Compare two response message, and print the different part
+	    in formatted report. 
+
+	@param msg1: 1st response message
+	@type msg1: Message
+	@param msg2: 2nd response message
+        @type msg2: Message
+	@param num: the id of the query case in the 1st column of the input file.
+		    Used by output report to locate the specified query case. 
+	@type num: int
+	"""
+
+	diff = {}
+	buf = {}
+
+	query = msg1.get_question()[0]
+
+	res_hdr = header_cmp(buf, msg1, msg2, diff)
+	res_ques = array_cmp('question', buf, \
+				msg1.get_question(), msg2.get_question())
+	res_ans = array_cmp('answer', buf, \
+				msg1.get_section(Message.SECTION_ANSWER), \
+				msg2.get_section(Message.SECTION_ANSWER))
+	res_auth = array_cmp('authority', buf, \
+				msg1.get_section(Message.SECTION_AUTHORITY), \
+				msg2.get_section(Message.SECTION_AUTHORITY))
+	res_addi = array_cmp('additional', buf, \
+				msg1.get_section(Message.SECTION_ADDITIONAL), \
+				msg2.get_section(Message.SECTION_ADDITIONAL))
+	
+	# If there are any differnt comparisons in the sections above, print the details
+	# contained in buf formattedly.
+	if not res_hdr or not res_ques or not res_ans or not res_auth or not res_addi:
+		print('=' * 30, '  BEGIN QUERY %s  ' % num, '=' * 30, sep='')
+		print('%-*s%-*s%-*s' % (POS_TITLE, '', int(POS_LEFT), 'SERVER1', \
+			POS_TOTAL - POS_TITLE, 'SERVER2'))
+		print('-' * 80)
+		print('Query:  ', query.to_text(), sep='')
+		print('-' * 80)
+
+		if not res_hdr:
+			print(buf['header'])
+			print('-' * 80)
+
+		if not res_ques:
+			print("QUESTION")
+			print('-' * 80)
+			print(buf['question'])
+
+		if not res_ans:
+			print("ANSWER")
+			print('-' * 80)
+			print(buf['answer'])
+
+		if not res_auth:
+			print("AUTHORITY")
+			print('-' * 80)
+			print(buf['authority'])
+
+		if not res_addi:
+			print("ADDITIONAL")
+			print('-' * 80)
+			print(buf['additional'])
+
+		print('=' * 30, '   END QUERY %s   ' % num, '=' * 30, sep='') 
+		print("\n\n")
+
+		return False
+
+	return True
+

+ 284 - 0
tools/query_cmp/src/lib/handledns.py

@@ -0,0 +1,284 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011  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.
+
+import errno
+import sys
+import select
+import socket
+import struct
+import time
+
+from pydnspp import *
+
+RECV_BUFSIZE = 65536
+	
+def _wait_for(ir, iw, ix, expiration):
+	done = False
+	while not done:
+		if expiration is None:
+			timeout = None
+		else:
+			timeout = expiration - time.time()
+			if timeout <= 0.0:
+				raise socket.timeout
+		try:
+			if timeout is None:
+				(r,w,x) = select.select(ir,iw,ix)
+			else:
+				(r,w,x) = select.select(ir,iw,ix,timeout)
+		except select.error as e:
+			if e.args[0] != errno.EINTR:
+				raise e
+		else:
+			done = True
+			if len(r) == 0 and len(w) == 0 and len(x) == 0:
+				raise socket.timeout
+
+def _wait_for_readable(s,expiration):
+	_wait_for([s],[],[s],expiration)
+
+def _compute_expiration(timeout):
+	if timeout is None:
+		return None
+	else:
+		return time.time() + timeout
+
+def _send_udp(q, where, timeout=None, port=53, source=None, source_port=0):
+	""" Return the response obtained after sending a query via UDP. 
+	    Refered to dnspython source code. """
+
+	qwire = MessageRenderer()
+	q.to_wire(qwire)      
+	if source is not None:
+		source = (source, source_port)
+	
+	udpCliSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
+
+	expiration = _compute_expiration(timeout)
+	if source is not None:
+		udpCliSock.bind(source)
+
+	dest = (where, port)
+	udpCliSock.sendto(qwire.get_data(), dest)
+
+	while True:
+		_wait_for_readable(udpCliSock, expiration)
+		rwire, r_addr = udpCliSock.recvfrom(RECV_BUFSIZE)
+		if dest[0] == r_addr[0] and dest[1:] == r_addr[1:]:
+			break
+		else:
+			sys.stderr.write('Got a respose from: %s instead of %s\n' % (r_addr, dest))
+
+	udpCliSock.close()
+
+	resp = Message(Message.PARSE)
+	resp.from_wire(rwire)
+
+	return resp 
+	
+def _connect(s, address):
+	try:
+		s.connect(address)
+	except socket.error as msg:
+		(exctype,value) = sys.exc_info()[:2]
+		if value.errno != errno.EINPROGRESS and \
+			value.errno != errno.EWOULDBLOCK and \
+			value.errno != errno.EALREADY:
+			raise value	
+
+def _net_read(sock, count, expiration):
+	""" Read the specified number of bytes from sock. Keep trying until we
+	    either get the desired amount, or we hit EOF.
+	    A Timeout exception will be raised if the operation is not completed
+	    by the expiration time.
+	"""
+
+	msgdata = b''
+	while count > 0:
+		_wait_for_readable(sock, expiration)
+		data = sock.recv(count)
+		if not data:
+			return None
+
+		count -= len(data)
+		msgdata += data
+	
+	return msgdata
+
+def _net_write(sock, data, expiration):
+	""" Write the specified data to the socket.
+	    A Timeout exception will be raised if the operation is not completed
+	    by the expiration time.
+	"""
+	current = 0
+	l = len(data)
+	while current < 1:
+		_wait_for_writable(sock, expiration)
+		current += sock.send(data[current:])
+
+def _send_tcp(q, dest, timeout=None, dest_port=53, source=None, source_port=0):
+	""" Return the response obtained after sending a query via TCP. 
+	    Refered to dnspython source code """
+
+	qwire = MessageRenderer()
+	q.to_wire(qwire)
+
+	if source is not None:
+		source = (source, source_port)
+	dest = (dest, dest_port)
+	tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
+		
+	expiration = _compute_expiration(timeout)
+	tcpCliSock.setblocking(False)
+	if source is not None:
+		tcpCliSock.bind(source)
+	_connect(tcpCliSock, dest)
+
+	wire_s = qwire.get_data()
+	l = len(wire_s)
+
+	tcpmsg = struct.pack("!H", l) + wire_s
+	_net_write(tcpCliSock, tcpmsg, expiration)
+	ldata = _net_read(tcpCliSock, 2, expiration)
+	(l,) = struct.unpack("!H", ldata)
+	res_wire = _net_read(tcpCliSock, l, expiration)
+	tcpCliSock.close()
+
+	resp = Message(Message.PARSE)
+	resp.from_wire(res_wire)
+
+	return resp
+
+def send_req(query, server, port=53, timeout=5):
+	""" Return the response message obtained after 
+	    sending the query.
+	
+	@param query: the query readed from input file
+	@type query: dict
+	@param server: the testee server ip address
+	@type server: string
+	@param port: the testee server listening port. The default is 53.
+	@type port: int
+	@param timeout: the number of seconds to wait before the query times out.
+		The default is 5.
+	@type timeout: float
+	"""
+
+	qname = query["qname"]
+	qtype = query["qtype"]
+	qclass = query["qclass"]
+	edns = query["edns"]
+	dnssec = query["dnssec"]
+	qheader = query['header']
+	protocol = query['protocol']
+
+	msg = Message(Message.RENDER)
+	msg.set_qid(int(qheader['id']))
+	msg.set_opcode(Opcode.QUERY())
+	msg.set_rcode(Rcode(int(qheader['rcode'])))
+
+	if qheader['qr'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_QR)
+	if qheader['aa'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_AA)
+	if qheader['tc'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_TC)		
+	if qheader['rd'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_RD)
+	if qheader['ra'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_RA)
+	if qheader['ad'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_AD)
+	if qheader['cd'] == 1: 
+		msg.set_header_flag(Message.HEADERFLAG_CD)
+
+	try:
+		msg.add_question(Question(Name(qname), \
+                         	RRClass(qclass), RRType(qtype)))
+	except InvalidRRType as e: 
+		sys.stderr.write('Unrecognized RR queryeter string: %s\n' % qtype)
+		return None
+
+	if edns == 1 or dnssec == 1:
+		edns_conf = EDNS()
+		payload = query['payload']
+		edns_conf.set_udp_size(payload)
+
+		if dnssec == 1:
+			edns_conf.set_dnssec_awareness(True)
+		else:
+			edns_conf.set_dnssec_awareness(False)
+
+		msg.set_edns(edns_conf)
+
+	port = int(port)
+	if protocol == 'udp':
+		resp = _send_udp(msg, server, timeout, port)
+	else:
+		resp = _send_tcp(msg, server, timeout, port)
+
+	return resp
+
+
+def main():
+	query = {}
+	query['qname'] = "A.example.com"
+	query['qtype'] = "ANY"
+	query['qclass'] = "IN"
+	query["edns"] = 1
+	query["dnssec"] = 1
+	query["protocol"] = 'tcp'
+	query["payload"] = 4096
+
+	query['header'] = {}
+	query['header']['id'] = 0
+	query['header']['qr'] = 0
+	query['header']['opcode'] = 0
+	query['header']['aa'] = 0
+	query['header']['tc'] = 0
+	query['header']['rd'] = 1
+	query['header']['ra'] = 0
+	query['header']['z'] = 0
+	query['header']['ad'] = 0
+	query['header']['cd'] = 0
+	query['header']['rcode'] = 0
+	query['header']['qdcount'] = 0
+	query['header']['ancount'] = 0
+	query['header']['nscount'] = 0
+	query['header']['arcount'] = 0
+
+	resp = send_req(query, "218.241.108.124", "4040")
+
+	if resp == None:
+		print('timeout')
+		exit(1)
+
+	print('qid -----')
+	print(resp.get_qid())
+
+	rrset = resp.get_section(Message.SECTION_ANSWER)[0]
+	print('name-----')
+	print(rrset.get_name())
+	print('type')
+	print(rrset.get_type())
+	print('class-----')
+	print(rrset.get_class())
+	print(rrset.get_ttl())
+	rdata = rrset.get_rdata()
+	print(rdata[0].to_text())
+	
+if __name__ == "__main__":
+	main()

+ 93 - 0
tools/query_cmp/src/lib/read_query.py

@@ -0,0 +1,93 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011  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.
+
+import re
+import sys
+
+def read_query(file, querylist):
+	fh = open(file)
+	while True:
+		query = {}
+		query['header'] = {}
+
+		line = fh.readline()
+		if not line: break
+		line = line.rstrip('\n')
+
+		if re.search('^#', line): continue
+		if re.search('^\s*$', line): continue
+
+		fields = line.split(' ')
+		query['header']['id'] = fields.pop(0)
+		query['header']['qr'] = fields.pop(0)
+		query['header']['opcode'] = int(fields.pop(0))
+		query['header']['aa'] = fields.pop(0)
+		query['header']['tc'] = fields.pop(0)
+		query['header']['rd'] = fields.pop(0)
+		query['header']['ra'] = fields.pop(0)
+		query['header']['z'] = fields.pop(0)
+		query['header']['ad'] = fields.pop(0)
+		query['header']['cd'] = fields.pop(0)
+		query['header']['rcode'] = fields.pop(0)
+		query['header']['qdcount'] = fields.pop(0)
+		query['header']['ancount'] = fields.pop(0)
+		query['header']['nscount'] = fields.pop(0)
+		query['header']['arcount'] = fields.pop(0)
+
+		if query['header']['opcode'] == 0:
+			get_qtuple(query, 'question', fields)
+
+		querylist.append(query)
+
+	fh.close()
+
+def get_qtuple(query, sectname, list):
+	if sectname == 'question':
+		count = int(query['header']['qdcount'])
+	item = {}
+	i = 0
+	while i < count:
+		query[sectname] = []
+		item['qname'] = list.pop(0)
+		item['qtype'] = list.pop(0)
+		item['qclass'] = list.pop(0)
+		query[sectname].append(item)
+		i += 1
+
+def print_query(querylist):
+	keylist = ['id', 'qr', 'opcode', 'aa', 'tc', 'rd', 'ra', 'z',
+		'ad', 'cd', 'rcode', 'qdcount', 'ancount', 'nscount',
+		'arcount']
+	for q in querylist:
+		for key in keylist:
+			print(q['header'][key], ' ')
+		print_question(q)
+
+def print_question(query):
+	i = 0
+
+	while i < len(query['question']):
+		print(query['question'][i]['qname'], \
+			query['question'][i]['qtype'], \
+			query['question'][i]['qclass'], \
+			sep=' ')
+		i += 1
+
+if __name__ == '__main__':
+	qlist = []
+	read_query(sys.argv[1], qlist)
+	print_query(qlist)
+

+ 102 - 0
tools/query_cmp/src/query_two_server.py

@@ -0,0 +1,102 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2011  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.
+
+import sys; sys.path.append('lib')
+from optparse import OptionParser
+
+from read_query import *
+import handledns
+import compare_rrset
+
+def getopt():
+	"""
+	get options from user.
+	"""
+	usage = "usage: %prog -f <file> -s <svr1> [-p <port1>] -t <svr2> [-q <port2>] [-e] [-u] [--bufsize] [--edns]"
+	parser = OptionParser(usage)
+	parser.add_option("-f", "--file", dest="filename",
+		help="specify the input data filename")
+	parser.add_option("-s", "--svr1", dest="server1",
+		help="specify the tested DNS server 1")
+	parser.add_option("-p",
+		help="specify the port of the tested DNS server 1, default is 53")
+	parser.add_option("-t", "--svr2", dest="server2",
+		help="specify the tested DNS server 2")
+	parser.add_option("-q",
+		help="specify the port of the tested DNS server 2, default is 53")
+	parser.add_option("-e", "--dnssec", action="store_true",
+		default=False, help="turn on dnssec")
+	parser.add_option("", "--edns", action="store_true",
+		default=False, help="turn on edns, if -e is set, --edns will lapse, it must be True")
+	parser.add_option("-u", "--udp", action="store_true", default=False,
+		help="if set, query by udp, otherwise by tcp, default is unset")
+	parser.add_option("", "--bufsize", default=4096,
+		help="if --edns is set, --bufsize specifies payload of edns0, default is 4096")
+
+
+	(options, args) = parser.parse_args()
+	
+	if(options.filename == None or options.server1 == None or
+		options.server2 == None):
+		parser.print_help()
+		sys.exit(1)
+
+	return options
+
+def main():
+	opts = getopt()
+
+	qlist = []
+	read_query(opts.filename, qlist)
+
+	for q in qlist:
+		# initial query
+		query = {}
+		if opts.dnssec:
+			query['edns'] = 1
+			query['dnssec'] = 1
+		elif opts.edns:
+			query['edns'] = 1
+			query['dnssec'] = 0
+		else:
+			query['edns'] = 0
+			query['dnssec'] = 0
+
+		if opts.udp:
+			query['protocol'] = 'udp'
+		else:
+			query['protocol'] = 'tcp'
+
+		query['payload'] = opts.bufsize
+		query['qname'] = q['question'][0]['qname']
+		query['qtype'] = q['question'][0]['qtype']
+		query['qclass'] = q['question'][0]['qclass']
+		query['header'] = q['header']
+		id = q['header']['id']
+
+		# send the query to the 1st and 2nd server, and store the
+		# response in res1 and res2
+		res1 = handledns.send_req(query, opts.server1, opts.p)
+		res2 = handledns.send_req(query, opts.server2, opts.q)
+
+		if res1 != None and res2 != None:
+			# compare res1 and res2, print the different part.
+			res3 = compare_rrset.resp_casecmp(res1, res2, id)
+		else:
+			sys.stderr.write('Empty response.\n')
+
+if __name__ == "__main__":
+	main()

File diff suppressed because it is too large
+ 1298 - 0
tools/query_cmp/zonefile/example.com.txt


File diff suppressed because it is too large
+ 6858 - 0
tools/query_cmp/zonefile/example.com.txt.signed