Browse Source

Merge branch 'master' into trac2157_merge

Conflicts:
	ChangeLog
Yoshitaka Aharen 12 years ago
parent
commit
946c4e8afa
100 changed files with 2693 additions and 1807 deletions
  1. 92 0
      ChangeLog
  2. 26 3
      configure.ac
  3. 900 71
      doc/guide/bind10-guide.xml
  4. 1 1
      src/bin/auth/auth_config.cc
  5. 3 3
      src/bin/auth/auth_messages.mes
  6. 3 3
      src/bin/auth/auth_srv.cc
  7. 12 8
      src/bin/auth/query.cc
  8. 1 1
      src/bin/auth/tests/config_unittest.cc
  9. 36 51
      src/bin/auth/tests/query_unittest.cc
  10. 12 7
      src/bin/auth/tests/testdata/example-base-inc.zone
  11. 1 1
      src/bin/auth/tests/testdata/example-nsec3-inc.zone
  12. 10 3
      src/bin/bind10/bind10.in
  13. 1 0
      src/bin/bind10/init.py.in
  14. 1 1
      src/bin/bind10/tests/Makefile.am
  15. 1 1
      src/bin/bind10/tests/bind10_test.py.in
  16. 1 1
      src/bin/bindctl/bindcmd.py
  17. 1 1
      src/bin/bindctl/run_bindctl.sh.in
  18. 4 4
      src/bin/ddns/ddns.py.in
  19. 2 2
      src/bin/ddns/ddns_messages.mes
  20. 17 17
      src/bin/ddns/tests/ddns_test.py
  21. 4 6
      src/bin/dhcp4/Makefile.am
  22. 2 2
      src/bin/dhcp4/config_parser.cc
  23. 6 1
      src/bin/dhcp4/dhcp4_messages.mes
  24. 97 44
      src/bin/dhcp4/dhcp4_srv.cc
  25. 0 9
      src/bin/dhcp4/dhcp4_srv.h
  26. 4 6
      src/bin/dhcp4/tests/Makefile.am
  27. 5 3
      src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
  28. 4 6
      src/bin/dhcp6/Makefile.am
  29. 2 2
      src/bin/dhcp6/config_parser.cc
  30. 16 13
      src/bin/dhcp6/dhcp6_messages.mes
  31. 107 56
      src/bin/dhcp6/dhcp6_srv.cc
  32. 0 10
      src/bin/dhcp6/dhcp6_srv.h
  33. 4 6
      src/bin/dhcp6/tests/Makefile.am
  34. 1 1
      src/bin/dhcp6/tests/config_parser_unittest.cc
  35. 2 1
      src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
  36. 1 1
      src/bin/loadzone/loadzone.py.in
  37. 3 3
      src/bin/loadzone/tests/loadzone_test.py
  38. 4 4
      src/bin/msgq/msgq.py.in
  39. 4 4
      src/bin/msgq/msgq_messages.mes
  40. 8 5
      src/bin/resolver/resolver.cc
  41. 3 10
      src/bin/resolver/resolver_messages.mes
  42. 8 1
      src/bin/sockcreator/tests/sockcreator_tests.cc
  43. 2 1
      src/bin/stats/stats.py.in
  44. 4 4
      src/bin/stats/stats_httpd.py.in
  45. 1 1
      src/bin/stats/stats_httpd_messages.mes
  46. 2 0
      src/bin/stats/tests/b10-stats-httpd_test.py
  47. 4 0
      src/bin/stats/tests/b10-stats_test.py
  48. 1 13
      src/bin/sysinfo/run_sysinfo.sh.in
  49. 147 149
      src/bin/xfrin/tests/xfrin_test.py
  50. 31 31
      src/bin/xfrin/xfrin.py.in
  51. 0 4
      src/bin/xfrin/xfrin_messages.mes
  52. 61 61
      src/bin/xfrout/tests/xfrout_test.py.in
  53. 34 34
      src/bin/xfrout/xfrout.py.in
  54. 1 1
      src/bin/xfrout/xfrout_messages.mes
  55. 0 1
      src/lib/asiodns/tcp_server.cc
  56. 0 1
      src/lib/asiodns/tcp_server.h
  57. 3 4
      src/lib/asiodns/udp_server.cc
  58. 5 5
      src/lib/cc/data.cc
  59. 2 0
      src/lib/config/tests/ccsession_unittests.cc
  60. 8 2
      src/lib/datasrc/memory/zone_finder.cc
  61. 1 0
      src/lib/datasrc/memory_datasrc.cc
  62. 3 0
      src/lib/datasrc/sqlite3_accessor.cc
  63. 40 10
      src/lib/datasrc/tests/memory/zone_finder_unittest.cc
  64. 188 170
      src/lib/dhcpsrv/alloc_engine.cc
  65. 13 1
      src/lib/dhcpsrv/dhcpdb_create.mysql
  66. 40 0
      src/lib/dhcpsrv/dhcpsrv_messages.mes
  67. 12 1
      src/lib/dhcpsrv/lease_mgr.cc
  68. 19 6
      src/lib/dhcpsrv/mysql_lease_mgr.cc
  69. 6 5
      src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
  70. 4 0
      src/lib/dns/Makefile.am
  71. 92 26
      src/lib/dns/gen-rdatacode.py.in
  72. 1 0
      src/lib/dns/master_loader.cc
  73. 0 1
      src/lib/dns/name.cc
  74. 0 140
      src/lib/dns/python/opcode_python.cc
  75. 164 66
      src/lib/dns/python/pydnspp.cc
  76. 0 146
      src/lib/dns/python/rcode_python.cc
  77. 0 43
      src/lib/dns/python/rrclass_python.cc
  78. 0 144
      src/lib/dns/python/rrtype_python.cc
  79. 3 3
      src/lib/dns/python/tests/edns_python_test.py
  80. 17 17
      src/lib/dns/python/tests/message_python_test.py
  81. 4 4
      src/lib/dns/python/tests/messagerenderer_python_test.py
  82. 23 23
      src/lib/dns/python/tests/nsec3hash_python_test.py
  83. 41 41
      src/lib/dns/python/tests/opcode_python_test.py
  84. 30 30
      src/lib/dns/python/tests/rcode_python_test.py
  85. 10 10
      src/lib/dns/python/tests/rrclass_python_test.py
  86. 23 23
      src/lib/dns/python/tests/rrset_collection_python_test.py
  87. 22 22
      src/lib/dns/python/tests/rrtype_python_test.py
  88. 18 18
      src/lib/dns/python/tests/tsig_python_test.py
  89. 13 13
      src/lib/dns/python/tests/tsigerror_python_test.py
  90. 29 32
      src/lib/dns/python/tests/zone_checker_python_test.py
  91. 4 0
      src/lib/dns/rdata/template.h
  92. 0 14
      src/lib/dns/rrclass-placeholder.h
  93. 0 30
      src/lib/dns/rrtype-placeholder.h
  94. 25 0
      src/lib/dns/tests/rrclass_unittest.cc
  95. 1 1
      src/lib/dns/tests/rrset_unittest.cc
  96. 53 0
      src/lib/dns/tests/rrtype_unittest.cc
  97. 3 7
      src/lib/python/isc/__init__.py
  98. 5 5
      src/lib/python/isc/datasrc/tests/clientlist_test.py
  99. 70 70
      src/lib/python/isc/datasrc/tests/datasrc_test.py
  100. 0 0
      src/lib/python/isc/datasrc/tests/zone_loader_test.py

+ 92 - 0
ChangeLog

@@ -6,6 +6,98 @@ TBD.	[func]*		y-aharen
 	             git 61d7c3959eb991b22bc1c0ef8f4ecb96b65d9325)
 	(Trac #2157, git TBD)
 
+579.	[bug]		jinmei
+	libdatasrc/b10-auth: corrected some corner cases in query handling
+	of in-memory data source that led to the following invalid/odd
+	responses from b10-auth:
+	- duplicate RRs in answer and additional for type ANY query
+	- incorrect NSEC for no error, no data (NXRRSET) response that
+	  matches a wildcard
+	(Trac #2585, git abe78fae4ba3aca5eb01806dd4e05607b1241745)
+
+578.	[bug]		jinmei
+	b10-auth now returns closest encloser NSEC3 proof to queries for
+	an empty non terminal derived from an Opt-Out NSEC RR, as clarified
+	in errata 3441 for RFC5155.  Previously it regarded such case as
+	broken zone and returned SERVFAIL.
+	(Trac #2659, git 24c235cb1b379c6472772d340e21577c3460b742)
+
+577.	[func]		muks
+	Added an SQLite3 index on records(rname, rdtype). This decreases
+	insert performance by ~28% and adds about ~20% to the file size,
+	but increases zone iteration performance. As it introduces a new
+	index, a database upgrade would be required.
+	(Trac #1756, git 9b3c959af13111af1fa248c5010aa33ee7e307ee)
+
+576.	[bug]		tmark, tomek
+	b10-dhcp6: Fixed bug when the server aborts operation when
+	receiving renew and there are no IPv6 subnets configured.
+	(Trac 2719, git 3132b8b19495470bbfd0f2ba0fe7da443926034b)
+
+575.	[bug]		marcin
+	b10-dhcp6: Fixed the bug whereby the subnet for the incoming
+	packet was selected using only its source address. The subnet
+	is now selected using either source address or the name of the
+	server's interface on which the packet has been received.
+	(Trac #2704, git 1cbacf19a28bdae50bb9bd3767bca0147fde37ed)
+
+574.	[func]		tmark
+	b10-dhcp4, b10-dhcp6: Composite key indexes were added to the lease
+	tables to reduce lease search time. The lease4 table now has two
+	additional indexes: a) hwaddr/subnet_id and b) client_id/subnet_id.
+	The lease6 now has the one additional index: iaid/subnet_id/duid.
+	Adding these indexes significantly improves lease acquisition
+	performance.
+	(Trac #2699,#2703, git 54bbed5fcbe237c5a49b515ae4c55148723406ce)
+
+573.	[bug]		stephen
+	Fixed problem whereby the DHCP server crashed if it ran out of
+	addresses.  Such a condition now causes a packet to be returned
+	to the client refusing the allocation of an address.
+	(Trac #2681, git 87ce14cdb121b37afb5b1931af51bed7f6323dd6)
+
+572.	[bug]		marcin
+	perfdhcp: Fixed bug where the command line switches used to
+	run the perfdhcp where printed as ASCII codes.
+	(Trac #2700, git b8d6b949eb7f4705e32fbdfd7694ca2e6a6a5cdc)
+
+571.	[build]		jinmei
+	The ./configure script can now handle output from python-config
+	--ldflags that contains a space after -L switches.  This fixes
+	failure reported on some Solaris environments.
+	(Trac #2661, git e6f86f2f5eec8e6003c13d36804a767a840d96d6)
+
+570.	[bug]		tmark, marcin, tomek
+	b10-dhcp4: Address renewal now works properly for DHCPv4 clients
+	that do not send client ID.
+	(Trac #2702, git daf2abe68ce9c111334a15c14e440730f3a085e2)
+
+569.	[bug]		tomek
+	b10-dhcp4: Fix bug whereby a DHCP packet without a client ID
+	could crash the MySQL lease database backend.
+	(Trac #2697, git b5e2be95d21ed750ad7cf5e15de2058aa8bc45f4)
+
+568.	[func]          muks
+	Various message IDs have been renamed to remove the word 'ERROR'
+	from them when they are not logged at ERROR severity level.
+	(Trac #2672, git 660a0d164feaf055677f375977f7ed327ead893e)
+
+567.	[doc]		marcin, stephen, tomek
+	Update DHCP sections of the BIND 10 guide.
+	(Trac #2657, git 1d0c2004865d1bf322bf78d13630d992e39179fd)
+
+566.	[func]*		jinmei
+	libdns++/Python isc.dns: In Python isc.dns, function style
+	constants for RRType, RRClass, Rcode and Opcode were deprecated
+	and replaced with straightforward object constants, e.g., from
+	RRType.AAAA() to RRType.AAAA.  This is a backward incompatible
+	change (see the Trac ticket for a conversion script if needed).
+	Also, these constants are now more consistent between C++
+	and Python, and RRType constants for all currently standardized
+	types are now supported (even if Rdata for these are not yet
+	available).
+	(Trac #1866 and #2409, git e5005185351cf73d4a611407c2cfcd163f80e428)
+
 565.	[func]*		jelte
 	The main initializer script (formerly known as either 'bind10',
 	'boss', or 'bob'), has been renamed to b10-init (and Init in

+ 26 - 3
configure.ac

@@ -238,6 +238,21 @@ AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
 AC_SUBST(SET_ENV_LIBRARY_PATH)
 AC_SUBST(ENV_LIBRARY_PATH)
 
+# Our experiments have shown Solaris 10 has broken support for the
+# IPV6_USE_MIN_MTU socket option for getsockopt(); it doesn't return the value
+# previously set via setsockopt().  We know it doesn't happen on one instance
+# on Solaris 11, but we don't know whether it happens for any Solaris 10
+# implementations or for earlier versions of Solaris.  In any case, at the
+# moment this matters for only one unittest case, so we'll simply disable
+# the affected test using the following definition with the specific hardcoding
+# of that version of Solaris.
+case "$host" in
+*-solaris2.10)
+	AC_DEFINE([HAVE_BROKEN_GET_IPV6_USE_MIN_MTU], [1],
+	[Define to 1 if getsockopt(IPV6_USE_MIN_MTU) does not work])
+	;;
+esac
+
 m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3.3 python3.2 python3.1 python3])
 AC_ARG_WITH([pythonpath],
 AC_HELP_STRING([--with-pythonpath=PATH],
@@ -298,8 +313,16 @@ AC_SUBST(COMMON_PYTHON_PATH)
 if test -x ${PYTHON}-config; then
 	PYTHON_INCLUDES=`${PYTHON}-config --includes`
 
-	for flag in `${PYTHON}-config --ldflags`; do
-		# add any '-L..." flags to PYTHON_LDFLAGS
+	# Add any '-L..." flags to PYTHON_LDFLAGS.  We first make a copy of
+	# python-config --ldflags, removing any spaces and tabs
+	# between "-L" and its argument (some instances of python-config
+	# insert a space, which would confuse the code below).
+	# Notes: if -L isn't contained at all we can simply skip this process,
+	# so we only go through the flag if it's contained; also, protecting
+	# the output with [] seems necessary for environment to avoid getting
+	# an empty output accidentally.
+	python_config_ldflags=[`${PYTHON}-config --ldflags | sed -ne 's/\([ \t]*-L\)[ ]*\([^ \t]*[ \t]*\)/\1\2/pg'`]
+	for flag in $python_config_ldflags; do
 		flag=`echo $flag | sed -ne 's/^\(\-L.*\)$/\1/p'`
 		if test "X${flag}" != X; then
 			PYTHON_LDFLAGS="$PYTHON_LDFLAGS ${flag}"
@@ -1319,7 +1342,7 @@ AC_OUTPUT([doc/version.ent
            src/bin/stats/stats_httpd.py
            src/bin/bind10/init.py
            src/bin/bind10/run_bind10.sh
-           src/bin/bind10/tests/bind10_test.py
+           src/bin/bind10/tests/init_test.py
            src/bin/bindctl/run_bindctl.sh
            src/bin/bindctl/bindctl_main.py
            src/bin/bindctl/tests/bindctl_test

File diff suppressed because it is too large
+ 900 - 71
doc/guide/bind10-guide.xml


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

@@ -106,7 +106,7 @@ public:
         rollbackAddresses_ = old;
     }
     virtual void commit() {
-        rollbackAddresses_.release();
+        rollbackAddresses_.reset();
     }
 private:
     AuthSrv& server_;

+ 3 - 3
src/bin/auth/auth_messages.mes

@@ -14,7 +14,7 @@
 
 $NAMESPACE isc::auth
 
-% AUTH_AXFR_ERROR error handling AXFR request: %1
+% AUTH_AXFR_PROBLEM error handling AXFR request: %1
 This is a debug message produced by the authoritative server when it
 has encountered an error processing an AXFR request. The message gives
 the reason for the error, and the server will return a SERVFAIL code to
@@ -232,13 +232,13 @@ This is a debug message produced by the authoritative server when it receives
 a NOTIFY packet but the XFRIN process is not running. The packet will be
 dropped and nothing returned to the sender.
 
-% AUTH_PACKET_PARSE_ERROR unable to parse received DNS packet: %1
+% AUTH_PACKET_PARSE_FAILED unable to parse received DNS packet: %1
 This is a debug message, generated by the authoritative server when an
 attempt to parse a received DNS packet has failed due to something other
 than a protocol error. The reason for the failure is given in the message;
 the server will return a SERVFAIL error code to the sender.
 
-% AUTH_PACKET_PROTOCOL_ERROR DNS packet protocol error: %1. Returning %2
+% AUTH_PACKET_PROTOCOL_FAILURE DNS packet protocol error: %1. Returning %2
 This is a debug message, generated by the authoritative server when an
 attempt to parse a received DNS packet has failed due to a protocol error.
 The reason for the failure is given in the message, as is the error code

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

@@ -529,14 +529,14 @@ AuthSrv::processMessage(const IOMessage& io_message, Message& message,
         // Parse the message.
         message.fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
-        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PROTOCOL_ERROR)
+        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PROTOCOL_FAILURE)
                   .arg(error.getRcode().toText()).arg(error.what());
         makeErrorMessage(impl_->renderer_, message, buffer, error.getRcode(),
                          stats_attrs);
         impl_->resumeServer(server, message, stats_attrs, true);
         return;
     } catch (const Exception& ex) {
-        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PARSE_ERROR)
+        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_PACKET_PARSE_FAILED)
                   .arg(ex.what());
         makeErrorMessage(impl_->renderer_, message, buffer, Rcode::SERVFAIL(),
                          stats_attrs);
@@ -731,7 +731,7 @@ AuthSrvImpl::processXfrQuery(const IOMessage& io_message, Message& message,
             xfrout_connected_ = false;
         }
 
-        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_AXFR_ERROR)
+        LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_AXFR_PROBLEM)
                   .arg(err.what());
         makeErrorMessage(renderer_, message, buffer, Rcode::SERVFAIL(),
                          stats_attrs, tsig_context);

+ 12 - 8
src/bin/auth/query.cc

@@ -298,14 +298,18 @@ Query::addNXRRsetProof(ZoneFinder& finder,
             addWildcardNXRRSETProof(finder, db_context.rrset);
         }
     } else if (db_context.isNSEC3Signed() && !db_context.isWildcard()) {
-        if (*qtype_ == RRType::DS()) {
-            // RFC 5155, Section 7.2.4.  Add either NSEC3 for the qname or
-            // closest (provable) encloser proof in case of optout.
-            addClosestEncloserProof(finder, *qname_, true);
-        } else {
-            // RFC 5155, Section 7.2.3.  Just add NSEC3 for the qname.
-            addNSEC3ForName(finder, *qname_, true);
-        }
+        // Section 7.2.3 and 7.2.4 of RFC 5155 with clarification by errata
+        // http://www.rfc-editor.org/errata_search.php?rfc=5155&eid=3441
+        // In the end, these two cases are basically the same: if the qname is
+        // equal to or derived from insecure delegation covered by an Opt-Out
+        // NSEC3 RR, include the closest provable encloser proof; otherwise we
+        // have a matching NSEC3, so we include it.
+        //
+        // Note: This implementation does not check in the former case whether
+        // the NSEC3 for the next closer has Opt-Out bit on; this must be the
+        // case as long as the zone is correctly signed, and if it's broken
+        // we'd just return what we are given and have the validator detect it.
+        addClosestEncloserProof(finder, *qname_, true);
     } else if (db_context.isNSEC3Signed() && db_context.isWildcard()) {
         // Case for RFC 5155 Section 7.2.5: add closest encloser proof for the
         // qname, construct the matched wildcard name and add NSEC3 for it.

+ 1 - 1
src/bin/auth/tests/config_unittest.cc

@@ -130,7 +130,7 @@ TEST_F(AuthConfigTest, invalidListenAddressConfig) {
     isc::testutils::portconfig::invalidListenAddressConfig(server);
 }
 
-// Try setting addresses trough config
+// Try setting addresses through config
 TEST_F(AuthConfigTest, listenAddressConfig) {
     isc::testutils::portconfig::listenAddressConfig(server);
 

+ 36 - 51
src/bin/auth/tests/query_unittest.cc

@@ -217,6 +217,13 @@ public:
             "t644ebqk9bibcna874givr6joj62mlhv";
         hash_map_[Name("www1.uwild.example.com")] =
             "q04jkcevqvmu85r014c7dkba38o0ji6r"; // a bit larger than H(www)
+
+        // For empty-non-terminal derived from insecure delegation (we don't
+        // need a hash for the delegation point itself for that test).  the
+        // hash for empty name is the same as that for unsigned-delegation
+        // above, as the case is similar to that.
+        hash_map_[Name("empty.example.com")] =
+            "q81r598950igr1eqvc60aedlq66425b5"; // a bit larger than H(www)
     }
     virtual string calculate(const Name& name) const {
         const NSEC3HashMap::const_iterator found = hash_map_.find(name);
@@ -262,8 +269,6 @@ public:
 // to child zones are identified by the existence of non origin NS records.
 // Another special name is "dname.example.com".  Query names under this name
 // will result in DNAME.
-// This mock zone doesn't handle empty non terminal nodes (if we need to test
-// such cases find() should have specialized code for it).
 class MockZoneFinder : public ZoneFinder {
 public:
     MockZoneFinder() :
@@ -1162,12 +1167,6 @@ TEST_P(QueryTest, apexNSMatch) {
 
 // test type any query logic
 TEST_P(QueryTest, exactAnyMatch) {
-    // This is an in-memory specific bug (#2585), until it's fixed we
-    // tentatively skip the test for in-memory
-    if (GetParam() == INMEMORY) {
-        return;
-    }
-
     // find match rrset, omit additional data which has already been provided
     // in the answer section from the additional.
     EXPECT_NO_THROW(query.process(*list_, Name("noglue.example.com"),
@@ -1373,17 +1372,11 @@ TEST_P(QueryTest, nxdomainWithNSEC) {
 }
 
 TEST_P(QueryTest, nxdomainWithNSEC2) {
-    // there seems to be a bug in the SQLite3 (or database in general) data
-    // source and this doesn't work (Trac #2586).
-    if (GetParam() == SQLITE3) {
-        return;
-    }
-
     // See comments about no_txt.  In this case the best possible wildcard
     // is derived from the next domain of the NSEC that proves NXDOMAIN, and
     // the NSEC to provide the non existence of wildcard is different from
     // the first NSEC.
-    query.process(*list_, Name("(.no.example.com"), qtype, response,
+    query.process(*list_, Name("!.no.example.com"), qtype, response,
                   true);
     responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 6, 0,
                   NULL, (string(soa_minttl_txt) +
@@ -1393,19 +1386,12 @@ TEST_P(QueryTest, nxdomainWithNSEC2) {
                          string("mx.example.com. 3600 IN RRSIG ") +
                          getCommonRRSIGText("NSEC") + "\n" +
                          string(nsec_no_txt) + "\n" +
-                         string(").no.example.com. 3600 IN RRSIG ") +
+                         string("&.no.example.com. 3600 IN RRSIG ") +
                          getCommonRRSIGText("NSEC")).c_str(),
                   NULL, mock_finder->getOrigin());
 }
 
 TEST_P(QueryTest, nxdomainWithNSECDuplicate) {
-    // there seems to be a bug in the SQLite3 (or database in general) data
-    // source and this doesn't work.  This is probably the same type of bug
-    // as nxdomainWithNSEC2 (Trac #2586).
-    if (GetParam() == SQLITE3) {
-        return;
-    }
-
     // See comments about nz_txt.  In this case we only need one NSEC,
     // which proves both NXDOMAIN and the non existence of wildcard.
     query.process(*list_, Name("nx.no.example.com"), qtype, response,
@@ -1415,7 +1401,7 @@ TEST_P(QueryTest, nxdomainWithNSECDuplicate) {
                          string("example.com. 0 IN RRSIG ") +
                          getCommonRRSIGText("SOA") + "\n" +
                          string(nsec_no_txt) + "\n" +
-                         string(").no.example.com. 3600 IN RRSIG ") +
+                         string("&.no.example.com. 3600 IN RRSIG ") +
                          getCommonRRSIGText("NSEC")).c_str(),
                   NULL, mock_finder->getOrigin());
 }
@@ -1529,7 +1515,7 @@ TEST_P(QueryTest, nxrrsetWithNSEC) {
 TEST_P(QueryTest, emptyNameWithNSEC) {
     // Empty non terminal with DNSSEC proof.  This is one of the cases of
     // Section 3.1.3.2 of RFC4035.
-    // mx.example.com. NSEC ).no.example.com. proves no.example.com. is a
+    // mx.example.com. NSEC &.no.example.com. proves no.example.com. is a
     // non empty terminal node.  Note that it also implicitly proves there
     // should be no closer wildcard match (because the empty name is an
     // exact match), so we only need one NSEC.
@@ -1700,12 +1686,6 @@ TEST_F(QueryTestForMockOnly, badWildcardProof3) {
 }
 
 TEST_P(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
-    // This is an in-memory specific bug (#2585), until it's fixed we
-    // tentatively skip the test for in-memory
-    if (GetParam() == INMEMORY) {
-        return;
-    }
-
     // NXRRSET on WILDCARD with DNSSEC proof.  We should have SOA, NSEC that
     // proves the NXRRSET and their RRSIGs. In this case we only need one NSEC,
     // which proves both NXDOMAIN and the non existence RRSETs of wildcard.
@@ -1723,12 +1703,6 @@ TEST_P(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
 }
 
 TEST_P(QueryTest, wildcardNxrrsetWithNSEC) {
-    // This is an in-memory specific bug (#2585), until it's fixed we
-    // tentatively skip the test for in-memory
-    if (GetParam() == INMEMORY) {
-        return;
-    }
-
     // WILDCARD + NXRRSET with DNSSEC proof.  We should have SOA, NSEC that
     // proves the NXRRSET and their RRSIGs. In this case we need two NSEC RRs,
     // one proves NXDOMAIN and the other proves non existence RRSETs of
@@ -2468,21 +2442,32 @@ TEST_P(QueryTest, nxrrsetWithNSEC3) {
                   NULL, mock_finder->getOrigin());
 }
 
-// Check the exception is correctly raised when the NSEC3 thing isn't in the
-// zone
-TEST_F(QueryTestForMockOnly, nxrrsetMissingNSEC3) {
-    // This is a broken data source scenario; works only with mock.
-
-    mock_finder->setNSEC3Flag(true);
-    // We just need it to return false for "matched". This indicates
-    // there's no exact match for NSEC3 on www.example.com.
-    ZoneFinder::FindNSEC3Result nsec3(false, 0, ConstRRsetPtr(),
-                                      ConstRRsetPtr());
-    mock_finder->setNSEC3Result(&nsec3);
+TEST_P(QueryTest, nxrrsetDerivedFromOptOutNSEC3) {
+    // In this test we emulate the situation where an empty non-terminal name
+    // is derived from insecure delegation and covered by an opt-out NSEC3.
+    // In the actual test data the covering NSEC3 really has the opt-out
+    // bit set, although the implementation doesn't check it anyway.
+    enableNSEC3(rrsets_to_add_);
+    query.process(*list_, Name("empty.example.com"), RRType::TXT(), response,
+                  true);
 
-    EXPECT_THROW(query.process(*list_, Name("www.example.com"),
-                               RRType::TXT(), response, true),
-                 Query::BadNSEC3);
+    // The closest provable encloser is the origin name (example.com.), and
+    // the next closer is the empty name itself, which is expected to be
+    // covered by an opt-out NSEC3 RR.  The response should contain these 2
+    // NSEC3s.
+    responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
+                  (string(soa_minttl_txt) +
+                   string("example.com. 0 IN RRSIG ") +
+                   getCommonRRSIGText("SOA") + "\n" +
+                   string(nsec3_apex_txt) + "\n" +
+                   nsec3_hash_.calculate(Name("example.com.")) +
+                   ".example.com. 3600 IN RRSIG " +
+                   getCommonRRSIGText("NSEC3") + "\n" +
+                   string(nsec3_www_txt) + "\n" +
+                   nsec3_hash_.calculate(Name("www.example.com.")) +
+                   ".example.com. 3600 IN RRSIG " +
+                   getCommonRRSIGText("NSEC3") + "\n").c_str(),
+                  NULL, mock_finder->getOrigin());
 }
 
 TEST_P(QueryTest, nxrrsetWithNSEC3_ds_exact) {

+ 12 - 7
src/bin/auth/tests/testdata/example-base-inc.zone

@@ -150,32 +150,32 @@ t.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 e
 ;; the best possible wildcard is below the "next domain" of the NSEC RR that
 ;; proves the NXDOMAIN, i.e.,
 ;; mx.example.com. (exist)
-;; (.no.example.com. (qname, NXDOMAIN)
-;; ).no.example.com. (exist)
+;; !.no.example.com. (qname, NXDOMAIN)
+;; &.no.example.com. (exist)
 ;; *.no.example.com. (best possible wildcard, not exist)
 ;var=no_txt
-\).no.example.com. 3600 IN AAAA 2001:db8::53
+&.no.example.com. 3600 IN AAAA 2001:db8::53
 ;; NSEC records.
 ;var=nsec_apex_txt
 example.com. 3600 IN NSEC cname.example.com. NS SOA NSEC RRSIG
 ;var=
 example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 ;var=nsec_mx_txt
-mx.example.com. 3600 IN NSEC \).no.example.com. MX NSEC RRSIG
+mx.example.com. 3600 IN NSEC &.no.example.com. MX NSEC RRSIG
 
 ;var=
 mx.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
 ;var=nsec_no_txt
-\).no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG
+&.no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG
 
 ;var=
-\).no.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
+&.no.example.com. 3600 IN RRSIG NSEC 5 3 3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE
 
 ;; We'll also test the case where a single NSEC proves both NXDOMAIN and the
 ;; non existence of wildcard.  The following records will be used for that
 ;; test.
-;; ).no.example.com. (exist, whose NSEC proves everything)
+;; &.no.example.com. (exist, whose NSEC proves everything)
 ;; *.no.example.com. (best possible wildcard, not exist)
 ;; nx.no.example.com. (NXDOMAIN)
 ;; nz.no.example.com. (exist)
@@ -234,3 +234,8 @@ bad-delegation.example.com. 3600 IN NS ns.example.net.
 ;; or NSEC3 that proves it.
 ;var=nosec_delegation_txt
 nosec-delegation.example.com. 3600 IN NS ns.nosec.example.net.
+
+;; Setup for emulating insecure delegation that contain an empty name.
+;; the delegation itself isn't expected to be used directly in tests.
+;var=
+delegation.empty.example.com. 3600 IN NS ns.delegation.empty.example

+ 1 - 1
src/bin/auth/tests/testdata/example-nsec3-inc.zone

@@ -1,4 +1,4 @@
-;; See query_testzone_data.txt for general notes.
+;; See example-base-inc.zone for general notes.
 
 ;; NSEC3PARAM.  This is needed for database-based data source to
 ;; signal the zone is NSEC3-signed

+ 10 - 3
src/bin/bind10/bind10.in

@@ -1,4 +1,11 @@
 #!/bin/sh
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-exec @libexecdir@/@PACKAGE@/b10-init $*
+
+# We use this wrapper script both for production and in-source tests; in
+# the latter case B10_FROM_BUILD environment is expected to be defined.
+if test -n "${B10_FROM_BUILD}"; then
+	exec ${B10_FROM_BUILD}/src/bin/bind10/b10-init $*
+else
+	prefix=@prefix@
+	exec_prefix=@exec_prefix@
+	exec @libexecdir@/@PACKAGE@/b10-init $*
+fi

+ 1 - 0
src/bin/bind10/init.py.in

@@ -72,6 +72,7 @@ import isc.cc
 import isc.util.process
 import isc.net.parse
 import isc.log
+import isc.config
 from isc.log_messages.init_messages import *
 import isc.bind10.component
 import isc.bind10.special_component

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

@@ -1,7 +1,7 @@
 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
+PYTESTS = init_test.py
 noinst_SCRIPTS = $(PYTESTS)
 
 # If necessary (rare cases), explicitly specify paths to dynamic libraries

+ 1 - 1
src/bin/bind10/tests/bind10_test.py.in

@@ -31,8 +31,8 @@ import signal
 import socket
 from isc.net.addr import IPAddr
 import time
-import isc
 import isc.log
+import isc.config
 import isc.bind10.socket_cache
 import errno
 import random

+ 1 - 1
src/bin/bindctl/bindcmd.py

@@ -25,7 +25,7 @@ from bindctl.moduleinfo import *
 from bindctl.cmdparse import BindCmdParser
 from bindctl import command_sets
 from xml.dom import minidom
-import isc
+import isc.config
 import isc.cc.data
 import http.client
 import json

+ 1 - 1
src/bin/bindctl/run_bindctl.sh.in

@@ -23,7 +23,7 @@ BINDCTL_PATH=@abs_top_builddir@/src/bin/bindctl
 # Note: lib/dns/python/.libs is necessary because __init__.py of isc package
 # automatically imports isc.datasrc, which then requires the DNS loadable
 # module.  #2145 should eliminate the need for it.
-PYTHONPATH=@abs_top_srcdir@/src/bin:@abs_top_builddir@/src/lib/python/isc/log_messages:@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/bin:@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/dns/python/.libs
+PYTHONPATH=@abs_top_srcdir@/src/bin:@abs_top_builddir@/src/lib/python/isc/log_messages:@abs_top_builddir@/src/lib/python:@abs_top_builddir@/src/bin:@abs_top_srcdir@/src/lib/python
 export PYTHONPATH
 
 # If necessary (rare cases), explicitly specify paths to dynamic libraries

+ 4 - 4
src/bin/ddns/ddns.py.in

@@ -134,7 +134,7 @@ def get_datasrc_client(cc_session):
     function will simply be removed.
 
     '''
-    HARDCODED_DATASRC_CLASS = RRClass.IN()
+    HARDCODED_DATASRC_CLASS = RRClass.IN
     file, is_default = cc_session.get_remote_config_value("Auth",
                                                           "database_file")
     # See xfrout.py:get_db_file() for this trick:
@@ -469,7 +469,7 @@ class DDNSServer:
             self.__request_msg.clear(Message.PARSE)
             # specify PRESERVE_ORDER as we need to handle each RR separately.
             self.__request_msg.from_wire(req_data, Message.PRESERVE_ORDER)
-            if self.__request_msg.get_opcode() != Opcode.UPDATE():
+            if self.__request_msg.get_opcode() != Opcode.UPDATE:
                 raise self.InternalError('Update request has unexpected '
                                          'opcode: ' +
                                          str(self.__request_msg.get_opcode()))
@@ -536,7 +536,7 @@ class DDNSServer:
                 else:
                     tcp_ctx.close()
         except socket.error as ex:
-            logger.warn(DDNS_RESPONSE_SOCKET_ERROR, ClientFormatter(dest), ex)
+            logger.warn(DDNS_RESPONSE_SOCKET_SEND_FAILED, ClientFormatter(dest), ex)
             return False
 
         return True
@@ -683,7 +683,7 @@ class DDNSServer:
                 result = ctx[0].send_ready()
                 if result != DNSTCPContext.SENDING:
                     if result == DNSTCPContext.CLOSED:
-                        logger.warn(DDNS_RESPONSE_TCP_SOCKET_ERROR,
+                        logger.warn(DDNS_RESPONSE_TCP_SOCKET_SEND_FAILED,
                                     ClientFormatter(ctx[1]))
                     ctx[0].close()
                     del self._tcp_ctxs[fileno]

+ 2 - 2
src/bin/ddns/ddns_messages.mes

@@ -134,12 +134,12 @@ appropriate ACL configuration or some lower layer filtering.  The
 number of existing TCP clients are shown in the log, which should be
 identical to the current quota.
 
-% DDNS_RESPONSE_SOCKET_ERROR failed to send update response to %1: %2
+% DDNS_RESPONSE_SOCKET_SEND_FAILED failed to send update response to %1: %2
 Network I/O error happens in sending an update response.  The
 client's address that caused the error and error details are also
 logged.
 
-% DDNS_RESPONSE_TCP_SOCKET_ERROR failed to complete sending update response to %1 over TCP
+% DDNS_RESPONSE_TCP_SOCKET_SEND_FAILED failed to complete sending update response to %1 over TCP
 b10-ddns had tried to send an update response over TCP, and it hadn't
 been completed at that time, and a followup attempt to complete the
 send operation failed due to some network I/O error.  While a network

+ 17 - 17
src/bin/ddns/tests/ddns_test.py

@@ -39,9 +39,9 @@ TESTDATA_PATH = os.environ['TESTDATA_PATH'] + os.sep
 READ_ZONE_DB_FILE = TESTDATA_PATH + "rwtest.sqlite3" # original, to be copied
 TEST_ZONE_NAME = Name('example.org')
 TEST_ZONE_NAME_STR = TEST_ZONE_NAME.to_text()
-UPDATE_RRTYPE = RRType.SOA()
+UPDATE_RRTYPE = RRType.SOA
 TEST_QID = 5353                 # arbitrary chosen
-TEST_RRCLASS = RRClass.IN()
+TEST_RRCLASS = RRClass.IN
 TEST_RRCLASS_STR = TEST_RRCLASS.to_text()
 TEST_SERVER6 = ('2001:db8::53', 53, 0, 0)
 TEST_CLIENT6 = ('2001:db8::1', 53000, 0, 0)
@@ -169,9 +169,9 @@ class FakeUpdateSession:
         self.__msg.make_response()
         self.__msg.clear_section(SECTION_ZONE)
         if self.__faked_result == UPDATE_SUCCESS:
-            self.__msg.set_rcode(Rcode.NOERROR())
+            self.__msg.set_rcode(Rcode.NOERROR)
         else:
-            self.__msg.set_rcode(Rcode.REFUSED())
+            self.__msg.set_rcode(Rcode.REFUSED)
         return self.__msg
 
 class FakeKeyringModule:
@@ -478,7 +478,7 @@ class TestDDNSServer(unittest.TestCase):
         # By default (in our faked config) it should be derived from the
         # test data source
         rrclass, datasrc_client = self.ddns_server._datasrc_info
-        self.assertEqual(RRClass.IN(), rrclass)
+        self.assertEqual(RRClass.IN, rrclass)
         self.assertEqual(DataSourceClient.SUCCESS,
                          datasrc_client.find_zone(Name('example.org'))[0])
 
@@ -491,7 +491,7 @@ class TestDDNSServer(unittest.TestCase):
             {'database_file': './notexistentdir/somedb.sqlite3'}
         self.__cc_session.add_remote_config_by_name('Auth')
         rrclass, datasrc_client = self.ddns_server._datasrc_info
-        self.assertEqual(RRClass.IN(), rrclass)
+        self.assertEqual(RRClass.IN, rrclass)
         self.assertRaises(isc.datasrc.Error,
                           datasrc_client.find_zone, Name('example.org'))
 
@@ -887,12 +887,12 @@ class TestDDNSServer(unittest.TestCase):
         self.__select_answer = ([], [10], [])
         self.assertRaises(KeyError, self.ddns_server.run)
 
-def create_msg(opcode=Opcode.UPDATE(), zones=[TEST_ZONE_RECORD], prereq=[],
+def create_msg(opcode=Opcode.UPDATE, zones=[TEST_ZONE_RECORD], prereq=[],
                tsigctx=None):
     msg = Message(Message.RENDER)
     msg.set_qid(TEST_QID)
     msg.set_opcode(opcode)
-    msg.set_rcode(Rcode.NOERROR())
+    msg.set_rcode(Rcode.NOERROR)
     for z in zones:
         msg.add_question(z)
     for p in prereq:
@@ -936,7 +936,7 @@ class TestDDNSSession(unittest.TestCase):
         return FakeUpdateSession(req_message, client_addr, zone_config,
                                  self.__faked_result)
 
-    def check_update_response(self, resp_wire, expected_rcode=Rcode.NOERROR(),
+    def check_update_response(self, resp_wire, expected_rcode=Rcode.NOERROR,
                               tsig_ctx=None, tcp=False):
         '''Check if given wire data are valid form of update response.
 
@@ -963,7 +963,7 @@ class TestDDNSSession(unittest.TestCase):
             self.assertNotEqual(None, tsig_record)
             self.assertEqual(TSIGError.NOERROR,
                              tsig_ctx.verify(tsig_record, resp_wire))
-        self.assertEqual(Opcode.UPDATE(), msg.get_opcode())
+        self.assertEqual(Opcode.UPDATE, msg.get_opcode())
         self.assertEqual(expected_rcode, msg.get_rcode())
         self.assertEqual(TEST_QID, msg.get_qid())
         for section in [SECTION_ZONE, SECTION_PREREQUISITE, SECTION_UPDATE]:
@@ -977,7 +977,7 @@ class TestDDNSSession(unittest.TestCase):
         server_addr = TEST_SERVER6 if ipv6 else TEST_SERVER4
         client_addr = TEST_CLIENT6 if ipv6 else TEST_CLIENT4
         tsig = TSIGContext(tsig_key) if tsig_key is not None else None
-        rcode = Rcode.NOERROR() if result == UPDATE_SUCCESS else Rcode.REFUSED()
+        rcode = Rcode.NOERROR if result == UPDATE_SUCCESS else Rcode.REFUSED
         has_response = (result != UPDATE_DROP)
 
         self.assertEqual(has_response,
@@ -1015,7 +1015,7 @@ class TestDDNSSession(unittest.TestCase):
 
         # Opcode is not UPDATE
         self.assertFalse(self.server.handle_request(
-                (self.__sock, None, None, create_msg(opcode=Opcode.QUERY()))))
+                (self.__sock, None, None, create_msg(opcode=Opcode.QUERY))))
         self.assertEqual((None, None), (s._sent_data, s._sent_addr))
 
         # TSIG verification error.  We use UPDATE_DROP to signal check_session
@@ -1031,7 +1031,7 @@ class TestDDNSSession(unittest.TestCase):
                                                      TEST_CLIENT6,
                                                      create_msg())))
         # this check ensures sendto() was really attempted.
-        self.check_update_response(self.__sock._sent_data, Rcode.NOERROR())
+        self.check_update_response(self.__sock._sent_data, Rcode.NOERROR)
 
     def test_tcp_request(self):
         # A simple case using TCP: all resopnse data are sent out at once.
@@ -1040,7 +1040,7 @@ class TestDDNSSession(unittest.TestCase):
         self.assertTrue(self.server.handle_request((s, TEST_SERVER6,
                                                     TEST_CLIENT6,
                                                     create_msg())))
-        self.check_update_response(s._sent_data, Rcode.NOERROR(), tcp=True)
+        self.check_update_response(s._sent_data, Rcode.NOERROR, tcp=True)
         # In the current implementation, the socket should be closed
         # immedidately after a successful send.
         self.assertEqual(1, s._close_called)
@@ -1071,7 +1071,7 @@ class TestDDNSSession(unittest.TestCase):
         s.make_send_ready()
         self.assertEqual(DNSTCPContext.SEND_DONE,
                          self.server._tcp_ctxs[s.fileno()][0].send_ready())
-        self.check_update_response(s._sent_data, Rcode.NOERROR(), tcp=True)
+        self.check_update_response(s._sent_data, Rcode.NOERROR, tcp=True)
 
     def test_tcp_request_error(self):
         # initial send() on the TCP socket will fail.  The request handling
@@ -1127,9 +1127,9 @@ class TestDDNSSession(unittest.TestCase):
         self.__faked_result = UPDATE_DROP
         # Put the same RR twice in the prerequisite section.  We should see
         # them as separate RRs.
-        dummy_record = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS(),
+        dummy_record = RRset(TEST_ZONE_NAME, TEST_RRCLASS, RRType.NS,
                              RRTTL(0))
-        dummy_record.add_rdata(Rdata(RRType.NS(), TEST_RRCLASS, "ns.example."))
+        dummy_record.add_rdata(Rdata(RRType.NS, TEST_RRCLASS, "ns.example."))
         self.server.handle_request((self.__sock, TEST_SERVER6, TEST_CLIENT6,
                                     create_msg(prereq=[dummy_record,
                                                        dummy_record])))

+ 4 - 6
src/bin/dhcp4/Makefile.am

@@ -5,6 +5,10 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
 AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
+if USE_CLANGPP
+# Disable unused parameter warning caused by some Boost headers when compiling with clang
+AM_CXXFLAGS += -Wno-unused-parameter
+endif
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static
@@ -51,12 +55,6 @@ b10_dhcp4_SOURCES += dhcp4_srv.cc dhcp4_srv.h
 nodist_b10_dhcp4_SOURCES = dhcp4_messages.h dhcp4_messages.cc
 EXTRA_DIST += dhcp4_messages.mes
 
-if USE_CLANGPP
-# Disable unused parameter warning caused by some of the
-# Boost headers when compiling with clang.
-b10_dhcp4_CXXFLAGS = -Wno-unused-parameter
-endif
-
 b10_dhcp4_LDADD  = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
 b10_dhcp4_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
 b10_dhcp4_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la

+ 2 - 2
src/bin/dhcp4/config_parser.cc

@@ -967,13 +967,13 @@ public:
         return (new OptionDataListParser(param_name));
     }
 
+    /// Pointer to options instances storage.
+    OptionStorage* options_;
     /// Intermediate option storage. This storage is used by
     /// lower level parsers to add new options.  Values held
     /// in this storage are assigned to main storage (options_)
     /// if overall parsing was successful.
     OptionStorage local_options_;
-    /// Pointer to options instances storage.
-    OptionStorage* options_;
     /// Collection of parsers;
     ParserCollection parsers_;
 };

+ 6 - 1
src/bin/dhcp4/dhcp4_messages.mes

@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2012-2013  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
@@ -94,6 +94,11 @@ server is about to open sockets on the specified port.
 The IPv4 DHCP server has received a packet that it is unable to
 interpret. The reason why the packet is invalid is included in the message.
 
+% DHCP4_PACKET_PROCESS_FAIL failed to process packet received from %1: %2
+This is a general catch-all message indicating that the processing of a
+received packet failed.  The reason is given in the message.  The server
+will not send a response but will instead ignore the packet.
+
 % DHCP4_PACKET_RECEIVED %1 (type %2) packet received on interface %3
 A debug message noting that the server has received the specified type of
 packet on the specified interface.  Note that a packet marked as UNKNOWN

+ 97 - 44
src/bin/dhcp4/dhcp4_srv.cc

@@ -42,6 +42,18 @@ using namespace isc::dhcp;
 using namespace isc::log;
 using namespace std;
 
+namespace isc {
+namespace dhcp {
+
+/// @brief file name of a server-id file
+///
+/// Server must store its server identifier in persistent storage that must not
+/// change between restarts. This is name of the file that is created in dataDir
+/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
+/// regular IPv4 address, e.g. 192.0.2.1. Server will create it during
+/// first run and then use it afterwards.
+static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
+
 // These are hardcoded parameters. Currently this is a skeleton server that only
 // grants those options and a single, fixed, hardcoded lease.
 
@@ -98,7 +110,8 @@ Dhcpv4Srv::~Dhcpv4Srv() {
     IfaceMgr::instance().closeSockets();
 }
 
-void Dhcpv4Srv::shutdown() {
+void
+Dhcpv4Srv::shutdown() {
     LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_SHUTDOWN_REQUEST);
     shutdown_ = true;
 }
@@ -136,32 +149,53 @@ Dhcpv4Srv::run() {
             LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL_DATA, DHCP4_QUERY_DATA)
                       .arg(query->toText());
 
-            switch (query->getType()) {
-            case DHCPDISCOVER:
-                rsp = processDiscover(query);
-                break;
-
-            case DHCPREQUEST:
-                rsp = processRequest(query);
-                break;
-
-            case DHCPRELEASE:
-                processRelease(query);
-                break;
-
-            case DHCPDECLINE:
-                processDecline(query);
-                break;
-
-            case DHCPINFORM:
-                processInform(query);
-                break;
-
-            default:
-                // Only action is to output a message if debug is enabled,
-                // and that will be covered by the debug statement before
-                // the "switch" statement.
-                ;
+            try {
+                switch (query->getType()) {
+                case DHCPDISCOVER:
+                    rsp = processDiscover(query);
+                    break;
+
+                case DHCPREQUEST:
+                    rsp = processRequest(query);
+                    break;
+
+                case DHCPRELEASE:
+                    processRelease(query);
+                    break;
+
+                case DHCPDECLINE:
+                    processDecline(query);
+                    break;
+
+                case DHCPINFORM:
+                    processInform(query);
+                    break;
+
+                default:
+                    // Only action is to output a message if debug is enabled,
+                    // and that is covered by the debug statement before the
+                    // "switch" statement.
+                    ;
+                }
+            } catch (const isc::Exception& e) {
+
+                // Catch-all exception (at least for ones based on the isc
+                // Exception class, which covers more or less all that
+                // are explicitly raised in the BIND 10 code).  Just log
+                // the problem and ignore the packet. (The problem is logged
+                // as a debug message because debug is disabled by default -
+                // it prevents a DDOS attack based on the sending of problem
+                // packets.)
+                if (dhcp4_logger.isDebugEnabled(DBG_DHCP4_BASIC)) {
+                    std::string source = "unknown";
+                    HWAddrPtr hwptr = query->getHWAddr();
+                    if (hwptr) {
+                        source = hwptr->toText();
+                    }
+                    LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
+                              DHCP4_PACKET_PROCESS_FAIL)
+                              .arg(source).arg(e.what());
+                }
             }
 
             if (rsp) {
@@ -199,7 +233,8 @@ Dhcpv4Srv::run() {
     return (true);
 }
 
-bool Dhcpv4Srv::loadServerID(const std::string& file_name) {
+bool
+Dhcpv4Srv::loadServerID(const std::string& file_name) {
 
     // load content of the file into a string
     fstream f(file_name.c_str(), ios::in);
@@ -233,7 +268,8 @@ bool Dhcpv4Srv::loadServerID(const std::string& file_name) {
     return (true);
 }
 
-void Dhcpv4Srv::generateServerID() {
+void
+Dhcpv4Srv::generateServerID() {
 
     const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
 
@@ -270,16 +306,19 @@ void Dhcpv4Srv::generateServerID() {
     isc_throw(BadValue, "No suitable interfaces for server-identifier found");
 }
 
-bool Dhcpv4Srv::writeServerID(const std::string& file_name) {
+bool
+Dhcpv4Srv::writeServerID(const std::string& file_name) {
     fstream f(file_name.c_str(), ios::out | ios::trunc);
     if (!f.good()) {
         return (false);
     }
     f << srvidToString(getServerID());
     f.close();
+    return (true);
 }
 
-string Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
+string 
+Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
     if (!srvid) {
         isc_throw(BadValue, "NULL pointer passed to srvidToString()");
     }
@@ -298,7 +337,8 @@ string Dhcpv4Srv::srvidToString(const OptionPtr& srvid) {
     return (addrs[0].toText());
 }
 
-void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
+void
+Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
     answer->setIface(question->getIface());
     answer->setIndex(question->getIndex());
     answer->setCiaddr(question->getCiaddr());
@@ -327,7 +367,8 @@ void Dhcpv4Srv::copyDefaultFields(const Pkt4Ptr& question, Pkt4Ptr& answer) {
     }
 }
 
-void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
+void
+Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
     OptionPtr opt;
 
     // add Message Type Option (type 53)
@@ -339,8 +380,8 @@ void Dhcpv4Srv::appendDefaultOptions(Pkt4Ptr& msg, uint8_t msg_type) {
     // more options will be added here later
 }
 
-
-void Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
+void
+Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
 
     // Get the subnet relevant for the client. We will need it
     // to get the options associated with it.
@@ -411,7 +452,8 @@ Dhcpv4Srv::appendBasicOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
     }
 }
 
-void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
+void
+Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
 
     // We need to select a subnet the client is connected in.
     Subnet4Ptr subnet = selectSubnet(question);
@@ -509,7 +551,8 @@ void Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
     }
 }
 
-OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
+OptionPtr
+Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
     uint32_t netmask = getNetmask4(subnet->get().second);
 
     OptionPtr opt(new OptionInt<uint32_t>(Option::V4,
@@ -518,7 +561,8 @@ OptionPtr Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
     return (opt);
 }
 
-Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
+Pkt4Ptr
+Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
     Pkt4Ptr offer = Pkt4Ptr
         (new Pkt4(DHCPOFFER, discover->getTransid()));
 
@@ -536,7 +580,8 @@ Pkt4Ptr Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
     return (offer);
 }
 
-Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
+Pkt4Ptr
+Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
     Pkt4Ptr ack = Pkt4Ptr
         (new Pkt4(DHCPACK, request->getTransid()));
 
@@ -554,7 +599,8 @@ Pkt4Ptr Dhcpv4Srv::processRequest(Pkt4Ptr& request) {
     return (ack);
 }
 
-void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
+void
+Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
 
     // Try to find client-id
     ClientIdPtr client_id;
@@ -622,11 +668,13 @@ void Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
 
 }
 
-void Dhcpv4Srv::processDecline(Pkt4Ptr& decline) {
+void
+Dhcpv4Srv::processDecline(Pkt4Ptr& /* decline */) {
     /// TODO: Implement this.
 }
 
-Pkt4Ptr Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
+Pkt4Ptr
+Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
     /// TODO: Currently implemented echo mode. Implement this for real
     return (inform);
 }
@@ -662,7 +710,8 @@ Dhcpv4Srv::serverReceivedPacketName(uint8_t type) {
     return (UNKNOWN);
 }
 
-Subnet4Ptr Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
+Subnet4Ptr
+Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
 
     // Is this relayed message?
     IOAddress relay = question->getGiaddr();
@@ -677,7 +726,8 @@ Subnet4Ptr Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) {
     }
 }
 
-void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
+void
+Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
     OptionPtr server_id = pkt->getOption(DHO_DHCP_SERVER_IDENTIFIER);
     switch (serverid) {
     case FORBIDDEN:
@@ -700,3 +750,6 @@ void Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
         ;
     }
 }
+
+}   // namespace dhcp
+}   // namespace isc

+ 0 - 9
src/bin/dhcp4/dhcp4_srv.h

@@ -28,15 +28,6 @@
 namespace isc {
 namespace dhcp {
 
-/// @brief file name of a server-id file
-///
-/// Server must store its server identifier in persistent storage that must not
-/// change between restarts. This is name of the file that is created in dataDir
-/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
-/// regular IPv4 address, e.g. 192.0.2.1. Server will create it during
-/// first run and then use it afterwards.
-static const char* SERVER_ID_FILE = "b10-dhcp4-serverid";
-
 /// @brief DHCPv4 server service.
 ///
 /// This singleton class represents DHCPv4 server. It contains all

+ 4 - 6
src/bin/dhcp4/tests/Makefile.am

@@ -34,6 +34,10 @@ AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
 CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
+if USE_CLANGPP
+# Disable unused parameter warning caused by some Boost headers when compiling with clang
+AM_CXXFLAGS += -Wno-unused-parameter
+endif
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static
@@ -56,12 +60,6 @@ dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
 dhcp4_unittests_SOURCES += config_parser_unittest.cc
 nodist_dhcp4_unittests_SOURCES = ../dhcp4_messages.h ../dhcp4_messages.cc
 
-if USE_CLANGPP
-# Disable unused parameter warning caused by some of the
-# Boost headers when compiling with clang.
-dhcp4_unittests_CXXFLAGS = -Wno-unused-parameter
-endif
-
 dhcp4_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 dhcp4_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 dhcp4_unittests_LDADD = $(GTEST_LDADD)

+ 5 - 3
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

@@ -234,11 +234,13 @@ public:
     /// Check that address was returned from proper range, that its lease
     /// lifetime is correct, that T1 and T2 are returned properly
     /// @param rsp response to be checked
-    /// @param subnet subnet that should be used to verify assigned address and options
+    /// @param subnet subnet that should be used to verify assigned address
+    ///        and options
     /// @param t1_mandatory is T1 mandatory?
     /// @param t2_mandatory is T2 mandatory?
     void checkAddressParams(const Pkt4Ptr& rsp, const SubnetPtr subnet,
-                            bool t1_mandatory = false, bool t2_mandatory = false) {
+                            bool t1_mandatory = false,
+                            bool t2_mandatory = false) {
 
         // Technically inPool implies inRange, but let's be on the safe
         // side and check both.
@@ -268,7 +270,7 @@ public:
         if (opt) {
             EXPECT_EQ(opt->getUint32(), subnet->getT2());
         } else {
-            if (t1_mandatory) {
+            if (t2_mandatory) {
                 ADD_FAILURE() << "Required T2 option missing";
             }
         }

+ 4 - 6
src/bin/dhcp6/Makefile.am

@@ -6,6 +6,10 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/lib/cc -I$(top_builddir)/src/lib/cc
 AM_CPPFLAGS += $(BOOST_INCLUDES)
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
+if USE_CLANGPP
+# Disable unused parameter warning caused by some Boost headers when compiling with clang
+AM_CXXFLAGS += -Wno-unused-parameter
+endif
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static
@@ -53,12 +57,6 @@ b10_dhcp6_SOURCES += dhcp6_srv.cc dhcp6_srv.h
 nodist_b10_dhcp6_SOURCES = dhcp6_messages.h dhcp6_messages.cc
 EXTRA_DIST += dhcp6_messages.mes
 
-if USE_CLANGPP
-# Disable unused parameter warning caused by some of the
-# Boost headers when compiling with clang.
-b10_dhcp6_CXXFLAGS = -Wno-unused-parameter
-endif
-
 b10_dhcp6_LDADD  = $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
 b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
 b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la

+ 2 - 2
src/bin/dhcp6/config_parser.cc

@@ -996,13 +996,13 @@ public:
         return (new OptionDataListParser(param_name));
     }
 
+    /// Pointer to options instances storage.
+    OptionStorage* options_;
     /// Intermediate option storage. This storage is used by
     /// lower level parsers to add new options.  Values held
     /// in this storage are assigned to main storage (options_)
     /// if overall parsing was successful.
     OptionStorage local_options_;
-    /// Pointer to options instances storage.
-    OptionStorage* options_;
     /// Collection of parsers;
     ParserCollection parsers_;
 };

+ 16 - 13
src/bin/dhcp6/dhcp6_messages.mes

@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2012-2013  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
@@ -93,6 +93,11 @@ This message indicates that the server failed to grant (in response to
 received REQUEST) a lease for a given client. There may be many reasons for
 such failure. Each specific failure is logged in a separate log entry.
 
+% DHCP6_PACKET_PROCESS_FAIL processing of %1 message received from %2 failed: %3
+This is a general catch-all message indicating that the processing of the
+specified packet type from the indicated address failed.  The reason is given in the
+message.  The server will not send a response but will instead ignore the packet.
+
 % DHCP6_RELEASE address %1 belonging to client duid=%2, iaid=%3 was released properly.
 This debug message indicates that an address was released properly. It
 is a normal operation during client shutdown.
@@ -132,18 +137,6 @@ IPv6 DHCP server but it is not running.
 During startup the IPv6 DHCP server failed to detect any network
 interfaces and is therefore shutting down.
 
-% DHCP6_NO_SUBNET_DEF_OPT failed to find subnet for address %1 when adding default options
-This warning message indicates that when attempting to add default options
-to a response, the server found that it was not configured to support
-the subnet from which the DHCPv6 request was received.  The packet has
-been ignored.
-
-% DHCP6_NO_SUBNET_REQ_OPT failed to find subnet for address %1 when adding requested options
-This warning message indicates that when attempting to add requested
-options to a response, the server found that it was not configured
-to support the subnet from which the DHCPv6 request was received.
-The packet has been ignored.
-
 % DHCP6_OPEN_SOCKET opening sockets on port %1
 A debug message issued during startup, this indicates that the IPv6 DHCP
 server is about to open sockets on the specified port.
@@ -217,6 +210,16 @@ as a hint for possible requested address.
 % DHCP6_QUERY_DATA received packet length %1, data length %2, data is %3
 A debug message listing the data received from the client or relay.
 
+% DHCP6_RENEW_UNKNOWN_SUBNET RENEW message received from client on unknown subnet (duid=%1, iaid=%2)
+A warning message indicating that a client is attempting to renew his lease,
+but the server does not have any information about the subnet this client belongs
+to. This may mean that faulty the mobile client changed its location and is trying to
+renew its old address (client is supposed to send confirm, not rewew in such cases,
+according to RFC3315) or the server configuration has changed and information about
+existing subnet was removed. Note that in a sense this is worse case of DHCP6_UNKNOWN_RENEW,
+as not only the lease is unknown, but also the subnet is. Depending on the reasons
+of this condition, it may or may not correct on its own.
+
 % DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1 message received from %2 failed the following check: %3
 This message indicates that received DHCPv6 packet is invalid.  This may be due
 to a number of reasons, e.g. the mandatory client-id option is missing,

+ 107 - 56
src/bin/dhcp6/dhcp6_srv.cc

@@ -56,6 +56,16 @@ using namespace std;
 namespace isc {
 namespace dhcp {
 
+/// @brief file name of a server-id file
+///
+/// Server must store its duid in persistent storage that must not change
+/// between restarts. This is name of the file that is created in dataDir
+/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
+/// double digit hex values separated by colons format, e.g.
+/// 01:ff:02:03:06:80:90:ab:cd:ef. Server will create it during first
+/// run and then use it afterwards.
+static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
+
 Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
     : alloc_engine_(), serverid_(), shutdown_(true) {
 
@@ -172,8 +182,8 @@ bool Dhcpv6Srv::run() {
                     break;
 
                 case DHCPV6_RELEASE:
-                rsp = processRelease(query);
-                break;
+                    rsp = processRelease(query);
+                    break;
 
                 case DHCPV6_DECLINE:
                     rsp = processDecline(query);
@@ -189,11 +199,26 @@ bool Dhcpv6Srv::run() {
                     // the "switch" statement.
                     ;
                 }
+
             } catch (const RFCViolation& e) {
                 LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_REQUIRED_OPTIONS_CHECK_FAIL)
                     .arg(query->getName())
                     .arg(query->getRemoteAddr())
                     .arg(e.what());
+
+            } catch (const isc::Exception& e) {
+
+                // Catch-all exception (at least for ones based on the isc
+                // Exception class, which covers more or less all that
+                // are explicitly raised in the BIND 10 code).  Just log
+                // the problem and ignore the packet. (The problem is logged
+                // as a debug message because debug is disabled by default -
+                // it prevents a DDOS attack based on the sending of problem
+                // packets.)
+                LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_PROCESS_FAIL)
+                    .arg(query->getName())
+                    .arg(query->getRemoteAddr())
+                    .arg(e.what());
             }
 
             if (rsp) {
@@ -256,7 +281,8 @@ bool Dhcpv6Srv::loadServerID(const std::string& file_name) {
     return (true);
 }
 
-std::string Dhcpv6Srv::duidToString(const OptionPtr& opt) {
+std::string
+Dhcpv6Srv::duidToString(const OptionPtr& opt) {
     stringstream tmp;
 
     OptionBuffer data = opt->getData();
@@ -275,16 +301,19 @@ std::string Dhcpv6Srv::duidToString(const OptionPtr& opt) {
     return tmp.str();
 }
 
-bool Dhcpv6Srv::writeServerID(const std::string& file_name) {
+bool
+Dhcpv6Srv::writeServerID(const std::string& file_name) {
     fstream f(file_name.c_str(), ios::out | ios::trunc);
     if (!f.good()) {
         return (false);
     }
     f << duidToString(getServerID());
     f.close();
+    return (true);
 }
 
-void Dhcpv6Srv::generateServerID() {
+void
+Dhcpv6Srv::generateServerID() {
 
     /// @todo: This code implements support for DUID-LLT (the recommended one).
     /// We should eventually add support for other DUID types: DUID-LL, DUID-EN
@@ -367,7 +396,8 @@ void Dhcpv6Srv::generateServerID() {
                                      srvid.begin(), srvid.end()));
 }
 
-void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
+void
+Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
     // Add client-id.
     OptionPtr clientid = question->getOption(D6O_CLIENTID);
     if (clientid) {
@@ -377,28 +407,22 @@ void Dhcpv6Srv::copyDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
     // TODO: Should throw if there is no client-id (except anonymous INF-REQUEST)
 }
 
-void Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
+void
+Dhcpv6Srv::appendDefaultOptions(const Pkt6Ptr&, Pkt6Ptr& answer) {
     // add server-id
     answer->addOption(getServerID());
-
-    // Get the subnet object. It holds options to be sent to the client
-    // that belongs to the particular subnet.
-    Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(question->getRemoteAddr());
-    // Warn if subnet is not supported and quit.
-    if (!subnet) {
-        LOG_WARN(dhcp6_logger, DHCP6_NO_SUBNET_DEF_OPT)
-            .arg(question->getRemoteAddr().toText());
-        return;
-    }
-
 }
 
-void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
-    // Get the subnet for a particular address.
-    Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(question->getRemoteAddr());
+void
+Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
+    // Get the configured subnet suitable for the incoming packet.
+    Subnet6Ptr subnet = selectSubnet(question);
+    // Leave if there is no subnet matching the incoming packet.
+    // There is no need to log the error message here because
+    // it will be logged in the assignLease() when it fails to
+    // pick the suitable subnet. We don't want to duplicate
+    // error messages in such case.
     if (!subnet) {
-        LOG_WARN(dhcp6_logger, DHCP6_NO_SUBNET_REQ_OPT)
-            .arg(question->getRemoteAddr().toText());
         return;
     }
 
@@ -420,7 +444,8 @@ void Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer)
     }
 }
 
-OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
+OptionPtr
+Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
     // @todo This function uses OptionCustom class to manage contents
     // of the data fields. Since this this option is frequently used
     // it may be good to implement dedicated class to avoid performance
@@ -446,8 +471,9 @@ OptionPtr Dhcpv6Srv::createStatusCode(uint16_t code, const std::string& text) {
     return (option_status);
 }
 
-void Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
-                            RequirementLevel serverid) {
+void
+Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
+                       RequirementLevel serverid) {
     Option::OptionCollection client_ids = pkt->getOptions(D6O_CLIENTID);
     switch (clientid) {
     case MANDATORY:
@@ -494,7 +520,8 @@ void Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
     }
 }
 
-Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
+Subnet6Ptr
+Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
 
     /// @todo: pass interface information only if received direct (non-relayed) message
 
@@ -510,7 +537,8 @@ Subnet6Ptr Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
     return (subnet);
 }
 
-void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
+void
+Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
 
     // We need to allocate addresses for all IA_NA options in the client's
     // question (i.e. SOLICIT or REQUEST) message.
@@ -528,9 +556,7 @@ void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
         // thing this client can get is some global information (like DNS
         // servers).
 
-        // perhaps this should be logged on some higher level? This is most likely
-        // configuration bug.
-        LOG_ERROR(dhcp6_logger, DHCP6_SUBNET_SELECTION_FAILED)
+        LOG_WARN(dhcp6_logger, DHCP6_SUBNET_SELECTION_FAILED)
             .arg(question->getRemoteAddr().toText())
             .arg(question->getName());
 
@@ -579,8 +605,9 @@ void Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
     }
 }
 
-OptionPtr Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
-                                 Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
+OptionPtr
+Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
+                       Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
     // If there is no subnet selected for handling this IA_NA, the only thing to do left is
     // to say that we are sorry, but the user won't get an address. As a convenience, we
     // use a different status text to indicate that (compare to the same status code,
@@ -663,11 +690,10 @@ OptionPtr Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
         // cause of that failure. The only thing left is to insert
         // status code to pass the sad news to the client.
 
-        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, fake_allocation?
-                  DHCP6_LEASE_ADVERT_FAIL:DHCP6_LEASE_ALLOC_FAIL)
+        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, fake_allocation ?
+                  DHCP6_LEASE_ADVERT_FAIL : DHCP6_LEASE_ALLOC_FAIL)
             .arg(duid?duid->toText():"(no-duid)")
-            .arg(ia->getIAID())
-            .arg(subnet->toText());
+            .arg(ia->getIAID());
 
         ia_rsp->addOption(createStatusCode(STATUS_NoAddrsAvail,
                           "Sorry, no address could be allocated."));
@@ -675,8 +701,24 @@ OptionPtr Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
     return (ia_rsp);
 }
 
-OptionPtr Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
-                                Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) {
+OptionPtr
+Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
+                      Pkt6Ptr /* question */, boost::shared_ptr<Option6IA> ia) {
+    if (!subnet) {
+        // There's no subnet select for this client. There's nothing to renew.
+        boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
+
+        // Insert status code NoAddrsAvail.
+        ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
+                          "Sorry, no known leases for this duid/iaid."));
+
+        LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_RENEW_UNKNOWN_SUBNET)
+            .arg(duid->toText())
+            .arg(ia->getIAID());
+
+        return (ia_rsp);
+    }
+
     Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(*duid, ia->getIAID(),
                                                             subnet->getID());
 
@@ -719,7 +761,8 @@ OptionPtr Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
     return (ia_rsp);
 }
 
-void Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
+void
+Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
 
     // We need to renew addresses for all IA_NA options in the client's
     // RENEW message.
@@ -737,9 +780,9 @@ void Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
         // thing this client can get is some global information (like DNS
         // servers).
 
-        // perhaps this should be logged on some higher level? This is most likely
-        // configuration bug.
-        LOG_ERROR(dhcp6_logger, DHCP6_SUBNET_SELECTION_FAILED);
+        LOG_WARN(dhcp6_logger, DHCP6_SUBNET_SELECTION_FAILED)
+            .arg(renew->getRemoteAddr().toText())
+            .arg(renew->getName());
     } else {
         LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, DHCP6_SUBNET_SELECTED)
             .arg(subnet->toText());
@@ -775,7 +818,8 @@ void Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply) {
     }
 }
 
-void Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
+void
+Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
 
     // We need to release addresses for all IA_NA options in the client's
     // RELEASE message.
@@ -831,9 +875,9 @@ void Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
                      "Summary status for all processed IA_NAs"));
 }
 
-OptionPtr Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr question,
-                                  int& general_status,
-                                  boost::shared_ptr<Option6IA> ia) {
+OptionPtr
+Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr /* question */,
+                        int& general_status, boost::shared_ptr<Option6IA> ia) {
     // Release can be done in one of two ways:
     // Approach 1: extract address from client's IA_NA and see if it belongs
     // to this particular client.
@@ -942,8 +986,8 @@ OptionPtr Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, Pkt6Ptr question,
     }
 }
 
-
-Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
+Pkt6Ptr
+Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
 
     sanityCheck(solicit, MANDATORY, FORBIDDEN);
 
@@ -958,7 +1002,8 @@ Pkt6Ptr Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
     return (advertise);
 }
 
-Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
+Pkt6Ptr
+Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
 
     sanityCheck(request, MANDATORY, MANDATORY);
 
@@ -973,7 +1018,8 @@ Pkt6Ptr Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
     return (reply);
 }
 
-Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
+Pkt6Ptr
+Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
 
     sanityCheck(renew, MANDATORY, MANDATORY);
 
@@ -988,19 +1034,22 @@ Pkt6Ptr Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
     return reply;
 }
 
-Pkt6Ptr Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
+Pkt6Ptr
+Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
     /// @todo: Implement this
     Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid()));
     return reply;
 }
 
-Pkt6Ptr Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
+Pkt6Ptr
+Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
     /// @todo: Implement this
     Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, confirm->getTransid()));
     return reply;
 }
 
-Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
+Pkt6Ptr
+Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
 
     sanityCheck(release, MANDATORY, MANDATORY);
 
@@ -1014,13 +1063,15 @@ Pkt6Ptr Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
     return reply;
 }
 
-Pkt6Ptr Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
+Pkt6Ptr
+Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
     /// @todo: Implement this
     Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid()));
     return reply;
 }
 
-Pkt6Ptr Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
+Pkt6Ptr
+Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
     /// @todo: Implement this
     Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, infRequest->getTransid()));
     return reply;

+ 0 - 10
src/bin/dhcp6/dhcp6_srv.h

@@ -31,16 +31,6 @@
 namespace isc {
 namespace dhcp {
 
-/// @brief file name of a server-id file
-///
-/// Server must store its duid in persistent storage that must not change
-/// between restarts. This is name of the file that is created in dataDir
-/// (see isc::dhcp::CfgMgr::getDataDir()). It is a text file that uses
-/// double digit hex values separated by colons format, e.g.
-/// 01:ff:02:03:06:80:90:ab:cd:ef. Server will create it during first
-/// run and then use it afterwards.
-static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
-
 /// @brief DHCPv6 server service.
 ///
 /// This class represents DHCPv6 server. It contains all

+ 4 - 6
src/bin/dhcp6/tests/Makefile.am

@@ -30,6 +30,10 @@ AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
 CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
 
 AM_CXXFLAGS = $(B10_CXXFLAGS)
+if USE_CLANGPP
+# Disable unused parameter warning caused by some Boost headers when compiling with clang
+AM_CXXFLAGS += -Wno-unused-parameter
+endif
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static
@@ -53,12 +57,6 @@ dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
 dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
 nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
 
-if USE_CLANGPP
-# Disable unused parameter warning caused by some of the
-# Boost headers when compiling with clang.
-dhcp6_unittests_CXXFLAGS = -Wno-unused-parameter
-endif
-
 dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 dhcp6_unittests_LDADD = $(GTEST_LDADD)

+ 1 - 1
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -277,9 +277,9 @@ public:
                             expected_data_len));
     }
 
+    int rcode_;
     Dhcpv6Srv srv_;
 
-    int rcode_;
     ConstElementPtr comment_;
 
     string valid_iface_;

+ 2 - 1
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -222,7 +222,8 @@ public:
     // Check that generated IAADDR option contains expected address.
     void checkIAAddr(const boost::shared_ptr<Option6IAAddr>& addr,
                      const IOAddress& expected_addr,
-                     uint32_t expected_preferred, uint32_t expected_valid) {
+                     uint32_t /* expected_preferred */,
+                     uint32_t /* expected_valid */) {
 
         // Check that the assigned address is indeed from the configured pool.
         // Note that when comparing addresses, we compare the textual

+ 1 - 1
src/bin/loadzone/loadzone.py.in

@@ -164,7 +164,7 @@ class LoadZoneRunner:
             self._zone_class = RRClass(options.zone_class)
         except isc.dns.InvalidRRClass as ex:
             raise BadArgument('Invalid zone class: ' + str(ex))
-        if self._zone_class != RRClass.IN():
+        if self._zone_class != RRClass.IN:
             raise BadArgument("RR class is not supported: " +
                               str(self._zone_class))
 

+ 3 - 3
src/bin/loadzone/tests/loadzone_test.py

@@ -79,7 +79,7 @@ class TestLoadZoneRunner(unittest.TestCase):
         self.assertEqual(DATASRC_CONFIG, self.__runner._datasrc_config)
         self.assertEqual('sqlite3', self.__runner._datasrc_type) # default
         self.assertEqual(10000, self.__runner._report_interval) # default
-        self.assertEqual(RRClass.IN(), self.__runner._zone_class) # default
+        self.assertEqual(RRClass.IN, self.__runner._zone_class) # default
         self.assertEqual('INFO', self.__runner._log_severity) # default
         self.assertEqual(0, self.__runner._log_debuglevel)
 
@@ -135,7 +135,7 @@ class TestLoadZoneRunner(unittest.TestCase):
                           'memory')
 
     def __common_load_setup(self):
-        self.__runner._zone_class = RRClass.IN()
+        self.__runner._zone_class = RRClass.IN
         self.__runner._zone_name = TEST_ZONE_NAME
         self.__runner._zone_file = NEW_ZONE_TXT_FILE
         self.__runner._datasrc_type = 'sqlite3'
@@ -159,7 +159,7 @@ class TestLoadZoneRunner(unittest.TestCase):
             self.assertEqual(client.NOTFOUND, result)
             return
         self.assertEqual(client.SUCCESS, result)
-        result, rrset, _ = finder.find(zone_name, RRType.SOA())
+        result, rrset, _ = finder.find(zone_name, RRType.SOA)
         if soa_txt:
             self.assertEqual(finder.SUCCESS, result)
             self.assertEqual(soa_txt, rrset.to_text())

+ 4 - 4
src/bin/msgq/msgq.py.in

@@ -411,7 +411,7 @@ class MsgQ:
             if isinstance(err, MsgQCloseOnReceive) and not err.partial_read:
                 logger.debug(TRACE_BASIC, MSGQ_CLOSE_ON_RECV, fd)
             else:
-                logger.error(MSGQ_RECV_ERR, fd, err)
+                logger.error(MSGQ_RECV_ERROR, fd, err)
             self.kill_socket(fd, sock)
             return
 
@@ -419,7 +419,7 @@ class MsgQ:
             routingmsg = isc.cc.message.from_wire(routing)
         except DecodeError as err:
             self.kill_socket(fd, sock)
-            logger.error(MSGQ_HDR_DECODE_ERR, fd, err)
+            logger.error(MSGQ_HDR_DECODE_ERROR, fd, err)
             return
 
         self.process_command(fd, sock, routingmsg, data)
@@ -492,7 +492,7 @@ class MsgQ:
                 if e.errno == errno.EPIPE:
                     logger.warn(MSGQ_CLOSE_ON_SEND, sock.fileno())
                 else:
-                    logger.error(MSGQ_SEND_ERR, sock.fileno(),
+                    logger.error(MSGQ_SEND_ERROR, sock.fileno(),
                                  errno.errorcode[e.errno])
                 self.kill_socket(sock.fileno(), sock)
                 return None
@@ -620,7 +620,7 @@ class MsgQ:
                 if err.args[0] == errno.EINTR:
                     events = []
                 else:
-                    logger.fatal(MSGQ_POLL_ERR, err)
+                    logger.fatal(MSGQ_POLL_ERROR, err)
                     break
             with self.__lock:
                 for (fd, event) in events:

+ 4 - 4
src/bin/msgq/msgq_messages.mes

@@ -62,7 +62,7 @@ Debug message. The message queue received a configuration update, handling it.
 % MSGQ_EXITING exiting
 The msgq daemon is exiting.
 
-% MSGQ_HDR_DECODE_ERR Error decoding header received from socket %1: %2
+% MSGQ_HDR_DECODE_ERROR Error decoding header received from socket %1: %2
 The socket with mentioned file descriptor sent a packet. However, it was not
 possible to decode the routing header of the packet. The packet is ignored.
 This may be caused by a programmer error (one of the components sending invalid
@@ -85,7 +85,7 @@ Debug message. The listener is trying to open a listening socket.
 Debug message. The message queue successfully opened a listening socket and
 waits for incoming connections.
 
-% MSGQ_POLL_ERR Error while polling for events: %1
+% MSGQ_POLL_ERROR Error while polling for events: %1
 A low-level error happened when waiting for events, the error is logged. The
 reason for this varies, but it usually means the system is short on some
 resources.
@@ -96,7 +96,7 @@ happen and it is either a programmer error or OS bug. The event is ignored. The
 number noted as the event is the raw encoded value, which might be useful to
 the authors when figuring the problem out.
 
-% MSGQ_RECV_ERR Error reading from socket %1: %2
+% MSGQ_RECV_ERROR Error reading from socket %1: %2
 There was a low-level error when reading from a socket. The error is logged and
 the corresponding socket is dropped.  The errors include receiving
 broken or (non empty but) incomplete data.  In either case it usually suggests
@@ -119,7 +119,7 @@ on shutdown unless there's really something unexpected.
 % MSGQ_RECV_HDR Received header: %1
 Debug message. This message includes the whole routing header of a packet.
 
-% MSGQ_SEND_ERR Error while sending to socket %1: %2
+% MSGQ_SEND_ERROR Error while sending to socket %1: %2
 There was a low-level error when sending data to a socket. The error is logged
 and the corresponding socket is dropped.
 

+ 8 - 5
src/bin/resolver/resolver.cc

@@ -431,13 +431,14 @@ Resolver::processMessage(const IOMessage& io_message,
 
         // Ignore all responses.
         if (query_message->getHeaderFlag(Message::HEADERFLAG_QR)) {
-            LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO, RESOLVER_UNEXPECTED_RESPONSE);
+            LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
+                      RESOLVER_UNEXPECTED_RESPONSE);
             server->resume(false);
             return;
         }
     } catch (const Exception& ex) {
-        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO, RESOLVER_HEADER_ERROR)
-                  .arg(ex.what());
+        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
+                  RESOLVER_HEADER_PROCESSING_FAILED).arg(ex.what());
         server->resume(false);
         return;
     }
@@ -446,14 +447,16 @@ Resolver::processMessage(const IOMessage& io_message,
     try {
         query_message->fromWire(request_buffer);
     } catch (const DNSProtocolError& error) {
-        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO, RESOLVER_PROTOCOL_ERROR)
+        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
+                  RESOLVER_PROTOCOL_BODY_PARSE_FAILED)
                   .arg(error.what()).arg(error.getRcode());
         makeErrorMessage(query_message, answer_message,
                          buffer, error.getRcode());
         server->resume(true);
         return;
     } catch (const Exception& ex) {
-        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO, RESOLVER_MESSAGE_ERROR)
+        LOG_DEBUG(resolver_logger, RESOLVER_DBG_IO,
+                  RESOLVER_MESSAGE_PROCESSING_FAILED)
                   .arg(ex.what()).arg(Rcode::SERVFAIL());
         makeErrorMessage(query_message, answer_message,
                          buffer, Rcode::SERVFAIL());

+ 3 - 10
src/bin/resolver/resolver_messages.mes

@@ -81,7 +81,7 @@ has passed a set of checks (message is well-formed, it is allowed by the
 ACL, it is a supported opcode, etc.) and is being forwarded to upstream
 servers.
 
-% RESOLVER_HEADER_ERROR message received, exception when processing header: %1
+% RESOLVER_HEADER_PROCESSING_FAILED message received, exception when processing header: %1
 This is a debug message from the resolver noting that an exception
 occurred during the processing of a received packet.  The packet has
 been dropped.
@@ -97,7 +97,7 @@ During the update of the resolver's configuration parameters, the value
 of the lookup timeout was found to be too small.  The configuration
 update will not be applied.
 
-% RESOLVER_MESSAGE_ERROR error parsing received message: %1 - returning %2
+% RESOLVER_MESSAGE_PROCESSING_FAILED error parsing received message: %1 - returning %2
 This is a debug message noting that parsing of the body of a received
 message by the resolver failed due to some error (although the parsing of
 the header succeeded).  The message parameters give a textual description
@@ -135,18 +135,11 @@ A warning message issued during resolver startup, this indicates that
 no root addresses have been set.  This may be because the resolver will
 get them from a priming query.
 
-% RESOLVER_PARSE_ERROR error parsing received message: %1 - returning %2
-This is a debug message noting that the resolver received a message and
-the parsing of the body of the message failed due to some non-protocol
-related reason (although the parsing of the header succeeded).
-The message parameters give a textual description of the problem and
-the RCODE returned.
-
 % RESOLVER_PRINT_COMMAND print message command, arguments are: %1
 This debug message is logged when a "print_message" command is received
 by the resolver over the command channel.
 
-% RESOLVER_PROTOCOL_ERROR protocol error parsing received message: %1 - returning %2
+% RESOLVER_PROTOCOL_BODY_PARSE_FAILED protocol error parsing received message: %1 - returning %2
 This is a debug message noting that the resolver received a message and
 the parsing of the body of the message failed due to some protocol error
 (although the parsing of the header succeeded).  The message parameters

+ 8 - 1
src/bin/sockcreator/tests/sockcreator_tests.cc

@@ -12,6 +12,8 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+#include <config.h>
+
 #include "../sockcreator.h"
 
 #include <util/unittests/fork.h>
@@ -195,7 +197,12 @@ TEST(get_sock, tcp4_create) {
     testAnyCreate<sockaddr_in>(SOCK_STREAM, tcpCheck);
 }
 
-TEST(get_sock, udp6_create) {
+#ifdef HAVE_BROKEN_GET_IPV6_USE_MIN_MTU
+TEST(get_sock, DISABLED_udp6_create)
+#else
+TEST(get_sock, udp6_create)
+#endif
+{
     testAnyCreate<sockaddr_in6>(SOCK_DGRAM, udpCheck<sockaddr_in6>);
 }
 

+ 2 - 1
src/bin/stats/stats.py.in

@@ -26,7 +26,8 @@ from optparse import OptionParser, OptionValueError
 import errno
 import select
 
-import isc
+import isc.cc
+import isc.config
 import isc.util.process
 import isc.log
 from isc.log_messages.stats_messages import *

+ 4 - 4
src/bin/stats/stats_httpd.py.in

@@ -130,9 +130,9 @@ def item_name_list(element, identifier):
     return ret
 
 class HttpHandler(http.server.BaseHTTPRequestHandler):
-    """HTTP handler class for HttpServer class. The class inhrits the super
-    class http.server.BaseHTTPRequestHandler. It implemets do_GET()
-    and do_HEAD() and orverrides log_message()"""
+    """HTTP handler class for HttpServer class. The class inherits the super
+    class http.server.BaseHTTPRequestHandler. It implements do_GET()
+    and do_HEAD() and overrides log_message()"""
     def do_GET(self):
         body = self.send_head()
         if body is not None:
@@ -413,7 +413,7 @@ class StatsHttpd:
         try:
             self.open_httpd()
         except HttpServerError as err:
-            logger.error(STATSHTTPD_SERVER_ERROR, err)
+            logger.error(STATSHTTPD_SERVER_INIT_ERROR, err)
             # restore old config
             self.load_config(old_config)
             self.open_httpd()

+ 1 - 1
src/bin/stats/stats_httpd_messages.mes

@@ -68,7 +68,7 @@ corresponding to the requested URI is incorrect.
 An internal error occurred while handling an HTTP request. An HTTP 500
 response will be sent back, and the specific error is printed. This
 is an error condition that likely points to a module that is not
-responding correctly to statistic requests.
+responding correctly to statistics requests.
 
 % STATSHTTPD_SERVER_INIT_ERROR HTTP server initialization error: %1
 There was a problem initializing the HTTP server in the stats-httpd

+ 2 - 0
src/bin/stats/tests/b10-stats-httpd_test.py

@@ -34,6 +34,7 @@ import http.client
 import xml.etree.ElementTree
 import random
 import urllib.parse
+import sys
 # load this module for xml validation with xsd. For this test, an
 # installation of lxml is required in advance. See http://lxml.de/.
 try:
@@ -250,6 +251,7 @@ class TestHttpHandler(unittest.TestCase):
         # reset the signal handler
         self.sig_handler.reset()
 
+    @unittest.skipIf(sys.version_info >= (3, 3), "Unsupported in Python 3.3 or higher")
     @unittest.skipUnless(xml_parser, "skipping the test using XMLParser")
     def test_do_GET(self):
         self.assertTrue(type(self.stats_httpd.httpd) is list)

+ 4 - 0
src/bin/stats/tests/b10-stats_test.py

@@ -27,6 +27,7 @@ import threading
 import io
 import time
 import imp
+import sys
 
 import stats
 import isc.log
@@ -605,6 +606,7 @@ class TestStats(unittest.TestCase):
         self.assertEqual(self.stats.update_statistics_data(
                 'Foo', 'foo1', _test_exp6), ['unknown module name: Foo'])
 
+    @unittest.skipIf(sys.version_info >= (3, 3), "Unsupported in Python 3.3 or higher")
     def test_update_statistics_data_withmid(self):
         self.stats = stats.Stats()
         self.stats.do_polling()
@@ -736,6 +738,7 @@ class TestStats(unittest.TestCase):
                          isc.config.create_answer(0))
         self.assertFalse(self.stats.running)
 
+    @unittest.skipIf(sys.version_info >= (3, 3), "Unsupported in Python 3.3 or higher")
     def test_command_show(self):
         # two auth instances invoked
         list_auth = [ self.base.auth.server,
@@ -1143,6 +1146,7 @@ class TestStats(unittest.TestCase):
                          isc.config.create_answer(
                 1, "module name is not specified"))
 
+    @unittest.skipIf(sys.version_info >= (3, 3), "Unsupported in Python 3.3 or higher")
     def test_polling(self):
         stats_server = ThreadingServerManager(MyStats)
         stat = stats_server.server

+ 1 - 13
src/bin/sysinfo/run_sysinfo.sh.in

@@ -20,20 +20,8 @@ export PYTHON_EXEC
 
 SYSINFO_PATH=@abs_top_builddir@/src/bin/sysinfo
 
-# Note: we shouldn't need log_messages and lib/dns except for the seemingly
-# necessary dependency due to the automatic import in the isc package (its
-# __init__.py imports some other modules)
-# #2145 should eliminate the need for them.
-PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_srcdir@/src/lib/python:@abs_top_builddir@/src/lib/python/isc/log_messages:@abs_top_builddir@/src/lib/dns/python/.libs
+PYTHONPATH=@abs_top_builddir@/src/lib/python:@abs_top_srcdir@/src/lib/python
 export PYTHONPATH
 
-# Likewise, we need only because isc.log requires some loadable modules.
-# sysinfo itself shouldn't need any of them.
-SET_ENV_LIBRARY_PATH=@SET_ENV_LIBRARY_PATH@
-if test $SET_ENV_LIBRARY_PATH = yes; then
-	@ENV_LIBRARY_PATH@=@abs_top_builddir@/src/lib/dns/.libs:@abs_top_builddir@/src/lib/dns/python/.libs:@abs_top_builddir@/src/lib/cryptolink/.libs:@abs_top_builddir@/src/lib/cc/.libs:@abs_top_builddir@/src/lib/config/.libs:@abs_top_builddir@/src/lib/log/.libs:@abs_top_builddir@/src/lib/acl/.libs:@abs_top_builddir@/src/lib/util/.libs:@abs_top_builddir@/src/lib/util/io/.libs:@abs_top_builddir@/src/lib/exceptions/.libs:@abs_top_builddir@/src/lib/datasrc/.libs:$@ENV_LIBRARY_PATH@
-	export @ENV_LIBRARY_PATH@
-fi
-
 cd ${SYSINFO_PATH}
 exec ${PYTHON_EXEC} -O sysinfo.py "$@"

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


+ 31 - 31
src/bin/xfrin/xfrin.py.in

@@ -78,7 +78,7 @@ DBG_XFRIN_TRACE = logger.DBGLVL_TRACE_BASIC
 # (TODO: have similar support to get default values for command
 # arguments as we do for config options)
 DEFAULT_MASTER_PORT = 53
-DEFAULT_ZONE_CLASS = RRClass.IN()
+DEFAULT_ZONE_CLASS = RRClass.IN
 
 __version__ = 'BIND10'
 
@@ -135,7 +135,7 @@ def _check_zone_class(zone_class_str):
     """If the given argument is a string: checks if the given class is
        a valid one, and returns an RRClass object if so.
        Raises XfrinZoneInfoException if not.
-       If it is None, this function returns the default RRClass.IN()"""
+       If it is None, this function returns the default RRClass.IN"""
     if zone_class_str is None:
         return DEFAULT_ZONE_CLASS
     try:
@@ -316,12 +316,12 @@ class XfrinState:
 
 class XfrinInitialSOA(XfrinState):
     def handle_rr(self, conn, rr):
-        if rr.get_type() != RRType.SOA():
+        if rr.get_type() != RRType.SOA:
             raise XfrinProtocolError('First RR in zone transfer must be SOA ('
                                      + rr.get_type().to_text() + ' received)')
         conn._end_serial = get_soa_serial(rr.get_rdata()[0])
 
-        if conn._request_type == RRType.IXFR() and \
+        if conn._request_type == RRType.IXFR and \
                 conn._end_serial <= conn._request_serial:
             logger.info(XFRIN_IXFR_UPTODATE, conn.zone_str(),
                         conn._request_serial, conn._end_serial)
@@ -364,8 +364,8 @@ class XfrinFirstData(XfrinState):
         http://www.ietf.org/mail-archive/web/dnsext/current/msg07908.html
 
         '''
-        if conn._request_type == RRType.IXFR() and \
-                rr.get_type() == RRType.SOA() and \
+        if conn._request_type == RRType.IXFR and \
+                rr.get_type() == RRType.SOA and \
                 conn._request_serial == get_soa_serial(rr.get_rdata()[0]):
             logger.debug(DBG_XFRIN_TRACE, XFRIN_GOT_INCREMENTAL_RESP,
                          conn.zone_str())
@@ -382,7 +382,7 @@ class XfrinFirstData(XfrinState):
 
 class XfrinIXFRDeleteSOA(XfrinState):
     def handle_rr(self, conn, rr):
-        if rr.get_type() != RRType.SOA():
+        if rr.get_type() != RRType.SOA:
             # this shouldn't happen; should this occur it means an internal
             # bug.
             raise XfrinException(rr.get_type().to_text() +
@@ -402,7 +402,7 @@ class XfrinIXFRDeleteSOA(XfrinState):
 
 class XfrinIXFRDelete(XfrinState):
     def handle_rr(self, conn, rr):
-        if rr.get_type() == RRType.SOA():
+        if rr.get_type() == RRType.SOA:
             # This is the only place where current_serial is set
             conn._current_serial = get_soa_serial(rr.get_rdata()[0])
             self.set_xfrstate(conn, XfrinIXFRAddSOA())
@@ -413,7 +413,7 @@ class XfrinIXFRDelete(XfrinState):
 
 class XfrinIXFRAddSOA(XfrinState):
     def handle_rr(self, conn, rr):
-        if rr.get_type() != RRType.SOA():
+        if rr.get_type() != RRType.SOA:
             # this shouldn't happen; should this occur it means an internal
             # bug.
             raise XfrinException(rr.get_type().to_text() +
@@ -425,7 +425,7 @@ class XfrinIXFRAddSOA(XfrinState):
 
 class XfrinIXFRAdd(XfrinState):
     def handle_rr(self, conn, rr):
-        if rr.get_type() == RRType.SOA():
+        if rr.get_type() == RRType.SOA:
             # This SOA marks the end of a difference sequence
             conn.get_transfer_stats().ixfr_changeset_count += 1
             soa_serial = get_soa_serial(rr.get_rdata()[0])
@@ -480,7 +480,7 @@ class XfrinAXFR(XfrinState):
         Handle the RR by putting it into the zone.
         """
         conn._diff.add_data(rr)
-        if rr.get_type() == RRType.SOA():
+        if rr.get_type() == RRType.SOA:
             # SOA means end.  Don't commit it yet - we need to perform
             # post-transfer checks
 
@@ -662,7 +662,7 @@ class XfrinConnection(asyncore.dispatcher):
             result, finder = self._datasrc_client.find_zone(self._zone_name)
         if result != DataSourceClient.SUCCESS:
             return None
-        result, soa_rrset, _ = finder.find(self._zone_name, RRType.SOA())
+        result, soa_rrset, _ = finder.find(self._zone_name, RRType.SOA)
         if result != ZoneFinder.SUCCESS:
             logger.info(XFRIN_ZONE_NO_SOA, self.zone_str())
             return None
@@ -714,8 +714,8 @@ class XfrinConnection(asyncore.dispatcher):
         query_id = random.randint(0, 0xFFFF)
         self._query_id = query_id
         msg.set_qid(query_id)
-        msg.set_opcode(Opcode.QUERY())
-        msg.set_rcode(Rcode.NOERROR())
+        msg.set_opcode(Opcode.QUERY)
+        msg.set_rcode(Rcode.NOERROR)
         msg.add_question(Question(self._zone_name, self._rrclass, query_type))
 
         # Remember our serial, if known
@@ -723,7 +723,7 @@ class XfrinConnection(asyncore.dispatcher):
             if self._zone_soa is not None else None
 
         # Set the authority section with our SOA for IXFR
-        if query_type == RRType.IXFR():
+        if query_type == RRType.IXFR:
             if self._zone_soa is None:
                 # (incremental) IXFR doesn't work without known SOA
                 raise XfrinException('Failed to create IXFR query due to no ' +
@@ -855,7 +855,7 @@ class XfrinConnection(asyncore.dispatcher):
         resp_question = msg.get_question()[0]
         if resp_question.get_name() != self._zone_name or \
                 resp_question.get_class() != self._rrclass or \
-                resp_question.get_type() != RRType.SOA():
+                resp_question.get_type() != RRType.SOA:
             raise XfrinProtocolError('Invalid response to SOA query: '
                                      'question mismatch: ' +
                                      str(resp_question))
@@ -863,21 +863,21 @@ class XfrinConnection(asyncore.dispatcher):
         # Look into the answer section for SOA
         soa = None
         for rr in msg.get_section(Message.SECTION_ANSWER):
-            if rr.get_type() == RRType.SOA():
+            if rr.get_type() == RRType.SOA:
                 if soa is not None:
                     raise XfrinProtocolError('SOA response had multiple SOAs')
                 soa = rr
             # There should not be a CNAME record at top of zone.
-            if rr.get_type() == RRType.CNAME():
+            if rr.get_type() == RRType.CNAME:
                 raise XfrinProtocolError('SOA query resulted in CNAME')
 
         # If SOA is not found, try to figure out the reason then report it.
         if soa is None:
             # See if we have any SOA records in the authority section.
             for rr in msg.get_section(Message.SECTION_AUTHORITY):
-                if rr.get_type() == RRType.NS():
+                if rr.get_type() == RRType.NS:
                     raise XfrinProtocolError('SOA query resulted in referral')
-                if rr.get_type() == RRType.SOA():
+                if rr.get_type() == RRType.SOA:
                     raise XfrinProtocolError('SOA query resulted in NODATA')
             raise XfrinProtocolError('No SOA record found in response to ' +
                                      'SOA query')
@@ -901,7 +901,7 @@ class XfrinConnection(asyncore.dispatcher):
 
         '''
 
-        self._send_query(RRType.SOA())
+        self._send_query(RRType.SOA)
         data_len = self._get_request_response(2)
         msg_len = socket.htons(struct.unpack('H', data_len)[0])
         soa_response = self._get_request_response(msg_len)
@@ -925,7 +925,7 @@ class XfrinConnection(asyncore.dispatcher):
 
         return XFRIN_OK
 
-    def do_xfrin(self, check_soa, request_type=RRType.AXFR()):
+    def do_xfrin(self, check_soa, request_type=RRType.AXFR):
         '''Do an xfr session by sending xfr request and parsing responses.'''
 
         try:
@@ -933,7 +933,7 @@ class XfrinConnection(asyncore.dispatcher):
             self._request_type = request_type
             # Right now RRType.[IA]XFR().to_text() is 'TYPExxx', so we need
             # to hardcode here.
-            req_str = 'IXFR' if request_type == RRType.IXFR() else 'AXFR'
+            req_str = 'IXFR' if request_type == RRType.IXFR else 'AXFR'
             if check_soa:
                 self._check_soa_serial()
                 self.close()
@@ -1024,7 +1024,7 @@ class XfrinConnection(asyncore.dispatcher):
         # cause interoperability trouble with stricter checks.
 
         msg_rcode = msg.get_rcode()
-        if msg_rcode != Rcode.NOERROR():
+        if msg_rcode != Rcode.NOERROR:
             raise XfrinProtocolError('error response: %s' %
                                      msg_rcode.to_text())
 
@@ -1120,13 +1120,13 @@ def __process_xfrin(server, zone_name, rrclass, db_file,
             ret = XFRIN_FAIL
             if conn.connect_to_master():
                 ret = conn.do_xfrin(check_soa, request_type)
-                if ret == XFRIN_FAIL and request_type == RRType.IXFR():
+                if ret == XFRIN_FAIL and request_type == RRType.IXFR:
                     # IXFR failed for some reason. It might mean the server can't
                     # handle it, or we don't have the zone or we are out of sync or
                     # whatever else. So we retry with with AXFR, as it may succeed
                     # in many such cases.
                     retry = True
-                    request_type = RRType.AXFR()
+                    request_type = RRType.AXFR
                     logger.warn(XFRIN_XFR_TRANSFER_FALLBACK, conn.zone_str())
                     conn.close()
                     conn = None
@@ -1172,7 +1172,7 @@ def process_xfrin(server, xfrin_recorder, zone_name, rrclass, db_file,
     xfrin_recorder.decrement(zone_name)
 
     if exception is not None:
-        typestr = "AXFR" if request_type == RRType.AXFR() else "IXFR"
+        typestr = "AXFR" if request_type == RRType.AXFR else "IXFR"
         logger.error(XFRIN_XFR_PROCESS_FAILURE, typestr, zone_name.to_text(),
                      str(rrclass), str(exception))
 
@@ -1507,9 +1507,9 @@ class Xfrin:
                     logger.info(XFRIN_RETRANSFER_UNKNOWN_ZONE, zone_str)
                     answer = create_answer(1, errmsg)
                 else:
-                    request_type = RRType.AXFR()
+                    request_type = RRType.AXFR
                     if zone_info.use_ixfr:
-                        request_type = RRType.IXFR()
+                        request_type = RRType.IXFR
                     master_addr = zone_info.get_master_addr_info()
                     if notify_addr[0] == master_addr[0] and\
                        notify_addr[2] == master_addr[2]:
@@ -1538,11 +1538,11 @@ class Xfrin:
                                                           rrclass)
                 zone_info = self._get_zone_info(zone_name, rrclass)
                 tsig_key = None
-                request_type = RRType.AXFR()
+                request_type = RRType.AXFR
                 if zone_info:
                     tsig_key = zone_info.get_tsig_key()
                     if zone_info.use_ixfr:
-                        request_type = RRType.IXFR()
+                        request_type = RRType.IXFR
                 db_file = args.get('db_file') or self._get_db_file()
                 ret = self.xfrin_start(zone_name,
                                        rrclass,

+ 0 - 4
src/bin/xfrin/xfrin_messages.mes

@@ -125,10 +125,6 @@ There was a problem sending a message to the xfrout module or the
 zone manager. This most likely means that the msgq daemon has quit or
 was killed.
 
-% XFRIN_MSGQ_SEND_ERROR_AUTH error while contacting %1
-There was a problem sending a message to b10-auth. This most likely
-means that the msgq daemon has quit or was killed.
-
 % XFRIN_MSGQ_SEND_ERROR_ZONE_MANAGER error while contacting %1
 There was a problem sending a message to the zone manager. This most
 likely means that the msgq daemon has quit or was killed.

+ 61 - 61
src/bin/xfrout/tests/xfrout_test.py.in

@@ -38,7 +38,7 @@ TSIG_KEY = TSIGKey("example.com:SFuWd/q99SzF8Yzd1QbB9g==")
 #
 TEST_ZONE_NAME_STR = "example.com."
 TEST_ZONE_NAME = Name(TEST_ZONE_NAME_STR)
-TEST_RRCLASS = RRClass.IN()
+TEST_RRCLASS = RRClass.IN
 IXFR_OK_VERSION = 2011111802
 IXFR_NG_VERSION = 2011111803
 SOA_CURRENT_VERSION = 2011112001
@@ -109,16 +109,16 @@ class MockDataSrcClient:
         zone names.
 
         '''
-        if name == Name('nosoa.example.com') and rrtype == RRType.SOA():
+        if name == Name('nosoa.example.com') and rrtype == RRType.SOA:
             return (ZoneFinder.NXDOMAIN, None, 0)
-        elif name == Name('multisoa.example.com') and rrtype == RRType.SOA():
+        elif name == Name('multisoa.example.com') and rrtype == RRType.SOA:
             soa_rrset = create_soa(SOA_CURRENT_VERSION)
             soa_rrset.add_rdata(soa_rrset.get_rdata()[0])
             return (ZoneFinder.SUCCESS, soa_rrset, 0)
         elif name == Name('maxserial.example.com'):
             soa_rrset = create_soa(0xffffffff)
             return (ZoneFinder.SUCCESS, soa_rrset, 0)
-        elif rrtype == RRType.SOA():
+        elif rrtype == RRType.SOA:
             return (ZoneFinder.SUCCESS, create_soa(SOA_CURRENT_VERSION), 0)
         raise ValueError('Unexpected input to mock finder: bug in test case?')
 
@@ -238,17 +238,17 @@ class TestXfroutSessionBase(unittest.TestCase):
         msg = Message(Message.RENDER)
         query_id = 0x1035
         msg.set_qid(query_id)
-        msg.set_opcode(Opcode.QUERY())
-        msg.set_rcode(Rcode.NOERROR())
-        req_type = RRType.AXFR() if ixfr is None else RRType.IXFR()
+        msg.set_opcode(Opcode.QUERY)
+        msg.set_rcode(Rcode.NOERROR)
+        req_type = RRType.AXFR if ixfr is None else RRType.IXFR
         if with_question:
-            msg.add_question(Question(zone_name, RRClass.IN(),
+            msg.add_question(Question(zone_name, RRClass.IN,
                                       req_type if qtype is None else qtype))
-        if req_type == RRType.IXFR():
-            soa = RRset(zone_name, soa_class, RRType.SOA(), RRTTL(0))
+        if req_type == RRType.IXFR:
+            soa = RRset(zone_name, soa_class, RRType.SOA, RRTTL(0))
             # In the RDATA only the serial matters.
             for i in range(0, num_soa):
-                soa.add_rdata(Rdata(RRType.SOA(), soa_class,
+                soa.add_rdata(Rdata(RRType.SOA, soa_class,
                                     'm. r. ' + str(ixfr) + ' 1 1 1 1'))
             msg.add_rrset(Message.SECTION_AUTHORITY, soa)
 
@@ -263,7 +263,7 @@ class TestXfroutSessionBase(unittest.TestCase):
 
     def set_request_type(self, type):
         self.xfrsess._request_type = type
-        if type == RRType.AXFR():
+        if type == RRType.AXFR:
             self.xfrsess._request_typestr = 'AXFR'
         else:
             self.xfrsess._request_typestr = 'IXFR'
@@ -280,7 +280,7 @@ class TestXfroutSessionBase(unittest.TestCase):
                                            [{"action": "ACCEPT"}]),
                                        {},
                                        **self._counters)
-        self.set_request_type(RRType.AXFR()) # test AXFR by default
+        self.set_request_type(RRType.AXFR) # test AXFR by default
         self.mdata = self.create_request_data()
         self.soa_rrset = create_soa(SOA_CURRENT_VERSION)
         # some test replaces a module-wide function.  We should ensure the
@@ -342,7 +342,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.xfrsess._request_data = self.mdata
         self.xfrsess._server.increase_transfers_counter = lambda : False
         XfroutSession._handle(self.xfrsess)
-        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.REFUSED())
+        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.REFUSED)
 
     def test_quota_ok(self):
         '''The default case in terms of the xfrout quota.
@@ -355,7 +355,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         # Replace the data source client to avoid datasrc related exceptions
         self.xfrsess.ClientClass = MockDataSrcClient
         XfroutSession._handle(self.xfrsess)
-        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.FORMERR())
+        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.FORMERR)
 
     def test_exception_from_session(self):
         '''Test the case where the main processing raises an exception.
@@ -372,14 +372,14 @@ class TestXfroutSession(TestXfroutSessionBase):
     def test_parse_query_message(self):
         # Valid AXFR
         [get_rcode, get_msg] = self.xfrsess._parse_query_message(self.mdata)
-        self.assertEqual(RRType.AXFR(), self.xfrsess._request_type)
+        self.assertEqual(RRType.AXFR, self.xfrsess._request_type)
         self.assertEqual(get_rcode.to_text(), "NOERROR")
 
         # Valid IXFR
         request_data = self.create_request_data(ixfr=2011111801)
         rcode, msg = self.xfrsess._parse_query_message(request_data)
-        self.assertEqual(RRType.IXFR(), self.xfrsess._request_type)
-        self.assertEqual(Rcode.NOERROR(), rcode)
+        self.assertEqual(RRType.IXFR, self.xfrsess._request_type)
+        self.assertEqual(Rcode.NOERROR, rcode)
 
         # Broken request: no question
         self.assertRaises(RuntimeError, self.xfrsess._parse_query_message,
@@ -387,7 +387,7 @@ class TestXfroutSession(TestXfroutSessionBase):
 
         # Broken request: invalid RR type (neither AXFR nor IXFR)
         self.assertRaises(RuntimeError, self.xfrsess._parse_query_message,
-                          self.create_request_data(qtype=RRType.A()))
+                          self.create_request_data(qtype=RRType.A))
 
         # NOERROR
         request_data = self.create_request_data(ixfr=IXFR_OK_VERSION)
@@ -554,7 +554,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         # should be used.
         self.xfrsess._acl = isc.acl.dns.REQUEST_LOADER.load([
                 {"from": "127.0.0.1", "action": "ACCEPT"}])
-        acl = self.xfrsess._get_transfer_acl(Name('example.com'), RRClass.IN())
+        acl = self.xfrsess._get_transfer_acl(Name('example.com'), RRClass.IN)
         self.assertEqual(acl, self.xfrsess._acl)
 
         # install a per zone config with transfer ACL for example.com.  Then
@@ -567,15 +567,15 @@ class TestXfroutSession(TestXfroutSessionBase):
             com_acl
         self.assertEqual(com_acl,
                          self.xfrsess._get_transfer_acl(Name('example.com'),
-                                                        RRClass.IN()))
+                                                        RRClass.IN))
         self.assertEqual(self.xfrsess._acl,
                          self.xfrsess._get_transfer_acl(Name('example.org'),
-                                                        RRClass.IN()))
+                                                        RRClass.IN))
 
         # Name matching should be case insensitive.
         self.assertEqual(com_acl,
                          self.xfrsess._get_transfer_acl(Name('EXAMPLE.COM'),
-                                                        RRClass.IN()))
+                                                        RRClass.IN))
 
     def test_send_data(self):
         self.xfrsess._send_data(self.sock, self.mdata)
@@ -600,9 +600,9 @@ class TestXfroutSession(TestXfroutSessionBase):
         msg = self.getmsg()
         msg.make_response()
         # SOA record data with different cases
-        soa_rrset = RRset(Name('Example.com.'), RRClass.IN(), RRType.SOA(),
+        soa_rrset = RRset(Name('Example.com.'), RRClass.IN, RRType.SOA,
                                RRTTL(3600))
-        soa_rrset.add_rdata(Rdata(RRType.SOA(), RRClass.IN(),
+        soa_rrset.add_rdata(Rdata(RRType.SOA, RRClass.IN,
                                   'master.Example.com. admin.exAmple.com. ' +
                                   '2011112001 3600 1800 2419200 7200'))
         msg.add_rrset(Message.SECTION_ANSWER, soa_rrset)
@@ -680,8 +680,8 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.assertEqual(get_msg.get_rr_count(Message.SECTION_AUTHORITY), 0)
 
     def test_trigger_send_message_with_last_soa(self):
-        rrset_a = RRset(Name("example.com"), RRClass.IN(), RRType.A(), RRTTL(3600))
-        rrset_a.add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+        rrset_a = RRset(Name("example.com"), RRClass.IN, RRType.A, RRTTL(3600))
+        rrset_a.add_rdata(Rdata(RRType.A, RRClass.IN, "192.0.2.1"))
 
         msg = self.getmsg()
         msg.make_response()
@@ -759,36 +759,36 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.xfrsess.ClientClass = MockDataSrcClient
         # Successful case.  A zone iterator should be set up.
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR)
         self.assertNotEqual(None, self.xfrsess._iterator)
 
         # Failure cases
         self.assertEqual(self.xfrsess._xfrout_setup(
                 self.getmsg(), Name('notauth.example.com'), TEST_RRCLASS),
-                         Rcode.NOTAUTH())
+                         Rcode.NOTAUTH)
         self.assertEqual(self.xfrsess._xfrout_setup(
                 self.getmsg(), Name('nosoa.example.com'), TEST_RRCLASS),
-                         Rcode.SERVFAIL())
+                         Rcode.SERVFAIL)
         self.assertEqual(self.xfrsess._xfrout_setup(
                 self.getmsg(), Name('multisoa.example.com'), TEST_RRCLASS),
-                         Rcode.SERVFAIL())
+                         Rcode.SERVFAIL)
 
     def test_xfrout_ixfr_setup(self):
         self.xfrsess.ClientClass = MockDataSrcClient
-        self.set_request_type(RRType.IXFR())
+        self.set_request_type(RRType.IXFR)
 
         # Successful case of pure IXFR.  A zone journal reader should be set
         # up.
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR)
         self.assertNotEqual(None, self.xfrsess._jnl_reader)
 
         # Successful case, but as a result of falling back to AXFR-style
         # IXFR.  A zone iterator should be set up instead of a journal reader.
         self.mdata = self.create_request_data(ixfr=IXFR_NG_VERSION)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR)
         self.assertNotEqual(None, self.xfrsess._iterator)
         self.assertEqual(None, self.xfrsess._jnl_reader)
 
@@ -797,7 +797,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         # indicating that the response will contain just one SOA.
         self.mdata = self.create_request_data(ixfr=SOA_CURRENT_VERSION+1)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR)
         self.assertEqual(None, self.xfrsess._iterator)
         self.assertEqual(None, self.xfrsess._jnl_reader)
 
@@ -805,7 +805,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         # the local SOA.
         self.mdata = self.create_request_data(ixfr=SOA_CURRENT_VERSION)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), TEST_ZONE_NAME, TEST_RRCLASS), Rcode.NOERROR)
         self.assertEqual(None, self.xfrsess._iterator)
         self.assertEqual(None, self.xfrsess._jnl_reader)
 
@@ -814,7 +814,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         zone_name = Name('maxserial.example.com') # whose SOA is 0xffffffff
         self.mdata = self.create_request_data(ixfr=1, zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                 self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOERROR())
+                 self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOERROR)
         self.assertEqual(None, self.xfrsess._iterator)
         self.assertEqual(None, self.xfrsess._jnl_reader)
 
@@ -823,7 +823,7 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOERROR())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOERROR)
         self.assertNotEqual(None, self.xfrsess._iterator)
 
         # Failure cases
@@ -831,42 +831,42 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOTAUTH())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOTAUTH)
         # this is a strange case: zone's SOA will be found but the journal
         # reader won't be created due to 'no such zone'.
         zone_name = Name('notauth2.example.com')
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOTAUTH())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.NOTAUTH)
         zone_name = Name('nosoa.example.com')
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.SERVFAIL())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.SERVFAIL)
         zone_name = Name('multisoa.example.com')
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               zone_name=zone_name)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.SERVFAIL())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.SERVFAIL)
 
         # query name doesn't match the SOA's owner
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR)
 
         # query's RR class doesn't match the SOA's class
         zone_name = TEST_ZONE_NAME # make sure the name matches this time
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
-                                              soa_class=RRClass.CH())
+                                              soa_class=RRClass.CH)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR)
 
         # multiple SOA RRs
         self.mdata = self.create_request_data(ixfr=IXFR_OK_VERSION,
                                               num_soa=2)
         self.assertEqual(self.xfrsess._xfrout_setup(
-                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR())
+                self.getmsg(), zone_name, TEST_RRCLASS), Rcode.FORMERR)
 
     def test_dns_xfrout_start_formerror(self):
         # formerror
@@ -876,7 +876,7 @@ class TestXfroutSession(TestXfroutSessionBase):
 
     def test_dns_xfrout_start_notauth(self):
         def notauth(msg, name, rrclass):
-            return Rcode.NOTAUTH()
+            return Rcode.NOTAUTH
         self.xfrsess._xfrout_setup = notauth
         self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
         get_msg = self.sock.read_msg()
@@ -887,11 +887,11 @@ class TestXfroutSession(TestXfroutSessionBase):
             raise isc.datasrc.Error('exception for the sake of test')
         self.xfrsess.ClientClass = internal_raise
         self.xfrsess.dns_xfrout_start(self.sock, self.mdata)
-        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.SERVFAIL())
+        self.assertEqual(self.sock.read_msg().get_rcode(), Rcode.SERVFAIL)
 
     def test_dns_xfrout_start_noerror(self):
         def noerror(msg, name, rrclass):
-            return Rcode.NOERROR()
+            return Rcode.NOERROR
         self.xfrsess._xfrout_setup = noerror
 
         def myreply(msg, sock):
@@ -905,7 +905,7 @@ class TestXfroutSession(TestXfroutSessionBase):
 
     def test_dns_xfrout_start_with_notcallable_xfrreqdone(self):
         def noerror(msg, name, rrclass):
-            return Rcode.NOERROR()
+            return Rcode.NOERROR
         self.xfrsess._xfrout_setup = noerror
 
         def myreply(msg, sock):
@@ -925,9 +925,9 @@ class TestXfroutSession(TestXfroutSessionBase):
         self.assertEqual(reply_msg.get_rr_count(Message.SECTION_ANSWER), 2)
 
     def test_reply_xfrout_query_axfr_with_tsig(self):
-        rrset = RRset(Name('a.example.com'), RRClass.IN(), RRType.A(),
+        rrset = RRset(Name('a.example.com'), RRClass.IN, RRType.A,
                       RRTTL(3600))
-        rrset.add_rdata(Rdata(RRType.A(), RRClass.IN(), '192.0.2.1'))
+        rrset.add_rdata(Rdata(RRType.A, RRClass.IN, '192.0.2.1'))
         global xfrout
 
         def get_rrset_len(rrset):
@@ -1015,8 +1015,8 @@ class TestXfroutSession(TestXfroutSessionBase):
         algorithm = hmac-md5)
 
         '''
-        soa = RRset(Name('.'), RRClass.IN(), RRType.SOA(), RRTTL(3600))
-        soa.add_rdata(Rdata(RRType.SOA(), RRClass.IN(), '. . 0 0 0 0 0'))
+        soa = RRset(Name('.'), RRClass.IN, RRType.SOA, RRTTL(3600))
+        soa.add_rdata(Rdata(RRType.SOA, RRClass.IN, '. . 0 0 0 0 0'))
         self.mdata = self.create_request_data(zone_name=Name('.'))
         self.xfrsess._soa = soa
         if tsig:
@@ -1177,10 +1177,10 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
         self.assertEqual(self.get_counter('ixfr_ended'), 0)
         XfroutSession._handle(self.xfrsess)
         response = self.sock.read_msg(Message.PRESERVE_ORDER);
-        self.assertEqual(Rcode.NOERROR(), response.get_rcode())
+        self.assertEqual(Rcode.NOERROR, response.get_rcode())
         self.check_axfr_stream(response)
-        self.assertEqual(self.xfrsess._request_type, RRType.AXFR())
-        self.assertNotEqual(self.xfrsess._request_type, RRType.IXFR())
+        self.assertEqual(self.xfrsess._request_type, RRType.AXFR)
+        self.assertNotEqual(self.xfrsess._request_type, RRType.IXFR)
         self.assertEqual(self.get_counter('axfr_started'), 1)
         self.assertEqual(self.get_counter('axfr_ended'), 1)
         self.assertEqual(self.get_counter('ixfr_started'), 0)
@@ -1191,10 +1191,10 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
             self.create_request_data(ixfr=IXFR_NG_VERSION)
         XfroutSession._handle(self.xfrsess)
         response = self.sock.read_msg(Message.PRESERVE_ORDER);
-        self.assertEqual(Rcode.NOERROR(), response.get_rcode())
+        self.assertEqual(Rcode.NOERROR, response.get_rcode())
         # This is an AXFR-style IXFR.  So the question section should indicate
         # that it's an IXFR resposne.
-        self.assertEqual(RRType.IXFR(), response.get_question()[0].get_type())
+        self.assertEqual(RRType.IXFR, response.get_question()[0].get_type())
         self.check_axfr_stream(response)
 
     def test_ixfr_normal_session(self):
@@ -1222,8 +1222,8 @@ class TestXfroutSessionWithSQLite3(TestXfroutSessionBase):
         self.assertEqual(len(expected_records), len(actual_records))
         for (expected_rr, actual_rr) in zip(expected_records, actual_records):
             self.assertTrue(rrsets_equal(expected_rr, actual_rr))
-        self.assertNotEqual(self.xfrsess._request_type, RRType.AXFR())
-        self.assertEqual(self.xfrsess._request_type, RRType.IXFR())
+        self.assertNotEqual(self.xfrsess._request_type, RRType.AXFR)
+        self.assertEqual(self.xfrsess._request_type, RRType.IXFR)
         self.assertEqual(self.get_counter('axfr_started'), 0)
         self.assertEqual(self.get_counter('axfr_ended'), 0)
         self.assertEqual(self.get_counter('ixfr_started'), 1)

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

@@ -227,9 +227,9 @@ class XfroutSession():
                                                   self._tsig_key_ring)
             tsig_error = self._tsig_ctx.verify(tsig_record, request_data)
             if tsig_error != TSIGError.NOERROR:
-                return Rcode.NOTAUTH()
+                return Rcode.NOTAUTH
 
-        return Rcode.NOERROR()
+        return Rcode.NOERROR
 
     def _parse_query_message(self, mdata):
         ''' parse query message to [socket,message]'''
@@ -239,11 +239,11 @@ class XfroutSession():
             Message.from_wire(msg, mdata)
         except Exception as err: # Exception is too broad
             logger.error(XFROUT_PARSE_QUERY_ERROR, err)
-            return Rcode.FORMERR(), None
+            return Rcode.FORMERR, None
 
         # TSIG related checks
         rcode = self._check_request_tsig(msg, mdata)
-        if rcode != Rcode.NOERROR():
+        if rcode != Rcode.NOERROR:
             return rcode, msg
 
         # Make sure the question is valid.  This should be ensured by
@@ -257,9 +257,9 @@ class XfroutSession():
 
         # Identify the request type
         self._request_type = question.get_type()
-        if self._request_type == RRType.AXFR():
+        if self._request_type == RRType.AXFR:
             self._request_typestr = 'AXFR'
-        elif self._request_type == RRType.IXFR():
+        elif self._request_type == RRType.IXFR:
             self._request_typestr = 'IXFR'
         else:
             # Likewise, this should be impossible.
@@ -283,7 +283,7 @@ class XfroutSession():
             logger.debug(DBG_XFROUT_TRACE, XFROUT_QUERY_REJECTED,
                          self._request_type, format_addrinfo(self._remote),
                          format_zone_str(zone_name, zone_class))
-            return Rcode.REFUSED(), msg
+            return Rcode.REFUSED, msg
 
         return rcode, msg
 
@@ -351,16 +351,16 @@ class XfroutSession():
         '''
         result, finder = self._datasrc_client.find_zone(zone_name)
         if result != DataSourceClient.SUCCESS:
-            return (Rcode.NOTAUTH(), None)
-        result, soa_rrset, _ = finder.find(zone_name, RRType.SOA())
+            return (Rcode.NOTAUTH, None)
+        result, soa_rrset, _ = finder.find(zone_name, RRType.SOA)
         if result != ZoneFinder.SUCCESS:
-            return (Rcode.SERVFAIL(), None)
+            return (Rcode.SERVFAIL, None)
         # Especially for database-based zones, a working zone may be in
         # a broken state where it has more than one SOA RR.  We proactively
         # check the condition and abort the xfr attempt if we identify it.
         if soa_rrset.get_rdata_count() != 1:
-            return (Rcode.SERVFAIL(), None)
-        return (Rcode.NOERROR(), soa_rrset)
+            return (Rcode.SERVFAIL, None)
+        return (Rcode.NOERROR, soa_rrset)
 
     def __axfr_setup(self, zone_name):
         '''Setup a zone iterator for AXFR or AXFR-style IXFR.
@@ -379,16 +379,16 @@ class XfroutSession():
             # update get_iterator() API so that we can distinguish "no such
             # zone" and other cases (#1373).  For now we consider all these
             # cases as NOTAUTH.
-            return Rcode.NOTAUTH()
+            return Rcode.NOTAUTH
 
         # If we are an authoritative name server for the zone, but fail
         # to find the zone's SOA record in datasource, xfrout can't
         # provide zone transfer for it.
         self._soa = self._iterator.get_soa()
         if self._soa is None or self._soa.get_rdata_count() != 1:
-            return Rcode.SERVFAIL()
+            return Rcode.SERVFAIL
 
-        return Rcode.NOERROR()
+        return Rcode.NOERROR
 
     def __ixfr_setup(self, request_msg, zone_name, zone_class):
         '''Setup a zone journal reader for IXFR.
@@ -405,21 +405,21 @@ class XfroutSession():
             # Ignore data whose owner name is not the zone apex, and
             # ignore non-SOA or different class of records.
             if auth_rrset.get_name() != zone_name or \
-                    auth_rrset.get_type() != RRType.SOA() or \
+                    auth_rrset.get_type() != RRType.SOA or \
                     auth_rrset.get_class() != zone_class:
                 continue
             if auth_rrset.get_rdata_count() != 1:
                 logger.info(XFROUT_IXFR_MULTIPLE_SOA,
                             format_addrinfo(self._remote))
-                return Rcode.FORMERR()
+                return Rcode.FORMERR
             remote_soa = auth_rrset
         if remote_soa is None:
             logger.info(XFROUT_IXFR_NO_SOA, format_addrinfo(self._remote))
-            return Rcode.FORMERR()
+            return Rcode.FORMERR
 
         # Retrieve the local SOA
         rcode, self._soa = self._get_zone_soa(zone_name)
-        if rcode != Rcode.NOERROR():
+        if rcode != Rcode.NOERROR:
             return rcode
 
         # RFC1995 says "If an IXFR query with the same or newer version
@@ -437,7 +437,7 @@ class XfroutSession():
             logger.info(XFROUT_IXFR_UPTODATE, format_addrinfo(self._remote),
                         format_zone_str(zone_name, zone_class),
                         begin_serial, end_serial)
-            return Rcode.NOERROR()
+            return Rcode.NOERROR
 
         # Set up the journal reader or fall back to AXFR-style IXFR
         try:
@@ -462,12 +462,12 @@ class XfroutSession():
             # between these two operations.  We treat it as NOTAUTH.
             logger.warn(XFROUT_IXFR_NO_ZONE, format_addrinfo(self._remote),
                         format_zone_str(zone_name, zone_class))
-            return Rcode.NOTAUTH()
+            return Rcode.NOTAUTH
 
         # Use the reader as the iterator to generate the response.
         self._iterator = self._jnl_reader
 
-        return Rcode.NOERROR()
+        return Rcode.NOERROR
 
     def _xfrout_setup(self, request_msg, zone_name, zone_class):
         '''Setup a context for xfr responses according to the request type.
@@ -490,7 +490,7 @@ class XfroutSession():
             self._server.get_db_file() + '"}'
         self._datasrc_client = self.ClientClass('sqlite3', datasrc_config)
 
-        if self._request_type == RRType.AXFR():
+        if self._request_type == RRType.AXFR:
             return self.__axfr_setup(zone_name)
         else:
             return self.__ixfr_setup(request_msg, zone_name, zone_class)
@@ -500,17 +500,17 @@ class XfroutSession():
         #TODO. create query message and parse header
         if rcode_ is None: # Dropped by ACL
             return
-        elif rcode_ == Rcode.NOTAUTH() or rcode_ == Rcode.REFUSED():
+        elif rcode_ == Rcode.NOTAUTH or rcode_ == Rcode.REFUSED:
             return self._reply_query_with_error_rcode(msg, sock_fd, rcode_)
-        elif rcode_ != Rcode.NOERROR():
+        elif rcode_ != Rcode.NOERROR:
             return self._reply_query_with_error_rcode(msg, sock_fd,
-                                                      Rcode.FORMERR())
+                                                      Rcode.FORMERR)
         elif not quota_ok:
             logger.warn(XFROUT_QUERY_QUOTA_EXCCEEDED, self._request_typestr,
                         format_addrinfo(self._remote),
                         self._server._max_transfers_out)
             return self._reply_query_with_error_rcode(msg, sock_fd,
-                                                      Rcode.REFUSED())
+                                                      Rcode.REFUSED)
 
         question = msg.get_question()[0]
         zone_name = question.get_name()
@@ -522,15 +522,15 @@ class XfroutSession():
         except Exception as ex:
             logger.error(XFROUT_XFR_TRANSFER_CHECK_ERROR, self._request_typestr,
                          format_addrinfo(self._remote), zone_str, ex)
-            rcode_ = Rcode.SERVFAIL()
-        if rcode_ != Rcode.NOERROR():
+            rcode_ = Rcode.SERVFAIL
+        if rcode_ != Rcode.NOERROR:
             logger.info(XFROUT_XFR_TRANSFER_FAILED, self._request_typestr,
                         format_addrinfo(self._remote), zone_str, rcode_)
             return self._reply_query_with_error_rcode(msg, sock_fd, rcode_)
 
         try:
             # increment Xfr starts by RRType
-            if self._request_type == RRType.AXFR():
+            if self._request_type == RRType.AXFR:
                 self._inc_axfr_running()
             else:
                 self._inc_ixfr_running()
@@ -542,7 +542,7 @@ class XfroutSession():
                     format_addrinfo(self._remote), zone_str, err)
         finally:
             # decrement Xfr starts by RRType
-            if self._request_type == RRType.AXFR():
+            if self._request_type == RRType.AXFR:
                 self._dec_axfr_running()
             else:
                 self._dec_ixfr_running()
@@ -614,7 +614,7 @@ class XfroutSession():
 
             # For AXFR (or AXFR-style IXFR), in which case _jnl_reader is None,
             # we should skip SOAs from the iterator.
-            if self._jnl_reader is None and rrset.get_type() == RRType.SOA():
+            if self._jnl_reader is None and rrset.get_type() == RRType.SOA:
                 continue
 
             # We calculate the maximum size of the RRset (i.e. the
@@ -756,7 +756,7 @@ class UnixSockServer(socketserver_mixin.NoPollMixIn,
         """
         sock_fd = recv_fd(request.fileno())
         if sock_fd < 0:
-            logger.warn(XFROUT_RECEIVE_FILE_DESCRIPTOR_ERROR)
+            logger.warn(XFROUT_RECEIVE_FD_FAILED)
             return False
 
         # receive request msg.  If it fails we simply terminate the thread;
@@ -1215,7 +1215,7 @@ class XfroutServer:
             zone_name = args.get('zone_name')
             zone_class = args.get('zone_class')
             if not zone_class:
-                zone_class = str(RRClass.IN())
+                zone_class = str(RRClass.IN)
             if zone_name:
                 logger.info(XFROUT_NOTIFY_COMMAND, zone_name, zone_class)
                 if self.send_notify(zone_name, zone_class):

+ 1 - 1
src/bin/xfrout/xfrout_messages.mes

@@ -155,7 +155,7 @@ statistics data should be sent to the stats daemon.
 The xfrout daemon received a shutdown command from the command channel
 and will now shut down.
 
-% XFROUT_RECEIVE_FILE_DESCRIPTOR_ERROR error receiving the file descriptor for an XFR connection
+% XFROUT_RECEIVE_FD_FAILED error receiving the file descriptor for an XFR connection
 There was an error receiving the file descriptor for the transfer
 request from b10-auth.  There can be several reasons for this, but
 the most likely cause is that b10-auth terminates for some reason

+ 0 - 1
src/lib/asiodns/tcp_server.cc

@@ -184,7 +184,6 @@ TCPServer::operator()(asio::error_code ec, size_t length) {
         // provides the appropriate operator() but is otherwise functionless.
         iosock_.reset(new TCPSocket<DummyIOCallback>(*socket_));
         io_message_.reset(new IOMessage(data_.get(), length, *iosock_, *peer_));
-        bytes_ = length;
 
         // Perform any necessary operations prior to processing the incoming
         // packet (e.g., checking for queued configuration messages).

+ 0 - 1
src/lib/asiodns/tcp_server.h

@@ -122,7 +122,6 @@ private:
 
     // State information that is entirely internal to a given instance
     // of the coroutine can be declared here.
-    size_t bytes_;
     bool done_;
 
     // Callback functions provided by the caller

+ 3 - 4
src/lib/asiodns/udp_server.cc

@@ -61,7 +61,7 @@ struct UDPServer::Data {
      */
     Data(io_service& io_service, const ip::address& addr, const uint16_t port,
         SimpleCallback* checkin, DNSLookup* lookup, DNSAnswer* answer) :
-        io_(io_service), done_(false),
+        io_(io_service), bytes_(0), done_(false),
         checkin_callback_(checkin),lookup_callback_(lookup),
         answer_callback_(answer)
     {
@@ -77,7 +77,7 @@ struct UDPServer::Data {
     }
     Data(io_service& io_service, int fd, int af, SimpleCallback* checkin,
          DNSLookup* lookup, DNSAnswer* answer) :
-         io_(io_service), done_(false),
+         io_(io_service), bytes_(0), done_(false),
          checkin_callback_(checkin),lookup_callback_(lookup),
          answer_callback_(answer)
     {
@@ -104,7 +104,7 @@ struct UDPServer::Data {
      * We also allocate data for receiving the packet here.
      */
     Data(const Data& other) :
-        io_(other.io_), socket_(other.socket_), done_(false),
+        io_(other.io_), socket_(other.socket_), bytes_(0), done_(false),
         checkin_callback_(other.checkin_callback_),
         lookup_callback_(other.lookup_callback_),
         answer_callback_(other.answer_callback_)
@@ -168,7 +168,6 @@ struct UDPServer::Data {
     size_t bytes_;
     bool done_;
 
-
     // Callback functions provided by the caller
     const SimpleCallback* checkin_callback_;
     const DNSLookup* lookup_callback_;

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

@@ -261,7 +261,7 @@ skipChars(std::istream& in, const char* chars, int& line, int& pos) {
         } else {
             ++pos;
         }
-        in.get();
+        in.ignore();
         c = in.peek();
     }
 }
@@ -291,7 +291,7 @@ skipTo(std::istream& in, const std::string& file, int& line,
                     pos = 1;
                     ++line;
                 }
-                in.get();
+                in.ignore();
                 ++pos;
             }
             in.putback(c);
@@ -352,7 +352,7 @@ strFromStringstream(std::istream& in, const std::string& file,
                 throwJSONError("Bad escape", file, line, pos);
             }
             // drop the escaped char
-            in.get();
+            in.ignore();
             ++pos;
         }
         ss.put(c);
@@ -490,14 +490,14 @@ fromStringstreamMap(std::istream& in, const std::string& file, int& line,
         throwJSONError(std::string("Unterminated map, <string> or } expected"), file, line, pos);
     } else if (c == '}') {
         // empty map, skip closing curly
-        c = in.get();
+        in.ignore();
     } else {
         while (c != EOF && c != '}') {
             std::string key = strFromStringstream(in, file, line, pos);
 
             skipTo(in, file, line, pos, ":", WHITESPACE);
             // skip the :
-            in.get();
+            in.ignore();
             pos++;
 
             ConstElementPtr value = Element::fromJSON(in, file, line, pos);

+ 2 - 0
src/lib/config/tests/ccsession_unittests.cc

@@ -343,6 +343,7 @@ TEST_F(CCSessionTest, checkCommand) {
     session.addMessage(el("{ \"command\": \"bad_command\" }"), "Spec29", "*");
     result = mccs.checkCommand();
     EXPECT_EQ(0, session.getMsgQueue()->size());
+    EXPECT_EQ(0, result);
 
     session.addMessage(el("{ \"command\": [ \"bad_command\" ] }"),
                        "Spec29", "*");
@@ -627,6 +628,7 @@ TEST_F(CCSessionTest, ignoreRemoteConfigCommands) {
     EXPECT_EQ(1, session.getMsgQueue()->size());
     result = mccs.checkCommand();
     EXPECT_EQ(0, session.getMsgQueue()->size());
+    EXPECT_EQ(0, result);
 }
 
 TEST_F(CCSessionTest, initializationFail) {

+ 8 - 2
src/lib/datasrc/memory/zone_finder.cc

@@ -573,6 +573,7 @@ FindNodeResult findNode(const ZoneData& zone_data,
 /// For (successful) type ANY query, found_node points to the
 /// corresponding zone node, which is recorded within this specialized
 /// context.
+// cppcheck-suppress noConstructor
 class InMemoryZoneFinder::Context : public ZoneFinder::Context {
 public:
     Context(InMemoryZoneFinder& finder, ZoneFinder::FindOptions options,
@@ -865,7 +866,8 @@ InMemoryZoneFinder::findInternal(const isc::dns::Name& name,
         const RdataSet* cur_rds = node->getData();
         while (cur_rds != NULL) {
             target->push_back(createTreeNodeRRset(node, cur_rds, rrclass_,
-                                                  options, &name));
+                                                  options,
+                                                  wild ? &name : NULL));
             cur_rds = cur_rds->getNext();
         }
         LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ANY_SUCCESS).
@@ -892,9 +894,13 @@ InMemoryZoneFinder::findInternal(const isc::dns::Name& name,
         }
     }
     // No exact match or CNAME.  Get NSEC if necessary and return NXRRSET.
+    // Note that we don't have to provide the "real name" even if this is
+    // a wildcard; if NSEC is needed its owner name shouldn't be subject to
+    // wildcard substitution; if NSEC isn't needed the "real name" doesn't
+    // matter anyway.
     return (createFindResult(rrclass_, zone_data_, NXRRSET, node,
                              getNSECForNXRRSET(zone_data_, options, node),
-                             options, wild, &name));
+                             options, wild));
 }
 
 isc::datasrc::ZoneFinder::FindNSEC3Result

+ 1 - 0
src/lib/datasrc/memory_datasrc.cc

@@ -782,6 +782,7 @@ struct RBNodeResultContext {
 };
 }
 
+// cppcheck-suppress noConstructor
 class InMemoryZoneFinder::Context : public ZoneFinder::Context {
 public:
     /// \brief Constructor.

+ 3 - 0
src/lib/datasrc/sqlite3_accessor.cc

@@ -682,6 +682,8 @@ convertToPlainChar(const unsigned char* ucp, sqlite3 *db) {
 }
 
 }
+
+// cppcheck-suppress noConstructor
 class SQLite3Accessor::Context : public DatabaseAccessor::IteratorContext {
 public:
     // Construct an iterator for all records. When constructed this
@@ -887,6 +889,7 @@ SQLite3Accessor::getAllRecords(int id) const {
 /// This iterator is used to search through the differences table for the
 /// resouce records making up an IXFR between two versions of a zone.
 
+// cppcheck-suppress noConstructor
 class SQLite3Accessor::DiffContext : public DatabaseAccessor::IteratorContext {
 public:
 

+ 40 - 10
src/lib/datasrc/tests/memory/zone_finder_unittest.cc

@@ -442,14 +442,23 @@ protected:
         }
         EXPECT_EQ((expected_flags & ZoneFinder::RESULT_WILDCARD) != 0,
                   find_result->isWildcard());
-        EXPECT_EQ((expected_flags & ZoneFinder::RESULT_NSEC_SIGNED)
-                  != 0, find_result->isNSECSigned());
-        EXPECT_EQ((expected_flags & ZoneFinder::RESULT_NSEC3_SIGNED)
-                  != 0, find_result->isNSEC3Signed());
-        // Convert all rrsets to 'full' ones before checking
+        EXPECT_EQ((expected_flags & ZoneFinder::RESULT_NSEC_SIGNED) != 0,
+                  find_result->isNSECSigned());
+        EXPECT_EQ((expected_flags & ZoneFinder::RESULT_NSEC3_SIGNED) != 0,
+                  find_result->isNSEC3Signed());
+        // Convert all rrsets to 'full' ones before checking.  Also, confirm
+        // each RRset of the vector is of the "same kind" as one would be
+        // found by the find() method.
         std::vector<ConstRRsetPtr> converted_rrsets;
         BOOST_FOREACH(ConstRRsetPtr cur_rrset, target) {
             converted_rrsets.push_back(convertRRset(cur_rrset));
+
+            // As we know findAll() succeeded, this find() should also
+            // succeed, and the two sets should be "identical".
+            const ZoneFinderContextPtr result =
+                finder->find(name, cur_rrset->getType());
+            ASSERT_TRUE(result->rrset);
+            EXPECT_TRUE(result->rrset->isSameKind(*cur_rrset));
         }
         rrsetsCheck(expected_rrsets.begin(), expected_rrsets.end(),
                     converted_rrsets.begin(), converted_rrsets.end());
@@ -1133,21 +1142,42 @@ InMemoryZoneFinderTest::wildcardCheck(
     }
 }
 
+// We have combinations of these cases (6 in total)
+// expected_flags: NSEC, NSEC3, RESULT_DEFAULT
+// options: NO_WILDCARD, FIND_DEFAULT
+
+// 1. Normal case: expected = DEFAULT, options = DEFAULT
 TEST_F(InMemoryZoneFinderTest, wildcard) {
-    // Normal case
     wildcardCheck();
 }
 
+// 2. options: expected = DEFAULT, options = NO_WILDCARD
+TEST_F(InMemoryZoneFinderTest, wildcardDisabled) {
+    // Similar to the previous once, but check the behavior for a non signed
+    // zone just in case.
+    wildcardCheck(ZoneFinder::RESULT_DEFAULT, ZoneFinder::NO_WILDCARD);
+}
+
+// 3. options: expected = NSEC_SIGNED, options = DEFAULT
+TEST_F(InMemoryZoneFinderTest, wildcardWithNSEC) {
+    wildcardCheck(ZoneFinder::RESULT_NSEC_SIGNED, ZoneFinder::FIND_DEFAULT);
+}
+
+// 4. options: expected = NSEC_SIGNED, options = NO_WILDCARD
 TEST_F(InMemoryZoneFinderTest, wildcardDisabledWithNSEC) {
     // Wildcard is disabled.  In practice, this is used as part of query
     // processing for an NSEC-signed zone, so we test that case specifically.
     wildcardCheck(ZoneFinder::RESULT_NSEC_SIGNED, ZoneFinder::NO_WILDCARD);
 }
 
-TEST_F(InMemoryZoneFinderTest, wildcardDisabledWithoutNSEC) {
-    // Similar to the previous once, but check the behavior for a non signed
-    // zone just in case.
-    wildcardCheck(ZoneFinder::RESULT_DEFAULT, ZoneFinder::NO_WILDCARD);
+// 5. options: expected = NSEC3_SIGNED, options = DEFAULT
+TEST_F(InMemoryZoneFinderTest, wildcardWithNSEC3) {
+    wildcardCheck(ZoneFinder::RESULT_NSEC3_SIGNED, ZoneFinder::FIND_DEFAULT);
+}
+
+// 6. options: expected = NSEC3_SIGNED, options = DEFAULT
+TEST_F(InMemoryZoneFinderTest, wildcardDisabledWithNSEC3) {
+    wildcardCheck(ZoneFinder::RESULT_NSEC3_SIGNED, ZoneFinder::NO_WILDCARD);
 }
 
 /*

+ 188 - 170
src/lib/dhcpsrv/alloc_engine.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013 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
@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <dhcpsrv/alloc_engine.h>
+#include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 
 #include <cstring>
@@ -169,95 +170,104 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
                               const IOAddress& hint,
                               bool fake_allocation /* = false */ ) {
 
-    // That check is not necessary. We create allocator in AllocEngine
-    // constructor
-    if (!allocator_) {
-        isc_throw(InvalidOperation, "No allocator selected");
-    }
-
-    // check if there's existing lease for that subnet/duid/iaid combination.
-    Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(*duid, iaid, subnet->getID());
-    if (existing) {
-        // we have a lease already. This is a returning client, probably after
-        // his reboot.
-        return (existing);
-    }
+    try {
+        // That check is not necessary. We create allocator in AllocEngine
+        // constructor
+        if (!allocator_) {
+            isc_throw(InvalidOperation, "No allocator selected");
+        }
 
-    // check if the hint is in pool and is available
-    if (subnet->inPool(hint)) {
-        existing = LeaseMgrFactory::instance().getLease6(hint);
-        if (!existing) {
-            /// @todo: check if the hint is reserved once we have host support
-            /// implemented
+        // check if there's existing lease for that subnet/duid/iaid combination.
+        Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(*duid, iaid, subnet->getID());
+        if (existing) {
+            // we have a lease already. This is a returning client, probably after
+            // his reboot.
+            return (existing);
+        }
 
-            // the hint is valid and not currently used, let's create a lease for it
-            Lease6Ptr lease = createLease6(subnet, duid, iaid, hint, fake_allocation);
+        // check if the hint is in pool and is available
+        if (subnet->inPool(hint)) {
+            existing = LeaseMgrFactory::instance().getLease6(hint);
+            if (!existing) {
+                /// @todo: check if the hint is reserved once we have host support
+                /// implemented
+
+                // the hint is valid and not currently used, let's create a lease for it
+                Lease6Ptr lease = createLease6(subnet, duid, iaid, hint, fake_allocation);
+
+                // It can happen that the lease allocation failed (we could have lost
+                // the race condition. That means that the hint is lo longer usable and
+                // we need to continue the regular allocation path.
+                if (lease) {
+                    return (lease);
+                }
+            } else {
+                if (existing->expired()) {
+                    return (reuseExpiredLease(existing, subnet, duid, iaid,
+                                              fake_allocation));
+                }
 
-            // It can happen that the lease allocation failed (we could have lost
-            // the race condition. That means that the hint is lo longer usable and
-            // we need to continue the regular allocation path.
-            if (lease) {
-                return (lease);
             }
-        } else {
-            if (existing->expired()) {
-                return (reuseExpiredLease(existing, subnet, duid, iaid,
-                                          fake_allocation));
-            }
-
         }
-    }
 
-    // Hint is in the pool but is not available. Search the pool until first of
-    // the following occurs:
-    // - we find a free address
-    // - we find an address for which the lease has expired
-    // - we exhaust number of tries
-    //
-    // @todo: Current code does not handle pool exhaustion well. It will be
-    // improved. Current problems:
-    // 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
-    // 10 addresses), we will iterate over it 100 times before giving up
-    // 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
-    // 3. the whole concept of infinite attempts is just asking for infinite loop
-    // We may consider some form or reference counting (this pool has X addresses
-    // left), but this has one major problem. We exactly control allocation
-    // moment, but we currently do not control expiration time at all
-
-    unsigned int i = attempts_;
-    do {
-        IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
-
-        /// @todo: check if the address is reserved once we have host support
-        /// implemented
-
-        Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
-        if (!existing) {
-            // there's no existing lease for selected candidate, so it is
-            // free. Let's allocate it.
-            Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate,
-                                          fake_allocation);
-            if (lease) {
-                return (lease);
-            }
+        // Hint is in the pool but is not available. Search the pool until first of
+        // the following occurs:
+        // - we find a free address
+        // - we find an address for which the lease has expired
+        // - we exhaust number of tries
+        //
+        // @todo: Current code does not handle pool exhaustion well. It will be
+        // improved. Current problems:
+        // 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
+        // 10 addresses), we will iterate over it 100 times before giving up
+        // 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
+        // 3. the whole concept of infinite attempts is just asking for infinite loop
+        // We may consider some form or reference counting (this pool has X addresses
+        // left), but this has one major problem. We exactly control allocation
+        // moment, but we currently do not control expiration time at all
+
+        unsigned int i = attempts_;
+        do {
+            IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
+
+            /// @todo: check if the address is reserved once we have host support
+            /// implemented
 
-            // Although the address was free just microseconds ago, it may have
-            // been taken just now. If the lease insertion fails, we continue
-            // allocation attempts.
-        } else {
-            if (existing->expired()) {
-                return (reuseExpiredLease(existing, subnet, duid, iaid,
-                                          fake_allocation));
+            Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
+            if (!existing) {
+                // there's no existing lease for selected candidate, so it is
+                // free. Let's allocate it.
+                Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate,
+                                              fake_allocation);
+                if (lease) {
+                    return (lease);
+                }
+
+                // Although the address was free just microseconds ago, it may have
+                // been taken just now. If the lease insertion fails, we continue
+                // allocation attempts.
+            } else {
+                if (existing->expired()) {
+                    return (reuseExpiredLease(existing, subnet, duid, iaid,
+                                              fake_allocation));
+                }
             }
-        }
 
-        // continue trying allocation until we run out of attempts
-        // (or attempts are set to 0, which means infinite)
-        --i;
-    } while ( i || !attempts_);
+            // Continue trying allocation until we run out of attempts
+            // (or attempts are set to 0, which means infinite)
+            --i;
+        } while ((i > 0) || !attempts_);
 
-    isc_throw(AllocFailed, "Failed to allocate address after " << attempts_
-              << " tries");
+        // Unable to allocate an address, return an empty lease.
+        LOG_WARN(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_FAIL).arg(attempts_);
+
+    } catch (const isc::Exception& e) {
+
+        // Some other error, return an empty lease.
+        LOG_ERROR(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_ERROR).arg(e.what());
+    }
+
+    return (Lease6Ptr());
 }
 
 Lease4Ptr
@@ -267,115 +277,123 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
                               const IOAddress& hint,
                               bool fake_allocation /* = false */ ) {
 
-    // Allocator is always created in AllocEngine constructor and there is
-    // currently no other way to set it, so that check is not really necessary.
-    if (!allocator_) {
-        isc_throw(InvalidOperation, "No allocator selected");
-    }
-
-    // Check if there's existing lease for that subnet/clientid/hwaddr combination.
-    Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(hwaddr->hwaddr_, subnet->getID());
-    if (existing) {
-        // We have a lease already. This is a returning client, probably after
-        // its reboot.
-        existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
-        if (existing) {
-            return (existing);
+    try {
+        // Allocator is always created in AllocEngine constructor and there is
+        // currently no other way to set it, so that check is not really necessary.
+        if (!allocator_) {
+            isc_throw(InvalidOperation, "No allocator selected");
         }
 
-        // If renewal failed (e.g. the lease no longer matches current configuration)
-        // let's continue the allocation process
-    }
-
-    if (clientid) {
-        existing = LeaseMgrFactory::instance().getLease4(*clientid, subnet->getID());
+        // Check if there's existing lease for that subnet/clientid/hwaddr combination.
+        Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(hwaddr->hwaddr_, subnet->getID());
         if (existing) {
-            // we have a lease already. This is a returning client, probably after
+            // We have a lease already. This is a returning client, probably after
             // its reboot.
             existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
-            // @todo: produce a warning. We haven't found him using MAC address, but
-            // we found him using client-id
             if (existing) {
                 return (existing);
             }
+
+            // If renewal failed (e.g. the lease no longer matches current configuration)
+            // let's continue the allocation process
         }
-    }
 
-    // check if the hint is in pool and is available
-    if (subnet->inPool(hint)) {
-        existing = LeaseMgrFactory::instance().getLease4(hint);
-        if (!existing) {
-            /// @todo: Check if the hint is reserved once we have host support
-            /// implemented
+        if (clientid) {
+            existing = LeaseMgrFactory::instance().getLease4(*clientid, subnet->getID());
+            if (existing) {
+                // we have a lease already. This is a returning client, probably after
+                // its reboot.
+                existing = renewLease4(subnet, clientid, hwaddr, existing, fake_allocation);
+                // @todo: produce a warning. We haven't found him using MAC address, but
+                // we found him using client-id
+                if (existing) {
+                    return (existing);
+                }
+            }
+        }
 
-            // The hint is valid and not currently used, let's create a lease for it
-            Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, hint, fake_allocation);
+        // check if the hint is in pool and is available
+        if (subnet->inPool(hint)) {
+            existing = LeaseMgrFactory::instance().getLease4(hint);
+            if (!existing) {
+                /// @todo: Check if the hint is reserved once we have host support
+                /// implemented
+
+                // The hint is valid and not currently used, let's create a lease for it
+                Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, hint, fake_allocation);
+
+                // It can happen that the lease allocation failed (we could have lost
+                // the race condition. That means that the hint is lo longer usable and
+                // we need to continue the regular allocation path.
+                if (lease) {
+                    return (lease);
+                }
+            } else {
+                if (existing->expired()) {
+                    return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
+                                              fake_allocation));
+                }
 
-            // It can happen that the lease allocation failed (we could have lost
-            // the race condition. That means that the hint is lo longer usable and
-            // we need to continue the regular allocation path.
-            if (lease) {
-                return (lease);
             }
-        } else {
-            if (existing->expired()) {
-                return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
-                                          fake_allocation));
-            }
-
         }
-    }
 
-    // Hint is in the pool but is not available. Search the pool until first of
-    // the following occurs:
-    // - we find a free address
-    // - we find an address for which the lease has expired
-    // - we exhaust the number of tries
-    //
-    // @todo: Current code does not handle pool exhaustion well. It will be
-    // improved. Current problems:
-    // 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
-    // 10 addresses), we will iterate over it 100 times before giving up
-    // 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
-    // 3. the whole concept of infinite attempts is just asking for infinite loop
-    // We may consider some form or reference counting (this pool has X addresses
-    // left), but this has one major problem. We exactly control allocation
-    // moment, but we currently do not control expiration time at all
-
-    unsigned int i = attempts_;
-    do {
-        IOAddress candidate = allocator_->pickAddress(subnet, clientid, hint);
-
-        /// @todo: check if the address is reserved once we have host support
-        /// implemented
-
-        Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(candidate);
-        if (!existing) {
-            // there's no existing lease for selected candidate, so it is
-            // free. Let's allocate it.
-            Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, candidate,
-                                          fake_allocation);
-            if (lease) {
-                return (lease);
-            }
+        // Hint is in the pool but is not available. Search the pool until first of
+        // the following occurs:
+        // - we find a free address
+        // - we find an address for which the lease has expired
+        // - we exhaust the number of tries
+        //
+        // @todo: Current code does not handle pool exhaustion well. It will be
+        // improved. Current problems:
+        // 1. with attempts set to too large value (e.g. 1000) and a small pool (e.g.
+        // 10 addresses), we will iterate over it 100 times before giving up
+        // 2. attempts 0 mean unlimited (this is really UINT_MAX, not infinite)
+        // 3. the whole concept of infinite attempts is just asking for infinite loop
+        // We may consider some form or reference counting (this pool has X addresses
+        // left), but this has one major problem. We exactly control allocation
+        // moment, but we currently do not control expiration time at all
+
+        unsigned int i = attempts_;
+        do {
+            IOAddress candidate = allocator_->pickAddress(subnet, clientid, hint);
+
+            /// @todo: check if the address is reserved once we have host support
+            /// implemented
 
-            // Although the address was free just microseconds ago, it may have
-            // been taken just now. If the lease insertion fails, we continue
-            // allocation attempts.
-        } else {
-            if (existing->expired()) {
-                return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
-                                          fake_allocation));
+            Lease4Ptr existing = LeaseMgrFactory::instance().getLease4(candidate);
+            if (!existing) {
+                // there's no existing lease for selected candidate, so it is
+                // free. Let's allocate it.
+                Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, candidate,
+                                              fake_allocation);
+                if (lease) {
+                    return (lease);
+                }
+
+                // Although the address was free just microseconds ago, it may have
+                // been taken just now. If the lease insertion fails, we continue
+                // allocation attempts.
+            } else {
+                if (existing->expired()) {
+                    return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
+                                              fake_allocation));
+                }
             }
-        }
 
-        // Continue trying allocation until we run out of attempts
-        // (or attempts are set to 0, which means infinite)
-        --i;
-    } while ( i || !attempts_);
+            // Continue trying allocation until we run out of attempts
+            // (or attempts are set to 0, which means infinite)
+            --i;
+        } while ((i > 0) || !attempts_);
 
-    isc_throw(AllocFailed, "Failed to allocate address after " << attempts_
-              << " tries");
+        // Unable to allocate an address, return an empty lease.
+        LOG_WARN(dhcpsrv_logger, DHCPSRV_ADDRESS4_ALLOC_FAIL).arg(attempts_);
+
+    } catch (const isc::Exception& e) {
+
+        // Some other error, return an empty lease.
+        LOG_ERROR(dhcpsrv_logger, DHCPSRV_ADDRESS4_ALLOC_ERROR).arg(e.what());
+    }
+    return (Lease4Ptr());
 }
 
 Lease4Ptr AllocEngine::renewLease4(const SubnetPtr& subnet,

+ 13 - 1
src/lib/dhcpsrv/dhcpdb_create.mysql

@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Internet Systems Consortium.
+# Copyright (C) 2012-2013  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -39,6 +39,14 @@ CREATE TABLE lease4 (
     subnet_id INT UNSIGNED                      # Subnet identification
     ) ENGINE = INNODB;
 
+
+# Create search indexes for lease4 table 
+# index by hwaddr and subnet_id
+CREATE INDEX lease4_by_hwaddr_subnet_id ON lease4 (hwaddr, subnet_id);
+
+# index by client_id and subnet_id
+CREATE INDEX lease4_by_client_id_subnet_id ON lease4 (client_id, subnet_id);
+
 # Holds the IPv6 leases.
 # N.B. The use of a VARCHAR for the address is temporary for development:
 # it will eventually be replaced by BINARY(16).
@@ -55,6 +63,10 @@ CREATE TABLE lease6 (
     prefix_len TINYINT UNSIGNED                 # For IA_PD only
     ) ENGINE = INNODB;
 
+# Create search indexes for lease4 table 
+# index by iaid, subnet_id, and duid 
+CREATE INDEX lease6_by_iaid_subnet_id_duid ON lease6 (iaid, subnet_id, duid);
+
 # ... and a definition of lease6 types.  This table is a convenience for
 # users of the database - if they want to view the lease table and use the
 # type names, they can join this table with the lease6 table

+ 40 - 0
src/lib/dhcpsrv/dhcpsrv_messages.mes

@@ -14,6 +14,46 @@
 
 $NAMESPACE isc::dhcp
 
+% DHCPSRV_ADDRESS4_ALLOC_ERROR error during attempt to allocate an IPv4 address: %1
+An error occurred during an attempt to allocate an IPv4 address, the
+reason for the failure being contained in the message.  The server will
+return a message to the client refusing a lease.
+
+% DHCPSRV_ADDRESS4_ALLOC_FAIL failed to allocate an IPv4 address after %1 attempt(s)
+THE DHCP allocation engine gave up trying to allocate an IPv4 address
+after the specified number of attempts.  This probably means that the
+address pool from which the allocation is being attempted is either
+empty, or very nearly empty.  As a result, the client will have been
+refused a lease.
+
+This message may indicate that your address pool is too small for the
+number of clients you are trying to service and should be expanded.
+Alternatively, if the you know that the number of concurrently active
+clients is less than the addresses you have available, you may want to
+consider reducing the lease lifetime.  In this way, addresses allocated
+to clients that are no longer active on the network will become available
+available sooner.
+
+% DHCPSRV_ADDRESS6_ALLOC_ERROR error during attempt to allocate an IPv6 address: %1
+An error occurred during an attempt to allocate an IPv6 address, the
+reason for the failure being contained in the message.  The server will
+return a message to the client refusing a lease.
+
+% DHCPSRV_ADDRESS6_ALLOC_FAIL failed to allocate an IPv6 address after %1 attempt(s)
+The DHCP allocation engine gave up trying to allocate an IPv6 address
+after the specified number of attempts.  This probably means that the
+address pool from which the allocation is being attempted is either
+empty, or very nearly empty.  As a result, the client will have been
+refused a lease.
+
+This message may indicate that your address pool is too small for the
+number of clients you are trying to service and should be expanded.
+Alternatively, if the you know that the number of concurrently active
+clients is less than the addresses you have available, you may want to
+consider reducing the lease lifetime.  In this way, addresses allocated
+to clients that are no longer active on the network will become available
+available sooner.
+
 % DHCPSRV_CFGMGR_ADD_SUBNET4 adding subnet %1
 A debug message reported when the DHCP configuration manager is adding the
 specified IPv4 subnet to its database.

+ 12 - 1
src/lib/dhcpsrv/lease_mgr.cc

@@ -113,11 +113,22 @@ Lease4::toText() const {
 
 bool
 Lease4::operator==(const Lease4& other) const {
+    if ( (client_id_ && !other.client_id_) ||
+         (!client_id_ && other.client_id_) ) {
+        // One lease has client-id, but the other doesn't
+        return false;
+    }
+
+    if (client_id_ && other.client_id_ &&
+        *client_id_ != *other.client_id_) {
+        // Different client-ids
+        return false;
+    }
+
     return (
         addr_ == other.addr_ &&
         ext_ == other.ext_ &&
         hwaddr_ == other.hwaddr_ &&
-        *client_id_ == *other.client_id_ &&
         t1_ == other.t1_ &&
         t2_ == other.t2_ &&
         valid_lft_ == other.valid_lft_ &&

+ 19 - 6
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -338,12 +338,25 @@ public:
         bind_[1].length = &hwaddr_length_;
 
         // client_id: varbinary(128)
-        client_id_ = lease_->client_id_->getClientId();
-        client_id_length_ = client_id_.size();
-        bind_[2].buffer_type = MYSQL_TYPE_BLOB;
-        bind_[2].buffer = reinterpret_cast<char*>(&client_id_[0]);
-        bind_[2].buffer_length = client_id_length_;
-        bind_[2].length = &client_id_length_;
+        if (lease_->client_id_) {
+            client_id_ = lease_->client_id_->getClientId();
+            client_id_length_ = client_id_.size();
+            bind_[2].buffer_type = MYSQL_TYPE_BLOB;
+            bind_[2].buffer = reinterpret_cast<char*>(&client_id_[0]);
+            bind_[2].buffer_length = client_id_length_;
+            bind_[2].length = &client_id_length_;
+        } else {
+            bind_[2].buffer_type = MYSQL_TYPE_NULL;
+
+            // According to http://dev.mysql.com/doc/refman/5.5/en/
+            // c-api-prepared-statement-data-structures.html, the other
+            // fields doesn't matter if type is set to MYSQL_TYPE_NULL,
+            // but let's set them to some sane values in case earlier versions
+            // didn't have that assumption.
+            static my_bool no_clientid = MLM_TRUE;
+            bind_[2].buffer = NULL;
+            bind_[2].is_null = &no_clientid;
+        }
 
         // valid lifetime: unsigned int
         bind_[3].buffer_type = MYSQL_TYPE_LONG;

+ 6 - 5
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc

@@ -461,9 +461,9 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
 
     // There is just a single address in the pool and allocated it to someone
     // else, so the allocation should fail
-
-    EXPECT_THROW(engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),false),
-                 AllocFailed);
+    Lease6Ptr lease2 = engine->allocateAddress6(subnet_, duid_, iaid_,
+                                                IOAddress("::"), false);
+    EXPECT_FALSE(lease2);
 }
 
 // This test checks if an expired lease can be reused in SOLICIT (fake allocation)
@@ -838,8 +838,9 @@ TEST_F(AllocEngine4Test, outOfAddresses4) {
     // There is just a single address in the pool and allocated it to someone
     // else, so the allocation should fail
 
-    EXPECT_THROW(engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),false),
-                 AllocFailed);
+    Lease4Ptr lease2 = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
+                                                IOAddress("0.0.0.0"), false);
+    EXPECT_FALSE(lease2);
 }
 
 // This test checks if an expired lease can be reused in DISCOVER (fake allocation)

+ 4 - 0
src/lib/dns/Makefile.am

@@ -8,6 +8,10 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
 CLEANFILES += rrclass.h rrtype.h rrparamregistry.cc rdataclass.h rdataclass.cc
+# These two are created with rrtype/class.h, so not explicitly listed in
+# BUILT_SOURCES.
+CLEANFILES += python/rrtype_constants_inc.cc
+CLEANFILES += python/rrclass_constants_inc.cc
 
 EXTRA_DIST = rrclass-placeholder.h
 EXTRA_DIST += rrparamregistry-placeholder.cc

+ 92 - 26
src/lib/dns/gen-rdatacode.py.in

@@ -46,9 +46,30 @@ new_rdata_factory_users = [('aaaa', 'in'),
                            ('txt', 'generic')
                           ]
 
-re_typecode = re.compile('([\da-z]+)_(\d+)')
+re_typecode = re.compile('([\da-z\-]+)_(\d+)')
 classcode2txt = {}
 typecode2txt = {}
+# For meta types and types well-known but not implemented.  This is a dict from
+# type code values (as string) to textual mnemonic.
+meta_types = {
+    # Real meta types.  We won't have Rdata implement for them, but we need
+    # RRType constants.
+    '251': 'ixfr', '252': 'axfr', '255': 'any',
+    # Obsolete types.  We probalby won't implement Rdata for them, but it's
+    # better to have RRType constants.
+    '3': 'md', '4': 'mf', '7': 'mb', '8': 'mg', '9': 'mr', '30': 'nxt',
+    '38': 'a6', '254': 'maila',
+    # Types officially assigned but not yet supported in our implementation.
+    '10': 'null', '11': 'wks', '19': 'x25', '21': 'rt', '22': 'nsap',
+    '23': 'nsap-ptr', '24': 'sig', '20': 'isdn', '25': 'key', '26': 'px',
+    '27': 'gpos', '29': 'loc', '36': 'kx', '37': 'cert', '42': 'apl',
+    '45': 'ipseckey', '52': 'tlsa', '55': 'hip', '103': 'unspec',
+    '104': 'nid', '105': 'l32', '106': 'l64', '107': 'lp', '249':  'tkey',
+    '253': 'mailb', '256': 'uri', '257': 'caa'
+    }
+# Classes that don't have any known types.  This is a dict from type code
+# values (as string) to textual mnemonic.
+meta_classes = {'254': 'none'}
 typeandclass = []
 generic_code = 65536            # something larger than any code value
 rdata_declarations = ''
@@ -191,11 +212,11 @@ def import_definitions(classcode2txt, typecode2txt, typeandclass):
                     type_code = m.group(2)
                     if not type_code in typecode2txt:
                         typecode2txt[type_code] = type_txt
-                    if re.search('\cc$', file):
+                    if re.search('\.cc$', file):
                         if rdatadef_mtime < getmtime(file):
                             rdatadef_mtime = getmtime(file)
                         class_definitions += import_classdef(class_txt, file)
-                    elif re.search('\h$', file):
+                    elif re.search('\.h$', file):
                         if rdatahdr_mtime < getmtime(file):
                             rdatahdr_mtime = getmtime(file)
                         rdata_declarations += import_classheader(class_txt,
@@ -261,36 +282,66 @@ class MasterLoaderCallbacks;
 def generate_typeclasscode(fileprefix, basemtime, code2txt, type_or_class):
     placeholder = '@srcdir@/' + fileprefix + '-placeholder.h'
     outputfile = '@builddir@/' + fileprefix + '.h'
+    py_outputfile = '@builddir@/python/' + fileprefix + '_constants_inc.cc'
     upper_key = type_or_class.upper() # TYPE or CLASS
     lower_key = 'rr' + type_or_class.lower() # rrtype or rrclass
     cap_key = type_or_class           # Type or Class
 
-    if not need_generate(outputfile, basemtime) and getmtime(outputfile) > getmtime(placeholder):
+    # We only decide whether to generate files for libdns++ files; Python
+    # files are generated if and only if libdns++ files are generated.
+    # In practice it should be sufficient.
+    if (not need_generate(outputfile, basemtime) and
+        getmtime(outputfile) > getmtime(placeholder)):
         print('skip generating ' + outputfile)
         return
 
-    declarationtxt = ''
-    deftxt = ''
-    for code in code2txt.keys():
-        codetxt = code2txt[code].upper()
-        declarationtxt += ' ' * 4 + 'static const RR' + cap_key + '& ' + codetxt + '();\n'
-        deftxt += '''inline const RR''' + cap_key + '''&
-RR''' + cap_key + '''::''' + codetxt + '''() {
-    static RR''' + cap_key + ''' ''' + lower_key + '''(''' + code + ''');
+    # Create a list of (code, code-text) pairs, where code-text is generally
+    # upper-cased, with applying speicial filters when necessary.
+    def convert(code_txt):
+        # Workaround by heuristics: there's a "NULL" RR type, but it would
+        # cause conflict with the C/C++ macro.  We use Null as a special case.
+        if code_txt == 'null':
+            return 'Null'
+        # Likewise, convert "nsap-ptr" to "NSAP_PTR" as a dash cannot be part
+        # of a C/C++ variable.
+        if code_txt == 'nsap-ptr':
+            return 'NSAP_PTR'
+        return code_txt.upper()
+    codes = [ (code, convert(txt)) for code, txt in code2txt.items() ]
+
+    # Dump source code for libdns++
+    with  open(placeholder, 'r') as header_temp:
+        with open(outputfile, 'w') as header_out:
+            header_out.write(heading_txt)
+            for line in header_temp:
+                header_out.write(line)
+                if re.match('\s+// BEGIN_WELL_KNOWN_' + upper_key +
+                            '_DECLARATIONS$', line):
+                    for code in codes:
+                        header_out.write(' ' * 4 + 'static const RR' +
+                                         cap_key + '& ' + code[1] + '();\n')
+                if re.match('// BEGIN_WELL_KNOWN_' + upper_key +
+                            '_DEFINITIONS$', line):
+                    for code in codes:
+                        header_out.write('''inline const RR''' + cap_key +
+                                         '''&
+RR''' + cap_key + '''::''' + code[1] + '''() {
+    static RR''' + cap_key + ''' ''' + lower_key + '''(''' + code[0] + ''');
     return (''' + lower_key + ''');
 }\n
-'''
-    header_temp = open(placeholder, 'r')
-    header_out = open(outputfile, 'w')
-    header_out.write(heading_txt)
-    for line in header_temp.readlines():
-        header_out.write(line)
-        if re.match('\s+// BEGIN_WELL_KNOWN_' + upper_key + '_DECLARATIONS$', line):
-            header_out.write(declarationtxt)
-        if re.match('// BEGIN_WELL_KNOWN_' + upper_key + '_DEFINITIONS$', line):
-            header_out.write('\n' + deftxt)
-    header_out.close()
-    header_temp.close()
+''')
+
+    # Dump source code snippet for isc.dns Python module
+    with open(py_outputfile, 'w') as py_out:
+        py_out.write("    // auto-generated by ../gen-rdatacode.py."
+                     "  Don't edit this file.\n")
+        py_out.write("\n")
+        for code in codes:
+            py_out.write('''\
+    installClassVariable(''' + lower_key + '''_type, "''' + code[1] + '''",
+                         createRR''' + cap_key + '''Object(RR''' + \
+        cap_key + '''::''' + code[1] + '''()));
+''')
 
 def generate_rrparam(fileprefix, basemtime):
     placeholder = '@srcdir@/' + fileprefix + '-placeholder.cc'
@@ -337,6 +388,16 @@ def generate_rrparam(fileprefix, basemtime):
             typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<'
             typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
 
+    typeandclassparams += indent + '// Meta and non-implemented RR types\n'
+    for type_code, type_txt in meta_types.items():
+        typeandclassparams += indent + \
+            'addType("' + type_txt.upper() + '", ' + type_code + ');\n'
+
+    typeandclassparams += indent + '// Meta classes\n'
+    for cls_code, cls_txt in meta_classes.items():
+        typeandclassparams += indent + \
+            'addClass("' + cls_txt.upper() + '", ' + cls_code + ');\n'
+
     rrparam_temp = open(placeholder, 'r')
     rrparam_out = open(outputfile, 'w')
     rrparam_out.write(heading_txt)
@@ -353,9 +414,14 @@ if __name__ == "__main__":
         generate_rdatadef('@builddir@/rdataclass.cc', rdatadef_mtime)
         generate_rdatahdr('@builddir@/rdataclass.h', heading_txt,
                           rdata_declarations, rdatahdr_mtime)
-        generate_typeclasscode('rrtype', rdatahdr_mtime, typecode2txt, 'Type')
+
+        # merge auto-generated types/classes with meta maps and generate the
+        # corresponding code.
+        generate_typeclasscode('rrtype', rdatahdr_mtime,
+                               dict(typecode2txt, **meta_types), 'Type')
         generate_typeclasscode('rrclass', classdir_mtime,
-                               classcode2txt, 'Class')
+                               dict(classcode2txt, **meta_classes), 'Class')
+
         generate_rrparam('rrparamregistry', rdatahdr_mtime)
     except:
         sys.stderr.write('Code generation failed due to exception: %s\n' %

+ 1 - 0
src/lib/dns/master_loader.cc

@@ -54,6 +54,7 @@ public:
 
 } // end unnamed namespace
 
+// cppcheck-suppress noConstructor
 class MasterLoader::MasterLoaderImpl {
 public:
     MasterLoaderImpl(const char* master_file,

+ 0 - 1
src/lib/dns/name.cc

@@ -227,7 +227,6 @@ stringParse(Iterator s, Iterator send, bool downcase, Offsets& offsets,
                 isc_throw(BadLabelType,
                           "invalid label type in " << string(orig_s, send));
             }
-            state = ft_escape;
             // FALLTHROUGH
         case ft_escape:
             if (!isdigit(c & 0xff)) {

+ 0 - 140
src/lib/dns/python/opcode_python.cc

@@ -43,62 +43,12 @@ void Opcode_destroy(s_Opcode* const self);
 PyObject* Opcode_getCode(const s_Opcode* const self);
 PyObject* Opcode_toText(const s_Opcode* const self);
 PyObject* Opcode_str(PyObject* self);
-PyObject* Opcode_QUERY(const s_Opcode* self);
-PyObject* Opcode_IQUERY(const s_Opcode* self);
-PyObject* Opcode_STATUS(const s_Opcode* self);
-PyObject* Opcode_RESERVED3(const s_Opcode* self);
-PyObject* Opcode_NOTIFY(const s_Opcode* self);
-PyObject* Opcode_UPDATE(const s_Opcode* self);
-PyObject* Opcode_RESERVED6(const s_Opcode* self);
-PyObject* Opcode_RESERVED7(const s_Opcode* self);
-PyObject* Opcode_RESERVED8(const s_Opcode* self);
-PyObject* Opcode_RESERVED9(const s_Opcode* self);
-PyObject* Opcode_RESERVED10(const s_Opcode* self);
-PyObject* Opcode_RESERVED11(const s_Opcode* self);
-PyObject* Opcode_RESERVED12(const s_Opcode* self);
-PyObject* Opcode_RESERVED13(const s_Opcode* self);
-PyObject* Opcode_RESERVED14(const s_Opcode* self);
-PyObject* Opcode_RESERVED15(const s_Opcode* self);
-PyObject* Opcode_richcmp(const s_Opcode* const self,
-                         const s_Opcode* const other, int op);
 
 PyMethodDef Opcode_methods[] = {
     { "get_code", reinterpret_cast<PyCFunction>(Opcode_getCode), METH_NOARGS,
       "Returns the code value" },
     { "to_text", reinterpret_cast<PyCFunction>(Opcode_toText), METH_NOARGS,
       "Returns the text representation" },
-    { "QUERY", reinterpret_cast<PyCFunction>(Opcode_QUERY),
-      METH_NOARGS | METH_STATIC, "Creates a QUERY Opcode" },
-    { "IQUERY", reinterpret_cast<PyCFunction>(Opcode_IQUERY),
-      METH_NOARGS | METH_STATIC, "Creates a IQUERY Opcode" },
-    { "STATUS", reinterpret_cast<PyCFunction>(Opcode_STATUS),
-      METH_NOARGS | METH_STATIC, "Creates a STATUS Opcode" },
-    { "RESERVED3", reinterpret_cast<PyCFunction>(Opcode_RESERVED3),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED3 Opcode" },
-    { "NOTIFY", reinterpret_cast<PyCFunction>(Opcode_NOTIFY),
-      METH_NOARGS | METH_STATIC, "Creates a NOTIFY Opcode" },
-    { "UPDATE", reinterpret_cast<PyCFunction>(Opcode_UPDATE),
-      METH_NOARGS | METH_STATIC, "Creates a UPDATE Opcode" },
-    { "RESERVED6", reinterpret_cast<PyCFunction>(Opcode_RESERVED6),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED6 Opcode" },
-    { "RESERVED7", reinterpret_cast<PyCFunction>(Opcode_RESERVED7),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED7 Opcode" },
-    { "RESERVED8", reinterpret_cast<PyCFunction>(Opcode_RESERVED8),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED8 Opcode" },
-    { "RESERVED9", reinterpret_cast<PyCFunction>(Opcode_RESERVED9),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED9 Opcode" },
-    { "RESERVED10", reinterpret_cast<PyCFunction>(Opcode_RESERVED10),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED10 Opcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Opcode_RESERVED11),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED11 Opcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Opcode_RESERVED12),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED12 Opcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Opcode_RESERVED13),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED13 Opcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Opcode_RESERVED14),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED14 Opcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Opcode_RESERVED15),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED15 Opcode" },
     { NULL, NULL, 0, NULL }
 };
 
@@ -156,96 +106,6 @@ Opcode_str(PyObject* self) {
 }
 
 PyObject*
-Opcode_createStatic(const Opcode& opcode) {
-    s_Opcode* ret = PyObject_New(s_Opcode, &opcode_type);
-    if (ret != NULL) {
-        ret->cppobj = &opcode;
-        ret->static_code = true;
-    }
-    return (ret);
-}
-
-PyObject*
-Opcode_QUERY(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::QUERY()));
-}
-
-PyObject*
-Opcode_IQUERY(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::IQUERY()));
-}
-
-PyObject*
-Opcode_STATUS(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::STATUS()));
-}
-
-PyObject*
-Opcode_RESERVED3(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED3()));
-}
-
-PyObject*
-Opcode_NOTIFY(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::NOTIFY()));
-}
-
-PyObject*
-Opcode_UPDATE(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::UPDATE()));
-}
-
-PyObject*
-Opcode_RESERVED6(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED6()));
-}
-
-PyObject*
-Opcode_RESERVED7(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED7()));
-}
-
-PyObject*
-Opcode_RESERVED8(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED8()));
-}
-
-PyObject*
-Opcode_RESERVED9(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED9()));
-}
-
-PyObject*
-Opcode_RESERVED10(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED10()));
-}
-
-PyObject*
-Opcode_RESERVED11(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED11()));
-}
-
-PyObject*
-Opcode_RESERVED12(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED12()));
-}
-
-PyObject*
-Opcode_RESERVED13(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED13()));
-}
-
-PyObject*
-Opcode_RESERVED14(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED14()));
-}
-
-PyObject*
-Opcode_RESERVED15(const s_Opcode*) {
-    return (Opcode_createStatic(Opcode::RESERVED15()));
-}
-
-PyObject*
 Opcode_richcmp(const s_Opcode* const self, const s_Opcode* const other,
                const int op)
 {

+ 164 - 66
src/lib/dns/python/pydnspp.cc

@@ -294,38 +294,83 @@ initModulePart_Opcode(PyObject* mod) {
         return (false);
     }
 
-    addClassVariable(opcode_type, "QUERY_CODE",
-                     Py_BuildValue("h", Opcode::QUERY_CODE));
-    addClassVariable(opcode_type, "IQUERY_CODE",
-                     Py_BuildValue("h", Opcode::IQUERY_CODE));
-    addClassVariable(opcode_type, "STATUS_CODE",
-                     Py_BuildValue("h", Opcode::STATUS_CODE));
-    addClassVariable(opcode_type, "RESERVED3_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED3_CODE));
-    addClassVariable(opcode_type, "NOTIFY_CODE",
-                     Py_BuildValue("h", Opcode::NOTIFY_CODE));
-    addClassVariable(opcode_type, "UPDATE_CODE",
-                     Py_BuildValue("h", Opcode::UPDATE_CODE));
-    addClassVariable(opcode_type, "RESERVED6_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED6_CODE));
-    addClassVariable(opcode_type, "RESERVED7_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED7_CODE));
-    addClassVariable(opcode_type, "RESERVED8_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED8_CODE));
-    addClassVariable(opcode_type, "RESERVED9_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED9_CODE));
-    addClassVariable(opcode_type, "RESERVED10_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED10_CODE));
-    addClassVariable(opcode_type, "RESERVED11_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED11_CODE));
-    addClassVariable(opcode_type, "RESERVED12_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED12_CODE));
-    addClassVariable(opcode_type, "RESERVED13_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED13_CODE));
-    addClassVariable(opcode_type, "RESERVED14_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED14_CODE));
-    addClassVariable(opcode_type, "RESERVED15_CODE",
-                     Py_BuildValue("h", Opcode::RESERVED15_CODE));
+    try {
+        installClassVariable(opcode_type, "QUERY_CODE",
+                             Py_BuildValue("h", Opcode::QUERY_CODE));
+        installClassVariable(opcode_type, "IQUERY_CODE",
+                             Py_BuildValue("h", Opcode::IQUERY_CODE));
+        installClassVariable(opcode_type, "STATUS_CODE",
+                             Py_BuildValue("h", Opcode::STATUS_CODE));
+        installClassVariable(opcode_type, "RESERVED3_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED3_CODE));
+        installClassVariable(opcode_type, "NOTIFY_CODE",
+                             Py_BuildValue("h", Opcode::NOTIFY_CODE));
+        installClassVariable(opcode_type, "UPDATE_CODE",
+                             Py_BuildValue("h", Opcode::UPDATE_CODE));
+        installClassVariable(opcode_type, "RESERVED6_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED6_CODE));
+        installClassVariable(opcode_type, "RESERVED7_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED7_CODE));
+        installClassVariable(opcode_type, "RESERVED8_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED8_CODE));
+        installClassVariable(opcode_type, "RESERVED9_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED9_CODE));
+        installClassVariable(opcode_type, "RESERVED10_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED10_CODE));
+        installClassVariable(opcode_type, "RESERVED11_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED11_CODE));
+        installClassVariable(opcode_type, "RESERVED12_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED12_CODE));
+        installClassVariable(opcode_type, "RESERVED13_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED13_CODE));
+        installClassVariable(opcode_type, "RESERVED14_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED14_CODE));
+        installClassVariable(opcode_type, "RESERVED15_CODE",
+                             Py_BuildValue("h", Opcode::RESERVED15_CODE));
+
+        installClassVariable(opcode_type, "QUERY",
+                             createOpcodeObject(Opcode::QUERY()));
+        installClassVariable(opcode_type, "IQUERY",
+                             createOpcodeObject(Opcode::IQUERY()));
+        installClassVariable(opcode_type, "STATUS",
+                             createOpcodeObject(Opcode::STATUS()));
+        installClassVariable(opcode_type, "RESERVED3",
+                             createOpcodeObject(Opcode::RESERVED3()));
+        installClassVariable(opcode_type, "NOTIFY",
+                             createOpcodeObject(Opcode::NOTIFY()));
+        installClassVariable(opcode_type, "UPDATE",
+                             createOpcodeObject(Opcode::UPDATE()));
+        installClassVariable(opcode_type, "RESERVED6",
+                             createOpcodeObject(Opcode::RESERVED6()));
+        installClassVariable(opcode_type, "RESERVED7",
+                             createOpcodeObject(Opcode::RESERVED7()));
+        installClassVariable(opcode_type, "RESERVED8",
+                             createOpcodeObject(Opcode::RESERVED8()));
+        installClassVariable(opcode_type, "RESERVED9",
+                             createOpcodeObject(Opcode::RESERVED9()));
+        installClassVariable(opcode_type, "RESERVED10",
+                             createOpcodeObject(Opcode::RESERVED10()));
+        installClassVariable(opcode_type, "RESERVED11",
+                             createOpcodeObject(Opcode::RESERVED11()));
+        installClassVariable(opcode_type, "RESERVED12",
+                             createOpcodeObject(Opcode::RESERVED12()));
+        installClassVariable(opcode_type, "RESERVED13",
+                             createOpcodeObject(Opcode::RESERVED13()));
+        installClassVariable(opcode_type, "RESERVED14",
+                             createOpcodeObject(Opcode::RESERVED14()));
+        installClassVariable(opcode_type, "RESERVED15",
+                             createOpcodeObject(Opcode::RESERVED15()));
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in Opcode initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in Opcode initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -341,40 +386,87 @@ initModulePart_Rcode(PyObject* mod) {
         return (false);
     }
 
-    addClassVariable(rcode_type, "NOERROR_CODE",
-                     Py_BuildValue("h", Rcode::NOERROR_CODE));
-    addClassVariable(rcode_type, "FORMERR_CODE",
-                     Py_BuildValue("h", Rcode::FORMERR_CODE));
-    addClassVariable(rcode_type, "SERVFAIL_CODE",
-                     Py_BuildValue("h", Rcode::SERVFAIL_CODE));
-    addClassVariable(rcode_type, "NXDOMAIN_CODE",
-                     Py_BuildValue("h", Rcode::NXDOMAIN_CODE));
-    addClassVariable(rcode_type, "NOTIMP_CODE",
-                     Py_BuildValue("h", Rcode::NOTIMP_CODE));
-    addClassVariable(rcode_type, "REFUSED_CODE",
-                     Py_BuildValue("h", Rcode::REFUSED_CODE));
-    addClassVariable(rcode_type, "YXDOMAIN_CODE",
-                     Py_BuildValue("h", Rcode::YXDOMAIN_CODE));
-    addClassVariable(rcode_type, "YXRRSET_CODE",
-                     Py_BuildValue("h", Rcode::YXRRSET_CODE));
-    addClassVariable(rcode_type, "NXRRSET_CODE",
-                     Py_BuildValue("h", Rcode::NXRRSET_CODE));
-    addClassVariable(rcode_type, "NOTAUTH_CODE",
-                     Py_BuildValue("h", Rcode::NOTAUTH_CODE));
-    addClassVariable(rcode_type, "NOTZONE_CODE",
-                     Py_BuildValue("h", Rcode::NOTZONE_CODE));
-    addClassVariable(rcode_type, "RESERVED11_CODE",
-                     Py_BuildValue("h", Rcode::RESERVED11_CODE));
-    addClassVariable(rcode_type, "RESERVED12_CODE",
-                     Py_BuildValue("h", Rcode::RESERVED12_CODE));
-    addClassVariable(rcode_type, "RESERVED13_CODE",
-                     Py_BuildValue("h", Rcode::RESERVED13_CODE));
-    addClassVariable(rcode_type, "RESERVED14_CODE",
-                     Py_BuildValue("h", Rcode::RESERVED14_CODE));
-    addClassVariable(rcode_type, "RESERVED15_CODE",
-                     Py_BuildValue("h", Rcode::RESERVED15_CODE));
-    addClassVariable(rcode_type, "BADVERS_CODE",
-                     Py_BuildValue("h", Rcode::BADVERS_CODE));
+    try {
+        installClassVariable(rcode_type, "NOERROR_CODE",
+                             Py_BuildValue("h", Rcode::NOERROR_CODE));
+        installClassVariable(rcode_type, "FORMERR_CODE",
+                             Py_BuildValue("h", Rcode::FORMERR_CODE));
+        installClassVariable(rcode_type, "SERVFAIL_CODE",
+                             Py_BuildValue("h", Rcode::SERVFAIL_CODE));
+        installClassVariable(rcode_type, "NXDOMAIN_CODE",
+                             Py_BuildValue("h", Rcode::NXDOMAIN_CODE));
+        installClassVariable(rcode_type, "NOTIMP_CODE",
+                             Py_BuildValue("h", Rcode::NOTIMP_CODE));
+        installClassVariable(rcode_type, "REFUSED_CODE",
+                             Py_BuildValue("h", Rcode::REFUSED_CODE));
+        installClassVariable(rcode_type, "YXDOMAIN_CODE",
+                             Py_BuildValue("h", Rcode::YXDOMAIN_CODE));
+        installClassVariable(rcode_type, "YXRRSET_CODE",
+                             Py_BuildValue("h", Rcode::YXRRSET_CODE));
+        installClassVariable(rcode_type, "NXRRSET_CODE",
+                             Py_BuildValue("h", Rcode::NXRRSET_CODE));
+        installClassVariable(rcode_type, "NOTAUTH_CODE",
+                             Py_BuildValue("h", Rcode::NOTAUTH_CODE));
+        installClassVariable(rcode_type, "NOTZONE_CODE",
+                             Py_BuildValue("h", Rcode::NOTZONE_CODE));
+        installClassVariable(rcode_type, "RESERVED11_CODE",
+                             Py_BuildValue("h", Rcode::RESERVED11_CODE));
+        installClassVariable(rcode_type, "RESERVED12_CODE",
+                             Py_BuildValue("h", Rcode::RESERVED12_CODE));
+        installClassVariable(rcode_type, "RESERVED13_CODE",
+                             Py_BuildValue("h", Rcode::RESERVED13_CODE));
+        installClassVariable(rcode_type, "RESERVED14_CODE",
+                             Py_BuildValue("h", Rcode::RESERVED14_CODE));
+        installClassVariable(rcode_type, "RESERVED15_CODE",
+                             Py_BuildValue("h", Rcode::RESERVED15_CODE));
+        installClassVariable(rcode_type, "BADVERS_CODE",
+                             Py_BuildValue("h", Rcode::BADVERS_CODE));
+
+        installClassVariable(rcode_type, "NOERROR",
+                             createRcodeObject(Rcode::NOERROR()));
+        installClassVariable(rcode_type, "FORMERR",
+                             createRcodeObject(Rcode::FORMERR()));
+        installClassVariable(rcode_type, "SERVFAIL",
+                             createRcodeObject(Rcode::SERVFAIL()));
+        installClassVariable(rcode_type, "NXDOMAIN",
+                             createRcodeObject(Rcode::NXDOMAIN()));
+        installClassVariable(rcode_type, "NOTIMP",
+                             createRcodeObject(Rcode::NOTIMP()));
+        installClassVariable(rcode_type, "REFUSED",
+                             createRcodeObject(Rcode::REFUSED()));
+        installClassVariable(rcode_type, "YXDOMAIN",
+                             createRcodeObject(Rcode::YXDOMAIN()));
+        installClassVariable(rcode_type, "YXRRSET",
+                             createRcodeObject(Rcode::YXRRSET()));
+        installClassVariable(rcode_type, "NXRRSET",
+                             createRcodeObject(Rcode::NXRRSET()));
+        installClassVariable(rcode_type, "NOTAUTH",
+                             createRcodeObject(Rcode::NOTAUTH()));
+        installClassVariable(rcode_type, "NOTZONE",
+                             createRcodeObject(Rcode::NOTZONE()));
+        installClassVariable(rcode_type, "RESERVED11",
+                             createRcodeObject(Rcode::RESERVED11()));
+        installClassVariable(rcode_type, "RESERVED12",
+                             createRcodeObject(Rcode::RESERVED12()));
+        installClassVariable(rcode_type, "RESERVED13",
+                             createRcodeObject(Rcode::RESERVED13()));
+        installClassVariable(rcode_type, "RESERVED14",
+                             createRcodeObject(Rcode::RESERVED14()));
+        installClassVariable(rcode_type, "RESERVED15",
+                             createRcodeObject(Rcode::RESERVED15()));
+        installClassVariable(rcode_type, "BADVERS",
+                             createRcodeObject(Rcode::BADVERS()));
+    } catch (const std::exception& ex) {
+        const std::string ex_what =
+            "Unexpected failure in Rcode initialization: " +
+            std::string(ex.what());
+        PyErr_SetString(po_IscException, ex_what.c_str());
+        return (false);
+    } catch (...) {
+        PyErr_SetString(PyExc_SystemError,
+                        "Unexpected failure in Rcode initialization");
+        return (false);
+    }
 
     return (true);
 }
@@ -432,6 +524,9 @@ initModulePart_RRClass(PyObject* mod) {
                                                   NULL, NULL);
         PyObjectContainer(po_IncompleteRRClass).installToModule(
             mod, "IncompleteRRClass");
+
+        // Incorporate auto-generated RRClass constants
+#include <dns/python/rrclass_constants_inc.cc>
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in RRClass initialization: " +
@@ -518,6 +613,9 @@ initModulePart_RRType(PyObject* mod) {
                                                  NULL, NULL);
         PyObjectContainer(po_IncompleteRRType).installToModule(
             mod, "IncompleteRRType");
+
+        // Incorporate auto-generated RRType constants
+#include <dns/python/rrtype_constants_inc.cc>
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in RRType initialization: " +

+ 0 - 146
src/lib/dns/python/rcode_python.cc

@@ -55,23 +55,6 @@ PyObject* Rcode_getCode(const s_Rcode* const self);
 PyObject* Rcode_getExtendedCode(const s_Rcode* const self);
 PyObject* Rcode_toText(const s_Rcode* const self);
 PyObject* Rcode_str(PyObject* self);
-PyObject* Rcode_NOERROR(const s_Rcode* self);
-PyObject* Rcode_FORMERR(const s_Rcode* self);
-PyObject* Rcode_SERVFAIL(const s_Rcode* self);
-PyObject* Rcode_NXDOMAIN(const s_Rcode* self);
-PyObject* Rcode_NOTIMP(const s_Rcode* self);
-PyObject* Rcode_REFUSED(const s_Rcode* self);
-PyObject* Rcode_YXDOMAIN(const s_Rcode* self);
-PyObject* Rcode_YXRRSET(const s_Rcode* self);
-PyObject* Rcode_NXRRSET(const s_Rcode* self);
-PyObject* Rcode_NOTAUTH(const s_Rcode* self);
-PyObject* Rcode_NOTZONE(const s_Rcode* self);
-PyObject* Rcode_RESERVED11(const s_Rcode* self);
-PyObject* Rcode_RESERVED12(const s_Rcode* self);
-PyObject* Rcode_RESERVED13(const s_Rcode* self);
-PyObject* Rcode_RESERVED14(const s_Rcode* self);
-PyObject* Rcode_RESERVED15(const s_Rcode* self);
-PyObject* Rcode_BADVERS(const s_Rcode* self);
 PyObject* Rcode_richcmp(const s_Rcode* const self,
                          const s_Rcode* const other, int op);
 
@@ -83,40 +66,6 @@ PyMethodDef Rcode_methods[] = {
       "Returns the upper 8-bit part of the extended code value" },
     { "to_text", reinterpret_cast<PyCFunction>(Rcode_toText), METH_NOARGS,
       "Returns the text representation" },
-    { "NOERROR", reinterpret_cast<PyCFunction>(Rcode_NOERROR),
-      METH_NOARGS | METH_STATIC, "Creates a NOERROR Rcode" },
-    { "FORMERR", reinterpret_cast<PyCFunction>(Rcode_FORMERR),
-      METH_NOARGS | METH_STATIC, "Creates a FORMERR Rcode" },
-    { "SERVFAIL", reinterpret_cast<PyCFunction>(Rcode_SERVFAIL),
-      METH_NOARGS | METH_STATIC, "Creates a SERVFAIL Rcode" },
-    { "NXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_NXDOMAIN),
-      METH_NOARGS | METH_STATIC, "Creates a NXDOMAIN Rcode" },
-    { "NOTIMP", reinterpret_cast<PyCFunction>(Rcode_NOTIMP),
-      METH_NOARGS | METH_STATIC, "Creates a NOTIMP Rcode" },
-    { "REFUSED", reinterpret_cast<PyCFunction>(Rcode_REFUSED),
-      METH_NOARGS | METH_STATIC, "Creates a REFUSED Rcode" },
-    { "YXDOMAIN", reinterpret_cast<PyCFunction>(Rcode_YXDOMAIN),
-      METH_NOARGS | METH_STATIC, "Creates a YXDOMAIN Rcode" },
-    { "YXRRSET", reinterpret_cast<PyCFunction>(Rcode_YXRRSET),
-      METH_NOARGS | METH_STATIC, "Creates a YYRRSET Rcode" },
-    { "NXRRSET", reinterpret_cast<PyCFunction>(Rcode_NXRRSET),
-      METH_NOARGS | METH_STATIC, "Creates a NXRRSET Rcode" },
-    { "NOTAUTH", reinterpret_cast<PyCFunction>(Rcode_NOTAUTH),
-      METH_NOARGS | METH_STATIC, "Creates a NOTAUTH Rcode" },
-    { "NOTZONE", reinterpret_cast<PyCFunction>(Rcode_NOTZONE),
-      METH_NOARGS | METH_STATIC, "Creates a NOTZONE Rcode" },
-    { "RESERVED11", reinterpret_cast<PyCFunction>(Rcode_RESERVED11),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED11 Rcode" },
-    { "RESERVED12", reinterpret_cast<PyCFunction>(Rcode_RESERVED12),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED12 Rcode" },
-    { "RESERVED13", reinterpret_cast<PyCFunction>(Rcode_RESERVED13),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED13 Rcode" },
-    { "RESERVED14", reinterpret_cast<PyCFunction>(Rcode_RESERVED14),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED14 Rcode" },
-    { "RESERVED15", reinterpret_cast<PyCFunction>(Rcode_RESERVED15),
-      METH_NOARGS | METH_STATIC, "Creates a RESERVED15 Rcode" },
-    { "BADVERS", reinterpret_cast<PyCFunction>(Rcode_BADVERS),
-      METH_NOARGS | METH_STATIC, "Creates a BADVERS Rcode" },
     { NULL, NULL, 0, NULL }
 };
 
@@ -193,101 +142,6 @@ Rcode_str(PyObject* self) {
 }
 
 PyObject*
-Rcode_createStatic(const Rcode& rcode) {
-    s_Rcode* ret = PyObject_New(s_Rcode, &rcode_type);
-    if (ret != NULL) {
-        ret->cppobj = &rcode;
-        ret->static_code = true;
-    }
-    return (ret);
-}
-
-PyObject*
-Rcode_NOERROR(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NOERROR()));
-}
-
-PyObject*
-Rcode_FORMERR(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::FORMERR()));
-}
-
-PyObject*
-Rcode_SERVFAIL(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::SERVFAIL()));
-}
-
-PyObject*
-Rcode_NXDOMAIN(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NXDOMAIN()));
-}
-
-PyObject*
-Rcode_NOTIMP(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NOTIMP()));
-}
-
-PyObject*
-Rcode_REFUSED(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::REFUSED()));
-}
-
-PyObject*
-Rcode_YXDOMAIN(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::YXDOMAIN()));
-}
-
-PyObject*
-Rcode_YXRRSET(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::YXRRSET()));
-}
-
-PyObject*
-Rcode_NXRRSET(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NXRRSET()));
-}
-
-PyObject*
-Rcode_NOTAUTH(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NOTAUTH()));
-}
-
-PyObject*
-Rcode_NOTZONE(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::NOTZONE()));
-}
-
-PyObject*
-Rcode_RESERVED11(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::RESERVED11()));
-}
-
-PyObject*
-Rcode_RESERVED12(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::RESERVED12()));
-}
-
-PyObject*
-Rcode_RESERVED13(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::RESERVED13()));
-}
-
-PyObject*
-Rcode_RESERVED14(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::RESERVED14()));
-}
-
-PyObject*
-Rcode_RESERVED15(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::RESERVED15()));
-}
-
-PyObject*
-Rcode_BADVERS(const s_Rcode*) {
-    return (Rcode_createStatic(Rcode::BADVERS()));
-}
-
-PyObject*
 Rcode_richcmp(const s_Rcode* const self, const s_Rcode* const other,
               const int op)
 {

+ 0 - 43
src/lib/dns/python/rrclass_python.cc

@@ -54,13 +54,6 @@ PyObject* RRClass_getCode(s_RRClass* self);
 PyObject* RRClass_richcmp(s_RRClass* self, s_RRClass* other, int op);
 Py_hash_t RRClass_hash(PyObject* pyself);
 
-// Static function for direct class creation
-PyObject* RRClass_IN(s_RRClass *self);
-PyObject* RRClass_CH(s_RRClass *self);
-PyObject* RRClass_HS(s_RRClass *self);
-PyObject* RRClass_NONE(s_RRClass *self);
-PyObject* RRClass_ANY(s_RRClass *self);
-
 typedef CPPPyObjectContainer<s_RRClass, RRClass> RRClassContainer;
 
 // This list contains the actual set of functions we have in
@@ -81,11 +74,6 @@ PyMethodDef RRClass_methods[] = {
       "returned" },
     { "get_code", reinterpret_cast<PyCFunction>(RRClass_getCode), METH_NOARGS,
       "Returns the class code as an integer" },
-    { "IN", reinterpret_cast<PyCFunction>(RRClass_IN), METH_NOARGS | METH_STATIC, "Creates an IN RRClass" },
-    { "CH", reinterpret_cast<PyCFunction>(RRClass_CH), METH_NOARGS | METH_STATIC, "Creates a CH RRClass" },
-    { "HS", reinterpret_cast<PyCFunction>(RRClass_HS), METH_NOARGS | METH_STATIC, "Creates an HS RRClass" },
-    { "NONE", reinterpret_cast<PyCFunction>(RRClass_NONE), METH_NOARGS | METH_STATIC, "Creates a NONE RRClass" },
-    { "ANY", reinterpret_cast<PyCFunction>(RRClass_ANY), METH_NOARGS | METH_STATIC, "Creates an ANY RRClass" },
     { NULL, NULL, 0, NULL }
 };
 
@@ -234,37 +222,6 @@ RRClass_richcmp(s_RRClass* self, s_RRClass* other, int op) {
         Py_RETURN_FALSE;
 }
 
-//
-// Common function for RRClass_IN/CH/etc.
-//
-PyObject* RRClass_createStatic(RRClass stc) {
-    s_RRClass* ret = PyObject_New(s_RRClass, &rrclass_type);
-    if (ret != NULL) {
-        ret->cppobj = new RRClass(stc);
-    }
-    return (ret);
-}
-
-PyObject* RRClass_IN(s_RRClass*) {
-    return (RRClass_createStatic(RRClass::IN()));
-}
-
-PyObject* RRClass_CH(s_RRClass*) {
-    return (RRClass_createStatic(RRClass::CH()));
-}
-
-PyObject* RRClass_HS(s_RRClass*) {
-    return (RRClass_createStatic(RRClass::HS()));
-}
-
-PyObject* RRClass_NONE(s_RRClass*) {
-    return (RRClass_createStatic(RRClass::NONE()));
-}
-
-PyObject* RRClass_ANY(s_RRClass*) {
-    return (RRClass_createStatic(RRClass::ANY()));
-}
-
 Py_hash_t
 RRClass_hash(PyObject* pyself) {
     const s_RRClass* const self = static_cast<s_RRClass*>(pyself);

+ 0 - 144
src/lib/dns/python/rrtype_python.cc

@@ -50,25 +50,6 @@ PyObject* RRType_toWire(s_RRType* self, PyObject* args);
 PyObject* RRType_getCode(s_RRType* self);
 PyObject* RRType_richcmp(s_RRType* self, s_RRType* other, int op);
 Py_hash_t RRType_hash(PyObject* pyself);
-PyObject* RRType_NSEC3PARAM(s_RRType *self);
-PyObject* RRType_DNAME(s_RRType *self);
-PyObject* RRType_PTR(s_RRType *self);
-PyObject* RRType_MX(s_RRType *self);
-PyObject* RRType_DNSKEY(s_RRType *self);
-PyObject* RRType_TXT(s_RRType *self);
-PyObject* RRType_RRSIG(s_RRType *self);
-PyObject* RRType_NSEC(s_RRType *self);
-PyObject* RRType_AAAA(s_RRType *self);
-PyObject* RRType_DS(s_RRType *self);
-PyObject* RRType_OPT(s_RRType *self);
-PyObject* RRType_A(s_RRType *self);
-PyObject* RRType_NS(s_RRType *self);
-PyObject* RRType_CNAME(s_RRType *self);
-PyObject* RRType_SOA(s_RRType *self);
-PyObject* RRType_NSEC3(s_RRType *self);
-PyObject* RRType_IXFR(s_RRType *self);
-PyObject* RRType_AXFR(s_RRType *self);
-PyObject* RRType_ANY(s_RRType *self);
 
 typedef CPPPyObjectContainer<s_RRType, RRType> RRTypeContainer;
 
@@ -90,25 +71,6 @@ PyMethodDef RRType_methods[] = {
       "returned" },
     { "get_code", reinterpret_cast<PyCFunction>(RRType_getCode), METH_NOARGS,
       "Returns the type code as an integer" },
-    { "NSEC3PARAM", reinterpret_cast<PyCFunction>(RRType_NSEC3PARAM), METH_NOARGS | METH_STATIC, "Creates an NSEC3PARAM RRType" },
-    { "DNAME", reinterpret_cast<PyCFunction>(RRType_DNAME), METH_NOARGS | METH_STATIC, "Creates a DNAME RRType" },
-    { "PTR", reinterpret_cast<PyCFunction>(RRType_PTR), METH_NOARGS | METH_STATIC, "Creates a PTR RRType" },
-    { "MX", reinterpret_cast<PyCFunction>(RRType_MX), METH_NOARGS | METH_STATIC, "Creates an MX RRType" },
-    { "DNSKEY", reinterpret_cast<PyCFunction>(RRType_DNSKEY), METH_NOARGS | METH_STATIC, "Creates a DNSKEY RRType" },
-    { "TXT", reinterpret_cast<PyCFunction>(RRType_TXT), METH_NOARGS | METH_STATIC, "Creates a TXT RRType" },
-    { "RRSIG", reinterpret_cast<PyCFunction>(RRType_RRSIG), METH_NOARGS | METH_STATIC, "Creates a RRSIG RRType" },
-    { "NSEC", reinterpret_cast<PyCFunction>(RRType_NSEC), METH_NOARGS | METH_STATIC, "Creates a NSEC RRType" },
-    { "AAAA", reinterpret_cast<PyCFunction>(RRType_AAAA), METH_NOARGS | METH_STATIC, "Creates an AAAA RRType" },
-    { "DS", reinterpret_cast<PyCFunction>(RRType_DS), METH_NOARGS | METH_STATIC, "Creates a DS RRType" },
-    { "OPT", reinterpret_cast<PyCFunction>(RRType_OPT), METH_NOARGS | METH_STATIC, "Creates an OPT RRType" },
-    { "A", reinterpret_cast<PyCFunction>(RRType_A), METH_NOARGS | METH_STATIC, "Creates an A RRType" },
-    { "NS", reinterpret_cast<PyCFunction>(RRType_NS), METH_NOARGS | METH_STATIC, "Creates an NS RRType" },
-    { "CNAME", reinterpret_cast<PyCFunction>(RRType_CNAME), METH_NOARGS | METH_STATIC, "Creates a CNAME RRType" },
-    { "SOA", reinterpret_cast<PyCFunction>(RRType_SOA), METH_NOARGS | METH_STATIC, "Creates a SOA RRType" },
-    { "NSEC3", reinterpret_cast<PyCFunction>(RRType_NSEC3), METH_NOARGS | METH_STATIC, "Creates an NSEC3 RRType" },
-    { "IXFR", reinterpret_cast<PyCFunction>(RRType_IXFR), METH_NOARGS | METH_STATIC, "Creates an IXFR RRType" },
-    { "AXFR", reinterpret_cast<PyCFunction>(RRType_AXFR), METH_NOARGS | METH_STATIC, "Creates an AXFR RRType" },
-    { "ANY", reinterpret_cast<PyCFunction>(RRType_ANY), METH_NOARGS | METH_STATIC, "Creates an ANY RRType" },
     { NULL, NULL, 0, NULL }
 };
 
@@ -263,112 +225,6 @@ RRType_richcmp(s_RRType* self, s_RRType* other, int op) {
         Py_RETURN_FALSE;
 }
 
-//
-// Common function for RRType_A/NS/etc.
-//
-PyObject* RRType_createStatic(RRType stc) {
-    s_RRType* ret = PyObject_New(s_RRType, &rrtype_type);
-    if (ret != NULL) {
-        ret->cppobj = new RRType(stc);
-    }
-    return (ret);
-}
-
-PyObject*
-RRType_NSEC3PARAM(s_RRType*) {
-    return (RRType_createStatic(RRType::NSEC3PARAM()));
-}
-
-PyObject*
-RRType_DNAME(s_RRType*) {
-    return (RRType_createStatic(RRType::DNAME()));
-}
-
-PyObject*
-RRType_PTR(s_RRType*) {
-    return (RRType_createStatic(RRType::PTR()));
-}
-
-PyObject*
-RRType_MX(s_RRType*) {
-    return (RRType_createStatic(RRType::MX()));
-}
-
-PyObject*
-RRType_DNSKEY(s_RRType*) {
-    return (RRType_createStatic(RRType::DNSKEY()));
-}
-
-PyObject*
-RRType_TXT(s_RRType*) {
-    return (RRType_createStatic(RRType::TXT()));
-}
-
-PyObject*
-RRType_RRSIG(s_RRType*) {
-    return (RRType_createStatic(RRType::RRSIG()));
-}
-
-PyObject*
-RRType_NSEC(s_RRType*) {
-    return (RRType_createStatic(RRType::NSEC()));
-}
-
-PyObject*
-RRType_AAAA(s_RRType*) {
-    return (RRType_createStatic(RRType::AAAA()));
-}
-
-PyObject*
-RRType_DS(s_RRType*) {
-    return (RRType_createStatic(RRType::DS()));
-}
-
-PyObject*
-RRType_OPT(s_RRType*) {
-    return (RRType_createStatic(RRType::OPT()));
-}
-
-PyObject*
-RRType_A(s_RRType*) {
-    return (RRType_createStatic(RRType::A()));
-}
-
-PyObject*
-RRType_NS(s_RRType*) {
-    return (RRType_createStatic(RRType::NS()));
-}
-
-PyObject*
-RRType_CNAME(s_RRType*) {
-    return (RRType_createStatic(RRType::CNAME()));
-}
-
-PyObject*
-RRType_SOA(s_RRType*) {
-    return (RRType_createStatic(RRType::SOA()));
-}
-
-PyObject*
-RRType_NSEC3(s_RRType*) {
-    return (RRType_createStatic(RRType::NSEC3()));
-}
-
-PyObject*
-RRType_IXFR(s_RRType*) {
-    return (RRType_createStatic(RRType::IXFR()));
-}
-
-PyObject*
-RRType_AXFR(s_RRType*) {
-    return (RRType_createStatic(RRType::AXFR()));
-}
-
-PyObject*
-RRType_ANY(s_RRType*) {
-    return (RRType_createStatic(RRType::ANY()));
-}
-
 Py_hash_t
 RRType_hash(PyObject* pyself) {
     const s_RRType* const self = static_cast<s_RRType*>(pyself);

+ 3 - 3
src/lib/dns/python/tests/edns_python_test.py

@@ -108,8 +108,8 @@ class EDNSTest(unittest.TestCase):
 
     def test_towire_renderer(self):
         renderer = MessageRenderer()
-        extrcode_noerror = Rcode.NOERROR().get_extended_code()
-        extrcode_badvers = Rcode.BADVERS().get_extended_code()
+        extrcode_noerror = Rcode.NOERROR.get_extended_code()
+        extrcode_badvers = Rcode.BADVERS.get_extended_code()
 
         self.assertEqual(1, self.edns_base.to_wire(renderer, extrcode_noerror))
         wiredata = read_wire_data("edns_toWire1.wire")
@@ -148,7 +148,7 @@ class EDNSTest(unittest.TestCase):
         self.assertEqual(0, renderer.get_length())
 
     def test_towire_buffer(self):
-        extrcode_noerror = Rcode.NOERROR().get_extended_code()
+        extrcode_noerror = Rcode.NOERROR.get_extended_code()
 
         obuffer = bytes()
         obuffer = self.edns_base.to_wire(obuffer, extrcode_noerror)

+ 17 - 17
src/lib/dns/python/tests/message_python_test.py

@@ -59,8 +59,8 @@ LONG_TXT4 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012
 def create_message():
     message_render = Message(Message.RENDER)
     message_render.set_qid(0x1035)
-    message_render.set_opcode(Opcode.QUERY())
-    message_render.set_rcode(Rcode.NOERROR())
+    message_render.set_opcode(Opcode.QUERY)
+    message_render.set_rcode(Rcode.NOERROR)
     message_render.set_header_flag(Message.HEADERFLAG_QR)
     message_render.set_header_flag(Message.HEADERFLAG_RD)
     message_render.set_header_flag(Message.HEADERFLAG_AA)
@@ -161,7 +161,7 @@ class MessageTest(unittest.TestCase):
     def test_set_rcode(self):
         self.assertRaises(TypeError, self.r.set_rcode, "wrong")
 
-        rcode = Rcode.BADVERS()
+        rcode = Rcode.BADVERS
         self.r.set_rcode(rcode)
         self.assertEqual(rcode, self.r.get_rcode())
 
@@ -173,7 +173,7 @@ class MessageTest(unittest.TestCase):
     def test_set_opcode(self):
         self.assertRaises(TypeError, self.r.set_opcode, "wrong")
 
-        opcode = Opcode.IQUERY()
+        opcode = Opcode.IQUERY
         self.r.set_opcode(opcode)
         self.assertEqual(opcode, self.r.get_opcode())
 
@@ -304,8 +304,8 @@ class MessageTest(unittest.TestCase):
         self.assertRaises(TypeError, self.r.clear, 3)
 
     def test_clear_question_section(self):
-        self.r.add_question(Question(Name("www.example.com"), RRClass.IN(),
-                                     RRType.A()))
+        self.r.add_question(Question(Name("www.example.com"), RRClass.IN,
+                                     RRType.A))
         self.assertEqual(1, self.r.get_rr_count(Message.SECTION_QUESTION))
         self.r.clear_section(Message.SECTION_QUESTION)
         self.assertEqual(0, self.r.get_rr_count(Message.SECTION_QUESTION))
@@ -336,19 +336,19 @@ class MessageTest(unittest.TestCase):
                          renderer.get_data())
 
     def test_to_wire_without_opcode(self):
-        self.r.set_rcode(Rcode.NOERROR())
+        self.r.set_rcode(Rcode.NOERROR)
         self.assertRaises(InvalidMessageOperation, self.r.to_wire,
                           MessageRenderer())
 
     def test_to_wire_without_rcode(self):
-        self.r.set_opcode(Opcode.QUERY())
+        self.r.set_opcode(Opcode.QUERY)
         self.assertRaises(InvalidMessageOperation, self.r.to_wire,
                           MessageRenderer())
 
     def __common_tsigmessage_setup(self, flags=[Message.HEADERFLAG_RD],
                                    rrtype=RRType("A"), answer_data=None):
-        self.r.set_opcode(Opcode.QUERY())
-        self.r.set_rcode(Rcode.NOERROR())
+        self.r.set_opcode(Opcode.QUERY)
+        self.r.set_rcode(Rcode.NOERROR)
         for flag in flags:
             self.r.set_header_flag(flag)
         if answer_data is not None:
@@ -407,8 +407,8 @@ class MessageTest(unittest.TestCase):
         self.__common_tsig_checks("message_toWire4.wire")
 
     def test_to_wire_tsig_truncation3(self):
-        self.r.set_opcode(Opcode.QUERY())
-        self.r.set_rcode(Rcode.NOERROR())
+        self.r.set_opcode(Opcode.QUERY)
+        self.r.set_rcode(Rcode.NOERROR)
         for i in range(1, 68):
             self.r.add_question(Question(Name("www.example.com"),
                                          RRClass("IN"), RRType(i)))
@@ -469,11 +469,11 @@ test.example.com. 3600 IN A 192.0.2.2
         self.assertEqual(msg_str, str(message_render))
 
     def test_to_text_without_opcode(self):
-        self.r.set_rcode(Rcode.NOERROR())
+        self.r.set_rcode(Rcode.NOERROR)
         self.assertRaises(InvalidMessageOperation, self.r.to_text)
 
     def test_to_text_without_rcode(self):
-        self.r.set_opcode(Opcode.QUERY())
+        self.r.set_opcode(Opcode.QUERY)
         self.assertRaises(InvalidMessageOperation, self.r.to_text)
 
     def test_from_wire(self):
@@ -488,8 +488,8 @@ test.example.com. 3600 IN A 192.0.2.2
         message_parse = Message(0)
         factoryFromFile(message_parse, "message_fromWire1")
         self.assertEqual(0x1035, message_parse.get_qid())
-        self.assertEqual(Opcode.QUERY(), message_parse.get_opcode())
-        self.assertEqual(Rcode.NOERROR(), message_parse.get_rcode())
+        self.assertEqual(Opcode.QUERY, message_parse.get_opcode())
+        self.assertEqual(Rcode.NOERROR, message_parse.get_rcode())
         self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_QR))
         self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_RD))
         self.assertTrue(message_parse.get_header_flag(Message.HEADERFLAG_AA))
@@ -568,7 +568,7 @@ test.example.com. 3600 IN A 192.0.2.2
         # Extended Rcode = BADVERS
         message_parse = Message(Message.PARSE)
         factoryFromFile(message_parse, "message_fromWire10.wire")
-        self.assertEqual(Rcode.BADVERS(), message_parse.get_rcode())
+        self.assertEqual(Rcode.BADVERS, message_parse.get_rcode())
 
         # Maximum extended Rcode
         message_parse.clear(Message.PARSE)

+ 4 - 4
src/lib/dns/python/tests/messagerenderer_python_test.py

@@ -31,8 +31,8 @@ class MessageRendererTest(unittest.TestCase):
 
         message = Message(Message.RENDER)
         message.set_qid(123)
-        message.set_opcode(Opcode.QUERY())
-        message.set_rcode(Rcode.NOERROR())
+        message.set_opcode(Opcode.QUERY)
+        message.set_rcode(Rcode.NOERROR)
         message.add_question(Question(name, c, t))
 
         self.message1 = message
@@ -40,8 +40,8 @@ class MessageRendererTest(unittest.TestCase):
         message.set_qid(123)
         message.set_header_flag(Message.HEADERFLAG_AA, True)
         message.set_header_flag(Message.HEADERFLAG_QR, True)
-        message.set_opcode(Opcode.QUERY())
-        message.set_rcode(Rcode.NOERROR())
+        message.set_opcode(Opcode.QUERY)
+        message.set_rcode(Rcode.NOERROR)
         message.add_question(Question(name, c, t))
         rrset = RRset(name, c, t, ttl)
         rrset.add_rdata(Rdata(t, c, "192.0.2.98"))

+ 23 - 23
src/lib/dns/python/tests/nsec3hash_python_test.py

@@ -24,9 +24,9 @@ class NSEC3HashTest(unittest.TestCase):
 
     def setUp(self):
         self.nsec3_common = "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG"
-        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM(), RRClass.IN(),
+        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM, RRClass.IN,
                                          "1 0 12 aabbccdd"))
-        self.test_hash_nsec3 = NSEC3Hash(Rdata(RRType.NSEC3(), RRClass.IN(),
+        self.test_hash_nsec3 = NSEC3Hash(Rdata(RRType.NSEC3, RRClass.IN,
                                                "1 0 12 aabbccdd " +
                                                self.nsec3_common))
     def test_bad_construct(self):
@@ -37,20 +37,20 @@ class NSEC3HashTest(unittest.TestCase):
         self.assertRaises(TypeError, NSEC3Hash, "1 0 12 aabbccdd")
 
         # additional parameter
-        self.assertRaises(TypeError, NSEC3Hash, Rdata(RRType.NSEC3PARAM(),
-                                                      RRClass.IN(),
+        self.assertRaises(TypeError, NSEC3Hash, Rdata(RRType.NSEC3PARAM,
+                                                      RRClass.IN,
                                                       "1 0 12 aabbccdd"), 1)
 
         # Invaid type of RDATA
-        self.assertRaises(TypeError, NSEC3Hash, Rdata(RRType.A(), RRClass.IN(),
+        self.assertRaises(TypeError, NSEC3Hash, Rdata(RRType.A, RRClass.IN,
                                                       "192.0.2.1"))
 
     def test_unknown_algorithm(self):
         self.assertRaises(UnknownNSEC3HashAlgorithm, NSEC3Hash,
-                          Rdata(RRType.NSEC3PARAM(), RRClass.IN(),
+                          Rdata(RRType.NSEC3PARAM, RRClass.IN,
                                 "2 0 12 aabbccdd"))
         self.assertRaises(UnknownNSEC3HashAlgorithm, NSEC3Hash,
-                          Rdata(RRType.NSEC3(), RRClass.IN(),
+                          Rdata(RRType.NSEC3, RRClass.IN,
                                 "2 0 12 aabbccdd " + self.nsec3_common))
 
     def calculate_check(self, hash):
@@ -71,15 +71,15 @@ class NSEC3HashTest(unittest.TestCase):
 
         # Using unusually large iterations, something larger than the 8-bit
         #range.  (expected hash value generated by BIND 9's dnssec-signzone)
-        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM(),
-                                         RRClass.IN(), "1 0 256 AABBCCDD"))
+        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM,
+                                         RRClass.IN, "1 0 256 AABBCCDD"))
         self.assertEqual("COG6A52MJ96MNMV3QUCAGGCO0RHCC2Q3",
                          self.test_hash.calculate(Name("example.org")))
 
         # Some boundary cases: 0-iteration and empty salt.  Borrowed from the
         # .com zone data.
-        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM(),
-                                         RRClass.IN(),"1 0 0 -"))
+        self.test_hash = NSEC3Hash(Rdata(RRType.NSEC3PARAM,
+                                         RRClass.IN,"1 0 0 -"))
         self.assertEqual("CK0POJMG874LJREF7EFN8430QVIT8BSM",
                          self.test_hash.calculate(Name("com")))
 
@@ -90,39 +90,39 @@ class NSEC3HashTest(unittest.TestCase):
 
     def check_match(self, hash, rrtype, postfix):
         # If all parameters match, it's considered to be matched.
-        self.assertTrue(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertTrue(hash.match(Rdata(rrtype, RRClass.IN,
                                          "1 0 12 aabbccdd" + postfix)))
         # Algorithm doesn't match
-        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN,
                                           "2 0 12 aabbccdd" + postfix)))
         # Iterations doesn't match
-        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN,
                                           "1 0 1 aabbccdd" + postfix)))
         # Salt doesn't match
-        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN,
                                           "1 0 12 aabbccde" + postfix)))
         # Salt doesn't match: the other has an empty salt
-        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertFalse(hash.match(Rdata(rrtype, RRClass.IN,
                                           "1 0 12 -" + postfix)))
         # Flag doesn't matter
-        self.assertTrue(hash.match(Rdata(rrtype, RRClass.IN(),
+        self.assertTrue(hash.match(Rdata(rrtype, RRClass.IN,
                                          "1 1 12 aabbccdd" + postfix)))
 
     def test_match(self):
-        self.check_match(self.test_hash, RRType.NSEC3(),
+        self.check_match(self.test_hash, RRType.NSEC3,
                          " " + self.nsec3_common)
-        self.check_match(self.test_hash_nsec3, RRType.NSEC3(),
+        self.check_match(self.test_hash_nsec3, RRType.NSEC3,
                          " " + self.nsec3_common)
-        self.check_match(self.test_hash, RRType.NSEC3PARAM(), "")
-        self.check_match(self.test_hash_nsec3, RRType.NSEC3PARAM(), "")
+        self.check_match(self.test_hash, RRType.NSEC3PARAM, "")
+        self.check_match(self.test_hash_nsec3, RRType.NSEC3PARAM, "")
 
         # bad parameter checks
         self.assertRaises(TypeError, self.test_hash.match, 1)
         self.assertRaises(TypeError, self.test_hash.match,
-                          Rdata(RRType.NSEC3(), RRClass.IN(),
+                          Rdata(RRType.NSEC3, RRClass.IN,
                                 "1 0 12 aabbccdd " + self.nsec3_common), 1)
         self.assertRaises(TypeError, self.test_hash.match,
-                          Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
+                          Rdata(RRType.A, RRClass.IN, "192.0.2.1"))
 
 if __name__ == '__main__':
     unittest.main()

+ 41 - 41
src/lib/dns/python/tests/opcode_python_test.py

@@ -34,53 +34,53 @@ class OpcodeTest(unittest.TestCase):
         self.assertEqual(Opcode.UPDATE_CODE, Opcode(5).get_code())
         self.assertEqual(Opcode.RESERVED15_CODE, Opcode(15).get_code())
 
-        self.assertEqual(Opcode.QUERY_CODE, Opcode.QUERY().get_code())
-        self.assertEqual(Opcode.IQUERY_CODE, Opcode.IQUERY().get_code())
-        self.assertEqual(Opcode.NOTIFY_CODE, Opcode.NOTIFY().get_code())
-        self.assertEqual(Opcode.UPDATE_CODE, Opcode.UPDATE().get_code())
-        self.assertEqual(Opcode.RESERVED15_CODE, Opcode.RESERVED15().get_code())
+        self.assertEqual(Opcode.QUERY_CODE, Opcode.QUERY.get_code())
+        self.assertEqual(Opcode.IQUERY_CODE, Opcode.IQUERY.get_code())
+        self.assertEqual(Opcode.NOTIFY_CODE, Opcode.NOTIFY.get_code())
+        self.assertEqual(Opcode.UPDATE_CODE, Opcode.UPDATE.get_code())
+        self.assertEqual(Opcode.RESERVED15_CODE, Opcode.RESERVED15.get_code())
 
     def test_get_code(self):
-        self.assertEqual(0, Opcode.QUERY().get_code())
-        self.assertEqual(1, Opcode.IQUERY().get_code())
-        self.assertEqual(2, Opcode.STATUS().get_code())
-        self.assertEqual(3, Opcode.RESERVED3().get_code())
-        self.assertEqual(4, Opcode.NOTIFY().get_code())
-        self.assertEqual(5, Opcode.UPDATE().get_code())
-        self.assertEqual(6, Opcode.RESERVED6().get_code())
-        self.assertEqual(7, Opcode.RESERVED7().get_code())
-        self.assertEqual(8, Opcode.RESERVED8().get_code())
-        self.assertEqual(9, Opcode.RESERVED9().get_code())
-        self.assertEqual(10, Opcode.RESERVED10().get_code())
-        self.assertEqual(11, Opcode.RESERVED11().get_code())
-        self.assertEqual(12, Opcode.RESERVED12().get_code())
-        self.assertEqual(13, Opcode.RESERVED13().get_code())
-        self.assertEqual(14, Opcode.RESERVED14().get_code())
-        self.assertEqual(15, Opcode.RESERVED15().get_code())
+        self.assertEqual(0, Opcode.QUERY.get_code())
+        self.assertEqual(1, Opcode.IQUERY.get_code())
+        self.assertEqual(2, Opcode.STATUS.get_code())
+        self.assertEqual(3, Opcode.RESERVED3.get_code())
+        self.assertEqual(4, Opcode.NOTIFY.get_code())
+        self.assertEqual(5, Opcode.UPDATE.get_code())
+        self.assertEqual(6, Opcode.RESERVED6.get_code())
+        self.assertEqual(7, Opcode.RESERVED7.get_code())
+        self.assertEqual(8, Opcode.RESERVED8.get_code())
+        self.assertEqual(9, Opcode.RESERVED9.get_code())
+        self.assertEqual(10, Opcode.RESERVED10.get_code())
+        self.assertEqual(11, Opcode.RESERVED11.get_code())
+        self.assertEqual(12, Opcode.RESERVED12.get_code())
+        self.assertEqual(13, Opcode.RESERVED13.get_code())
+        self.assertEqual(14, Opcode.RESERVED14.get_code())
+        self.assertEqual(15, Opcode.RESERVED15.get_code())
 
     def test_to_text(self):
-        self.assertEqual("QUERY", Opcode.QUERY().to_text())
-        self.assertEqual("QUERY", str(Opcode.QUERY()))
-        self.assertEqual("IQUERY", Opcode.IQUERY().to_text())
-        self.assertEqual("STATUS", Opcode.STATUS().to_text())
-        self.assertEqual("RESERVED3", Opcode.RESERVED3().to_text())
-        self.assertEqual("NOTIFY", Opcode.NOTIFY().to_text())
-        self.assertEqual("UPDATE", Opcode.UPDATE().to_text())
-        self.assertEqual("RESERVED6", Opcode.RESERVED6().to_text())
-        self.assertEqual("RESERVED7", Opcode.RESERVED7().to_text())
-        self.assertEqual("RESERVED8", Opcode.RESERVED8().to_text())
-        self.assertEqual("RESERVED9", Opcode.RESERVED9().to_text())
-        self.assertEqual("RESERVED10", Opcode.RESERVED10().to_text())
-        self.assertEqual("RESERVED11", Opcode.RESERVED11().to_text())
-        self.assertEqual("RESERVED12", Opcode.RESERVED12().to_text())
-        self.assertEqual("RESERVED13", Opcode.RESERVED13().to_text())
-        self.assertEqual("RESERVED14", Opcode.RESERVED14().to_text())
-        self.assertEqual("RESERVED15", Opcode.RESERVED15().to_text())
+        self.assertEqual("QUERY", Opcode.QUERY.to_text())
+        self.assertEqual("QUERY", str(Opcode.QUERY))
+        self.assertEqual("IQUERY", Opcode.IQUERY.to_text())
+        self.assertEqual("STATUS", Opcode.STATUS.to_text())
+        self.assertEqual("RESERVED3", Opcode.RESERVED3.to_text())
+        self.assertEqual("NOTIFY", Opcode.NOTIFY.to_text())
+        self.assertEqual("UPDATE", Opcode.UPDATE.to_text())
+        self.assertEqual("RESERVED6", Opcode.RESERVED6.to_text())
+        self.assertEqual("RESERVED7", Opcode.RESERVED7.to_text())
+        self.assertEqual("RESERVED8", Opcode.RESERVED8.to_text())
+        self.assertEqual("RESERVED9", Opcode.RESERVED9.to_text())
+        self.assertEqual("RESERVED10", Opcode.RESERVED10.to_text())
+        self.assertEqual("RESERVED11", Opcode.RESERVED11.to_text())
+        self.assertEqual("RESERVED12", Opcode.RESERVED12.to_text())
+        self.assertEqual("RESERVED13", Opcode.RESERVED13.to_text())
+        self.assertEqual("RESERVED14", Opcode.RESERVED14.to_text())
+        self.assertEqual("RESERVED15", Opcode.RESERVED15.to_text())
 
     def test_richcmp(self):
-        o1 = Opcode.QUERY()
-        o2 = Opcode.NOTIFY()
-        o3 = Opcode.NOTIFY()
+        o1 = Opcode.QUERY
+        o2 = Opcode.NOTIFY
+        o3 = Opcode.NOTIFY
         self.assertTrue(o2 == o3)
         self.assertFalse(o2 != o3)
         self.assertTrue(o1 != o2)

+ 30 - 30
src/lib/dns/python/tests/rcode_python_test.py

@@ -54,36 +54,36 @@ class RcodeTest(unittest.TestCase):
         self.assertEqual(Rcode.RESERVED15_CODE, Rcode(15).get_code())
         self.assertEqual(Rcode.BADVERS_CODE, Rcode(16).get_code())
 
-        self.assertEqual(Rcode.NOERROR_CODE, Rcode.NOERROR().get_code())
-        self.assertEqual(Rcode.FORMERR_CODE, Rcode.FORMERR().get_code())
-        self.assertEqual(Rcode.NOTIMP_CODE, Rcode.NOTIMP().get_code())
-        self.assertEqual(Rcode.REFUSED_CODE, Rcode.REFUSED().get_code())
-        self.assertEqual(Rcode.RESERVED15_CODE, Rcode.RESERVED15().get_code())
-        self.assertEqual(Rcode.BADVERS_CODE, Rcode.BADVERS().get_code())
+        self.assertEqual(Rcode.NOERROR_CODE, Rcode.NOERROR.get_code())
+        self.assertEqual(Rcode.FORMERR_CODE, Rcode.FORMERR.get_code())
+        self.assertEqual(Rcode.NOTIMP_CODE, Rcode.NOTIMP.get_code())
+        self.assertEqual(Rcode.REFUSED_CODE, Rcode.REFUSED.get_code())
+        self.assertEqual(Rcode.RESERVED15_CODE, Rcode.RESERVED15.get_code())
+        self.assertEqual(Rcode.BADVERS_CODE, Rcode.BADVERS.get_code())
 
     def test_get_code(self):
-        self.assertEqual(0, Rcode.NOERROR().get_code())
-        self.assertEqual(1, Rcode.FORMERR().get_code())
-        self.assertEqual(2, Rcode.SERVFAIL().get_code())
-        self.assertEqual(3, Rcode.NXDOMAIN().get_code())
-        self.assertEqual(4, Rcode.NOTIMP().get_code())
-        self.assertEqual(5, Rcode.REFUSED().get_code())
-        self.assertEqual(6, Rcode.YXDOMAIN().get_code())
-        self.assertEqual(7, Rcode.YXRRSET().get_code())
-        self.assertEqual(8, Rcode.NXRRSET().get_code())
-        self.assertEqual(9, Rcode.NOTAUTH().get_code())
-        self.assertEqual(10, Rcode.NOTZONE().get_code())
-        self.assertEqual(11, Rcode.RESERVED11().get_code())
-        self.assertEqual(12, Rcode.RESERVED12().get_code())
-        self.assertEqual(13, Rcode.RESERVED13().get_code())
-        self.assertEqual(14, Rcode.RESERVED14().get_code())
-        self.assertEqual(15, Rcode.RESERVED15().get_code())
-        self.assertEqual(16, Rcode.BADVERS().get_code())
+        self.assertEqual(0, Rcode.NOERROR.get_code())
+        self.assertEqual(1, Rcode.FORMERR.get_code())
+        self.assertEqual(2, Rcode.SERVFAIL.get_code())
+        self.assertEqual(3, Rcode.NXDOMAIN.get_code())
+        self.assertEqual(4, Rcode.NOTIMP.get_code())
+        self.assertEqual(5, Rcode.REFUSED.get_code())
+        self.assertEqual(6, Rcode.YXDOMAIN.get_code())
+        self.assertEqual(7, Rcode.YXRRSET.get_code())
+        self.assertEqual(8, Rcode.NXRRSET.get_code())
+        self.assertEqual(9, Rcode.NOTAUTH.get_code())
+        self.assertEqual(10, Rcode.NOTZONE.get_code())
+        self.assertEqual(11, Rcode.RESERVED11.get_code())
+        self.assertEqual(12, Rcode.RESERVED12.get_code())
+        self.assertEqual(13, Rcode.RESERVED13.get_code())
+        self.assertEqual(14, Rcode.RESERVED14.get_code())
+        self.assertEqual(15, Rcode.RESERVED15.get_code())
+        self.assertEqual(16, Rcode.BADVERS.get_code())
 
     def test_get_extended_code(self):
-        self.assertEqual(0, Rcode.NOERROR().get_extended_code())
-        self.assertEqual(0, Rcode.YXRRSET().get_extended_code())
-        self.assertEqual(1, Rcode.BADVERS().get_extended_code())
+        self.assertEqual(0, Rcode.NOERROR.get_extended_code())
+        self.assertEqual(0, Rcode.YXRRSET.get_extended_code())
+        self.assertEqual(1, Rcode.BADVERS.get_extended_code())
         self.assertEqual(0xab, Rcode(0xabf).get_extended_code())
         self.assertEqual(0xff, Rcode(0xfff).get_extended_code())
 
@@ -107,13 +107,13 @@ class RcodeTest(unittest.TestCase):
         self.assertEqual("RESERVED15", Rcode(15).to_text())
         self.assertEqual("BADVERS", Rcode(16).to_text())
         
-        self.assertEqual("17", Rcode(Rcode.BADVERS().get_code() + 1).to_text())
+        self.assertEqual("17", Rcode(Rcode.BADVERS.get_code() + 1).to_text())
         self.assertEqual("4095", Rcode(0xfff).to_text())
 
     def test_richcmp(self):
-        r1 = Rcode.NOERROR()
-        r2 = Rcode.FORMERR()
-        r3 = Rcode.FORMERR()
+        r1 = Rcode.NOERROR
+        r2 = Rcode.FORMERR
+        r3 = Rcode.FORMERR
         self.assertTrue(r2 == r3)
         self.assertTrue(r1 != r2)
         self.assertFalse(r1 == r2)

+ 10 - 10
src/lib/dns/python/tests/rrclass_python_test.py

@@ -23,8 +23,8 @@ from pydnspp import *
 
 class RRClassTest(unittest.TestCase):
     def setUp(self):
-        self.c1 = RRClass.IN()
-        self.c2 = RRClass.CH()
+        self.c1 = RRClass.IN
+        self.c2 = RRClass.CH
 
     def test_init(self):
         self.assertRaises(InvalidRRClass, RRClass, "wrong")
@@ -81,17 +81,17 @@ class RRClassTest(unittest.TestCase):
     def test_hash(self):
         # Exploiting the knowledge that the hash value is the numeric class
         # value, we can predict the comparison result.
-        self.assertEqual(hash(RRClass.IN()), hash(RRClass("IN")))
+        self.assertEqual(hash(RRClass.IN), hash(RRClass("IN")))
         self.assertEqual(hash(RRClass("in")), hash(RRClass("IN")))
-        self.assertNotEqual(hash(RRClass.IN()), hash(RRClass.CH()))
-        self.assertNotEqual(hash(RRClass.IN()), hash(RRClass("CLASS65535")))
+        self.assertNotEqual(hash(RRClass.IN), hash(RRClass.CH))
+        self.assertNotEqual(hash(RRClass.IN), hash(RRClass("CLASS65535")))
 
     def test_statics(self):
-        self.assertEqual(RRClass.IN(), RRClass("IN"))
-        self.assertEqual(RRClass.CH(), RRClass("CH"))
-        self.assertEqual(RRClass.HS(), RRClass("HS"))
-        self.assertEqual(254, RRClass.NONE().get_code())
-        self.assertEqual(255, RRClass.ANY().get_code())
+        self.assertEqual(RRClass.IN, RRClass("IN"))
+        self.assertEqual(RRClass.CH, RRClass("CH"))
+        self.assertEqual(RRClass.HS, RRClass("HS"))
+        self.assertEqual(254, RRClass.NONE.get_code())
+        self.assertEqual(255, RRClass.ANY.get_code())
 
 if __name__ == '__main__':
     unittest.main()

+ 23 - 23
src/lib/dns/python/tests/rrset_collection_python_test.py

@@ -34,64 +34,64 @@ class RRsetCollectionTest(unittest.TestCase):
         self.assertRaises(TypeError, RRsetCollection, 1)
         self.assertRaises(TypeError, RRsetCollection, # extra arg
                           b'example. 0 A 192.0.2.1',
-                          Name('example'), RRClass.IN(), 1)
+                          Name('example'), RRClass.IN, 1)
         self.assertRaises(TypeError, RRsetCollection, # incorrect order
-                          b'example. 0 A 192.0.2.1', RRClass.IN(),
+                          b'example. 0 A 192.0.2.1', RRClass.IN,
                           Name('example'))
 
         # constructor will result in C++ exception.
         self.assertRaises(IscException, RRsetCollection,
                           TESTDATA_DIR + '/no_such_file', Name('example.org'),
-                          RRClass.IN())
+                          RRClass.IN)
 
     def check_find_result(self, rrsets):
         # Commonly used check pattern
-        found = rrsets.find(Name('www.example.org'), RRClass.IN(), RRType.A())
+        found = rrsets.find(Name('www.example.org'), RRClass.IN, RRType.A)
         self.assertNotEqual(None, found)
         self.assertEqual(Name('www.example.org'), found.get_name())
-        self.assertEqual(RRClass.IN(), found.get_class())
-        self.assertEqual(RRType.A(), found.get_type())
+        self.assertEqual(RRClass.IN, found.get_class())
+        self.assertEqual(RRType.A, found.get_type())
         self.assertEqual('192.0.2.1', found.get_rdata()[0].to_text())
 
     def test_find(self):
         # Checking the underlying find() is called as intended, both for
         # success and failure cases, and with two different constructors.
         rrsets = RRsetCollection(TESTDATA_DIR + '/example.org',
-                                 Name('example.org'), RRClass.IN())
+                                 Name('example.org'), RRClass.IN)
         self.check_find_result(rrsets)
-        self.assertEqual(None, rrsets.find(Name('example.org'), RRClass.IN(),
-                                           RRType.A()))
+        self.assertEqual(None, rrsets.find(Name('example.org'), RRClass.IN,
+                                           RRType.A))
 
         rrsets = RRsetCollection(b'www.example.org. 3600 IN A 192.0.2.1',
-                                 Name('example.org'), RRClass.IN())
+                                 Name('example.org'), RRClass.IN)
         self.check_find_result(rrsets)
-        self.assertEqual(None, rrsets.find(Name('example.org'), RRClass.IN(),
-                                           RRType.A()))
+        self.assertEqual(None, rrsets.find(Name('example.org'), RRClass.IN,
+                                           RRType.A))
 
     def test_find_badargs(self):
         rrsets = RRsetCollection()
 
         # Check bad arguments: bad types
-        self.assertRaises(TypeError, rrsets.find, 1, RRClass.IN(), RRType.A())
+        self.assertRaises(TypeError, rrsets.find, 1, RRClass.IN, RRType.A)
         self.assertRaises(TypeError, rrsets.find, Name('example'), 1,
-                          RRType.A())
+                          RRType.A)
         self.assertRaises(TypeError, rrsets.find, Name('example'), 1,
-                          RRType.A())
+                          RRType.A)
         self.assertRaises(TypeError, rrsets.find, Name('example'),
-                          RRClass.IN(), 1)
-        self.assertRaises(TypeError, rrsets.find, Name('example'), RRType.A(),
-                          RRClass.IN())
+                          RRClass.IN, 1)
+        self.assertRaises(TypeError, rrsets.find, Name('example'), RRType.A,
+                          RRClass.IN)
 
         # Check bad arguments: too many/few arguments
         self.assertRaises(TypeError, rrsets.find, Name('example'),
-                          RRClass.IN(), RRType.A(), 0)
+                          RRClass.IN, RRType.A, 0)
         self.assertRaises(TypeError, rrsets.find, Name('example'),
-                          RRClass.IN())
+                          RRClass.IN)
 
     def test_add_remove_rrset(self):
         name = Name('www.example.org')
-        rrclass = RRClass.IN()
-        rrtype = RRType.A()
+        rrclass = RRClass.IN
+        rrtype = RRType.A
 
         # Create a collection with no RRsets
         rrsets = RRsetCollection()
@@ -134,7 +134,7 @@ class RRsetCollectionTest(unittest.TestCase):
                 pass
         rrsets = EmptyRRsetCollection()
         self.assertRaises(TypeError, rrsets.find, Name('www.example.org'),
-                          RRClass.IN(), RRType.A())
+                          RRClass.IN, RRType.A)
 
 if __name__ == '__main__':
     unittest.main()

+ 22 - 22
src/lib/dns/python/tests/rrtype_python_test.py

@@ -119,35 +119,35 @@ class TestModuleSpec(unittest.TestCase):
     def test_hash(self):
         # Exploiting the knowledge that the hash value is the numeric class
         # value, we can predict the comparison result.
-        self.assertEqual(hash(RRType.AAAA()), hash(RRType("AAAA")))
+        self.assertEqual(hash(RRType.AAAA), hash(RRType("AAAA")))
         self.assertEqual(hash(RRType("aaaa")), hash(RRType("AAAA")))
         self.assertEqual(hash(RRType(28)), hash(RRType("AAAA")))
-        self.assertNotEqual(hash(RRType.A()), hash(RRType.NS()))
-        self.assertNotEqual(hash(RRType.AAAA()), hash(RRType("Type65535")))
+        self.assertNotEqual(hash(RRType.A), hash(RRType.NS))
+        self.assertNotEqual(hash(RRType.AAAA), hash(RRType("Type65535")))
 
     def test_statics(self):
-        self.assertEqual(RRType("NSEC3PARAM"), RRType.NSEC3PARAM())
-        self.assertEqual(RRType("DNAME"), RRType.DNAME())
-        self.assertEqual(RRType("PTR"), RRType.PTR())
-        self.assertEqual(RRType("MX"), RRType.MX())
-        self.assertEqual(RRType("DNSKEY"), RRType.DNSKEY())
-        self.assertEqual(RRType("TXT"), RRType.TXT())
-        self.assertEqual(RRType("RRSIG"), RRType.RRSIG())
-        self.assertEqual(RRType("NSEC"), RRType.NSEC())
-        self.assertEqual(RRType("AAAA"), RRType.AAAA())
-        self.assertEqual(RRType("DS"), RRType.DS())
-        self.assertEqual(RRType("OPT"), RRType.OPT())
-        self.assertEqual(RRType("A"), RRType.A())
-        self.assertEqual(RRType("NS"), RRType.NS())
-        self.assertEqual(RRType("CNAME"), RRType.CNAME())
-        self.assertEqual(RRType("SOA"), RRType.SOA())
-        self.assertEqual(RRType("NSEC3"), RRType.NSEC3())
+        self.assertEqual(RRType("NSEC3PARAM"), RRType.NSEC3PARAM)
+        self.assertEqual(RRType("DNAME"), RRType.DNAME)
+        self.assertEqual(RRType("PTR"), RRType.PTR)
+        self.assertEqual(RRType("MX"), RRType.MX)
+        self.assertEqual(RRType("DNSKEY"), RRType.DNSKEY)
+        self.assertEqual(RRType("TXT"), RRType.TXT)
+        self.assertEqual(RRType("RRSIG"), RRType.RRSIG)
+        self.assertEqual(RRType("NSEC"), RRType.NSEC)
+        self.assertEqual(RRType("AAAA"), RRType.AAAA)
+        self.assertEqual(RRType("DS"), RRType.DS)
+        self.assertEqual(RRType("OPT"), RRType.OPT)
+        self.assertEqual(RRType("A"), RRType.A)
+        self.assertEqual(RRType("NS"), RRType.NS)
+        self.assertEqual(RRType("CNAME"), RRType.CNAME)
+        self.assertEqual(RRType("SOA"), RRType.SOA)
+        self.assertEqual(RRType("NSEC3"), RRType.NSEC3)
 
         # these can't be built with string input
         # (see the original cpp TODO)
-        self.assertEqual(251, RRType.IXFR().get_code())
-        self.assertEqual(252, RRType.AXFR().get_code())
-        self.assertEqual(255, RRType.ANY().get_code())
+        self.assertEqual(251, RRType.IXFR.get_code())
+        self.assertEqual(252, RRType.AXFR.get_code())
+        self.assertEqual(255, RRType.ANY.get_code())
         
 if __name__ == '__main__':
     unittest.main()

+ 18 - 18
src/lib/dns/python/tests/tsig_python_test.py

@@ -40,7 +40,7 @@ class TSIGContextTest(unittest.TestCase):
         self.keyring = TSIGKeyRing()
         self.message = Message(Message.RENDER)
         self.renderer = MessageRenderer()
-        self.test_class = RRClass.IN()
+        self.test_class = RRClass.IN
         self.test_ttl = RRTTL(86400)
         self.secret = base64.b64decode(b"SFuWd/q99SzF8Yzd1QbB9g==")
         self.tsig_ctx = TSIGContext(TSIGKey(self.test_name,
@@ -59,12 +59,12 @@ class TSIGContextTest(unittest.TestCase):
     # Note: intentionally use camelCase so that we can easily copy-paste
     # corresponding C++ tests.
     def createMessageAndSign(self, id, qname, ctx, message_flags=RD_FLAG,
-                             qtype=RRType.A(), answer_data=None,
+                             qtype=RRType.A, answer_data=None,
                              answer_type=None, add_question=True,
-                             rcode=Rcode.NOERROR()):
+                             rcode=Rcode.NOERROR):
         self.message.clear(Message.RENDER)
         self.message.set_qid(id)
-        self.message.set_opcode(Opcode.QUERY())
+        self.message.set_opcode(Opcode.QUERY)
         self.message.set_rcode(rcode)
         if (message_flags & QR_FLAG) != 0:
             self.message.set_header_flag(Message.HEADERFLAG_QR)
@@ -120,7 +120,7 @@ class TSIGContextTest(unittest.TestCase):
         self.assertEqual(TSIGContext.STATE_INIT, self.tsig_ctx.get_state())
 
         # And there should be no error code.
-        self.assertEqual(TSIGError(Rcode.NOERROR()), self.tsig_ctx.get_error())
+        self.assertEqual(TSIGError(Rcode.NOERROR), self.tsig_ctx.get_error())
 
         # No message signed yet
         self.assertRaises(TSIGContextError, self.tsig_ctx.last_had_signature)
@@ -249,7 +249,7 @@ class TSIGContextTest(unittest.TestCase):
         tsig = self.createMessageAndSign(self.qid, self.test_name,
                                          self.tsig_verify_ctx,
                                          QR_FLAG|AA_FLAG|RD_FLAG,
-                                         RRType.A(), "192.0.2.1")
+                                         RRType.A, "192.0.2.1")
 
         expected_mac = b"\x8f\xcd\xa6\x6a\x7c\xd1\xa3\xb9\x94\x8e\xb1\x86" + \
             b"\x9d\x38\x4a\x9f"
@@ -280,7 +280,7 @@ class TSIGContextTest(unittest.TestCase):
         zone_name = Name("example.com")
 
         tsig = self.createMessageAndSign(axfr_qid, zone_name, self.tsig_ctx,
-                                         0, RRType.AXFR())
+                                         0, RRType.AXFR)
 
         received_data = read_wire_data("tsig_verify1.wire")
         self.commonVerifyChecks(self.tsig_verify_ctx, tsig, received_data,
@@ -289,10 +289,10 @@ class TSIGContextTest(unittest.TestCase):
 
         tsig = self.createMessageAndSign(axfr_qid, zone_name,
                                          self.tsig_verify_ctx,
-                                         AA_FLAG|QR_FLAG, RRType.AXFR(),
+                                         AA_FLAG|QR_FLAG, RRType.AXFR,
                                          "ns.example.com. root.example.com." +\
                                          " 2011041503 7200 3600 2592000 1200",
-                                         RRType.SOA())
+                                         RRType.SOA)
 
         received_data = read_wire_data("tsig_verify2.wire")
         self.commonVerifyChecks(self.tsig_ctx, tsig, received_data,
@@ -302,8 +302,8 @@ class TSIGContextTest(unittest.TestCase):
             b"\x60\x34\x13\x09\x68"
         tsig = self.createMessageAndSign(axfr_qid, zone_name,
                                          self.tsig_verify_ctx,
-                                         AA_FLAG|QR_FLAG, RRType.AXFR(),
-                                         "ns.example.com.", RRType.NS(),
+                                         AA_FLAG|QR_FLAG, RRType.AXFR,
+                                         "ns.example.com.", RRType.NS,
                                          False)
         self.commonSignChecks(tsig, axfr_qid, 0x4da8e951, expected_mac)
 
@@ -316,7 +316,7 @@ class TSIGContextTest(unittest.TestCase):
 
         test_qid = 0x7fc4
         tsig = self.createMessageAndSign(test_qid, self.test_name,
-                                         self.tsig_ctx, 0, RRType.SOA())
+                                         self.tsig_ctx, 0, RRType.SOA)
 
         # "advance the clock" and try validating, which should fail due to
         # BADTIME
@@ -328,8 +328,8 @@ class TSIGContextTest(unittest.TestCase):
         # make and sign a response in the context of TSIG error.
         tsig = self.createMessageAndSign(test_qid, self.test_name,
                                          self.tsig_verify_ctx,
-                                         QR_FLAG, RRType.SOA(), None, None,
-                                         True, Rcode.NOTAUTH())
+                                         QR_FLAG, RRType.SOA, None, None,
+                                         True, Rcode.NOTAUTH)
 
         expected_otherdata = b"\x00\x00\x4d\xa8\xbe\x86"
         expected_mac = b"\xd4\xb0\x43\xf6\xf4\x44\x95\xec\x8a\x01\x26" +\
@@ -344,7 +344,7 @@ class TSIGContextTest(unittest.TestCase):
         fix_current_time(0x4da8b9d6)
 
         tsig = self.createMessageAndSign(self.qid, self.test_name,
-                                         self.tsig_ctx, 0, RRType.SOA())
+                                         self.tsig_ctx, 0, RRType.SOA)
 
         # "rewind the clock" and try validating, which should fail due to
         # BADTIME
@@ -361,7 +361,7 @@ class TSIGContextTest(unittest.TestCase):
         fix_current_time(0x4da8b9d6)
 
         tsig = self.createMessageAndSign(self.qid, self.test_name,
-                                         self.tsig_ctx, 0, RRType.SOA())
+                                         self.tsig_ctx, 0, RRType.SOA)
 
         fix_current_time(0x4da8b9d6 + 301)
         self.assertEqual(TSIGError.BAD_TIME,
@@ -382,7 +382,7 @@ class TSIGContextTest(unittest.TestCase):
     def test_badtime_overflow(self):
         fix_current_time(200)
         tsig = self.createMessageAndSign(self.qid, self.test_name,
-                                         self.tsig_ctx, 0, RRType.SOA())
+                                         self.tsig_ctx, 0, RRType.SOA)
 
         # This should be in the okay range, but since "200 - fudge" overflows
         # and we compare them as 64-bit unsigned integers, it results in a
@@ -522,7 +522,7 @@ class TSIGContextTest(unittest.TestCase):
                          self.tsig_verify_ctx.get_state())
         self.createMessageAndSign(self.qid, self.test_name,
                                   self.tsig_verify_ctx,
-                                  QR_FLAG|AA_FLAG|RD_FLAG, RRType.A(),
+                                  QR_FLAG|AA_FLAG|RD_FLAG, RRType.A,
                                   "192.0.2.1")
         self.assertEqual(TSIGContext.STATE_SENT_RESPONSE,
                          self.tsig_verify_ctx.get_state())

+ 13 - 13
src/lib/dns/python/tests/tsigerror_python_test.py

@@ -28,7 +28,7 @@ class TSIGErrorTest(unittest.TestCase):
 
     def test_from_rcode(self):
         # We use RCODE for code values from 0-15.
-        self.assertEqual(0, TSIGError(Rcode.NOERROR()).get_code())
+        self.assertEqual(0, TSIGError(Rcode.NOERROR).get_code())
         self.assertEqual(15, TSIGError(Rcode(15)).get_code())
 
         # From error code 16 TSIG errors define a separate space, so passing
@@ -50,19 +50,19 @@ class TSIGErrorTest(unittest.TestCase):
         self.assertEqual(TSIGError.BAD_TIME_CODE, TSIGError.BAD_TIME.get_code())
 
     def test_equal(self):
-        self.assertTrue(TSIGError.NOERROR == TSIGError(Rcode.NOERROR()))
-        self.assertTrue(TSIGError(Rcode.NOERROR()) == TSIGError.NOERROR)
+        self.assertTrue(TSIGError.NOERROR == TSIGError(Rcode.NOERROR))
+        self.assertTrue(TSIGError(Rcode.NOERROR) == TSIGError.NOERROR)
 
         self.assertTrue(TSIGError.BAD_SIG == TSIGError(16))
         self.assertTrue(TSIGError(16) == TSIGError.BAD_SIG)
 
     def test_nequal(self):
-        self.assertTrue(TSIGError.BAD_KEY != TSIGError(Rcode.NOERROR()))
-        self.assertTrue(TSIGError(Rcode.NOERROR()) != TSIGError.BAD_KEY)
+        self.assertTrue(TSIGError.BAD_KEY != TSIGError(Rcode.NOERROR))
+        self.assertTrue(TSIGError(Rcode.NOERROR) != TSIGError.BAD_KEY)
 
     def test_to_text(self):
         # TSIGError derived from the standard Rcode
-        self.assertEqual("NOERROR", TSIGError(Rcode.NOERROR()).to_text())
+        self.assertEqual("NOERROR", TSIGError(Rcode.NOERROR).to_text())
 
         # Well known TSIG errors
         self.assertEqual("BADSIG", TSIGError.BAD_SIG.to_text())
@@ -74,21 +74,21 @@ class TSIGErrorTest(unittest.TestCase):
         self.assertEqual("65535", TSIGError(65535).to_text());
 
         # also check str() works same way
-        self.assertEqual("NOERROR", str(TSIGError(Rcode.NOERROR())))
+        self.assertEqual("NOERROR", str(TSIGError(Rcode.NOERROR)))
         self.assertEqual("BADSIG", str(TSIGError.BAD_SIG))
 
     def test_to_rcode(self):
         # TSIGError derived from the standard Rcode
-        self.assertEqual(Rcode.NOERROR(), TSIGError(Rcode.NOERROR()).to_rcode())
+        self.assertEqual(Rcode.NOERROR, TSIGError(Rcode.NOERROR).to_rcode())
 
         # Well known TSIG errors
-        self.assertEqual(Rcode.NOTAUTH(), TSIGError.BAD_SIG.to_rcode())
-        self.assertEqual(Rcode.NOTAUTH(), TSIGError.BAD_KEY.to_rcode())
-        self.assertEqual(Rcode.NOTAUTH(), TSIGError.BAD_TIME.to_rcode())
+        self.assertEqual(Rcode.NOTAUTH, TSIGError.BAD_SIG.to_rcode())
+        self.assertEqual(Rcode.NOTAUTH, TSIGError.BAD_KEY.to_rcode())
+        self.assertEqual(Rcode.NOTAUTH, TSIGError.BAD_TIME.to_rcode())
 
         # Unknown (or not yet supported) codes are treated as SERVFAIL.
-        self.assertEqual(Rcode.SERVFAIL(), TSIGError(19).to_rcode())
-        self.assertEqual(Rcode.SERVFAIL(), TSIGError(65535).to_rcode())
+        self.assertEqual(Rcode.SERVFAIL, TSIGError(19).to_rcode())
+        self.assertEqual(Rcode.SERVFAIL, TSIGError(65535).to_rcode())
 
         # Check there's no redundant refcount (which would cause leak)
         self.assertEqual(1, sys.getrefcount(TSIGError.BAD_SIG.to_rcode()))

+ 29 - 32
src/lib/dns/python/tests/zone_checker_python_test.py

@@ -35,8 +35,8 @@ class ZoneCheckerTest(unittest.TestCase):
         rrsets = RRsetCollection(b'example.org. 0 SOA . . 0 0 0 0 0\n' +
                                  b'example.org. 0 NS ns.example.org.\n' +
                                  b'ns.example.org. 0 A 192.0.2.1\n',
-                                 Name('example.org'), RRClass.IN())
-        self.assertTrue(check_zone(Name('example.org'), RRClass.IN(),
+                                 Name('example.org'), RRClass.IN)
+        self.assertTrue(check_zone(Name('example.org'), RRClass.IN,
                                    rrsets,
                                    (lambda r: self.__callback(r, errors),
                                     lambda r: self.__callback(r, warns))))
@@ -45,8 +45,8 @@ class ZoneCheckerTest(unittest.TestCase):
 
         # Check fails and one additional warning.
         rrsets = RRsetCollection(b'example.org. 0 NS ns.example.org.',
-                                 Name('example.org'), RRClass.IN())
-        self.assertFalse(check_zone(Name('example.org'), RRClass.IN(), rrsets,
+                                 Name('example.org'), RRClass.IN)
+        self.assertFalse(check_zone(Name('example.org'), RRClass.IN, rrsets,
                                     (lambda r: self.__callback(r, errors),
                                      lambda r: self.__callback(r, warns))))
         self.assertEqual(['zone example.org/IN: has 0 SOA records'], errors)
@@ -56,7 +56,7 @@ class ZoneCheckerTest(unittest.TestCase):
         # Same RRset collection, suppressing callbacks
         errors = []
         warns = []
-        self.assertFalse(check_zone(Name('example.org'), RRClass.IN(), rrsets,
+        self.assertFalse(check_zone(Name('example.org'), RRClass.IN, rrsets,
                                     (None, None)))
         self.assertEqual([], errors)
         self.assertEqual([], warns)
@@ -64,29 +64,29 @@ class ZoneCheckerTest(unittest.TestCase):
     def test_check_badarg(self):
         rrsets = RRsetCollection()
         # Bad types
-        self.assertRaises(TypeError, check_zone, 1, RRClass.IN(), rrsets,
+        self.assertRaises(TypeError, check_zone, 1, RRClass.IN, rrsets,
                           (None, None))
         self.assertRaises(TypeError, check_zone, Name('example'), 1, rrsets,
                           (None, None))
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           1, (None, None))
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, 1)
 
         # Bad callbacks
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, (None, None, None))
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, (1, None))
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, (None, 1))
 
         # Extra/missing args
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, (None, None), 1)
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets)
-        check_zone(Name('example'), RRClass.IN(), rrsets, (None, None))
+        check_zone(Name('example'), RRClass.IN, rrsets, (None, None))
 
     def test_check_callback_fail(self):
         # Let the call raise a Python exception.  It should be propagated to
@@ -96,7 +96,7 @@ class ZoneCheckerTest(unittest.TestCase):
 
         # Using an empty collection, triggering an error callback.
         self.assertRaises(FakeException, check_zone, Name('example.org'),
-                          RRClass.IN(), RRsetCollection(),
+                          RRClass.IN, RRsetCollection(),
                           (__bad_callback, None))
 
         # An unusual case: the callback is expected to return None, but if it
@@ -108,7 +108,7 @@ class ZoneCheckerTest(unittest.TestCase):
 
         ref_checker = RefChecker()
         orig_refcnt = sys.getrefcount(ref_checker)
-        check_zone(Name('example.org'), RRClass.IN(), RRsetCollection(),
+        check_zone(Name('example.org'), RRClass.IN, RRsetCollection(),
                    (lambda r: __callback(r, ref_checker), None))
         self.assertEqual(orig_refcnt, sys.getrefcount(ref_checker))
 
@@ -132,48 +132,45 @@ class ZoneCheckerTest(unittest.TestCase):
                     raise FakeException('find error')
                 if self.__find_result is not 'use_default':
                     return self.__find_result
-                if rrtype == RRType.SOA():
-                    soa = RRset(Name('example'), RRClass.IN(), rrtype,
-                                RRTTL(0))
-                    soa.add_rdata(Rdata(RRType.SOA(), RRClass.IN(),
+                if rrtype == RRType.SOA:
+                    soa = RRset(Name('example'), RRClass.IN, rrtype, RRTTL(0))
+                    soa.add_rdata(Rdata(RRType.SOA, RRClass.IN,
                                         '. . 0 0 0 0 0'))
                     return soa
-                if rrtype == RRType.NS():
-                    ns = RRset(Name('example'), RRClass.IN(), rrtype,
-                               RRTTL(0))
-                    ns.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
-                                       'example.org.'))
+                if rrtype == RRType.NS:
+                    ns = RRset(Name('example'), RRClass.IN, rrtype, RRTTL(0))
+                    ns.add_rdata(Rdata(RRType.NS, RRClass.IN, 'example.org.'))
                     return ns
                 return None
 
         # A successful case.  Just checking it works in that case.
         rrsets = FakeRRsetCollection()
-        self.assertTrue(check_zone(Name('example'), RRClass.IN(), rrsets,
+        self.assertTrue(check_zone(Name('example'), RRClass.IN, rrsets,
                                    (None, None)))
 
         # Likewise, normal case but zone check fails.
         rrsets = FakeRRsetCollection(False, None)
-        self.assertFalse(check_zone(Name('example'), RRClass.IN(), rrsets,
+        self.assertFalse(check_zone(Name('example'), RRClass.IN, rrsets,
                                     (None, None)))
 
         # Our find() returns a bad type of result.
         rrsets = FakeRRsetCollection(False, 1)
-        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN(),
+        self.assertRaises(TypeError, check_zone, Name('example'), RRClass.IN,
                           rrsets, (None, None))
 
         # Our find() returns an empty SOA RRset.  C++ zone checker code
         # throws, which results in IscException.
         rrsets = FakeRRsetCollection(False, RRset(Name('example'),
-                                                  RRClass.IN(),
-                                                  RRType.SOA(), RRTTL(0)))
+                                                  RRClass.IN,
+                                                  RRType.SOA, RRTTL(0)))
         self.assertRaises(IscException, check_zone, Name('example'),
-                          RRClass.IN(), rrsets, (None, None))
+                          RRClass.IN, rrsets, (None, None))
 
         # Our find() raises an exception.  That exception is propagated to
         # the top level.
         rrsets = FakeRRsetCollection(True)
         self.assertRaises(FakeException, check_zone, Name('example'),
-                          RRClass.IN(), rrsets, (None, None))
+                          RRClass.IN, rrsets, (None, None))
 
 if __name__ == '__main__':
     unittest.main()

+ 4 - 0
src/lib/dns/rdata/template.h

@@ -39,6 +39,10 @@
 // Note: do not remove the comment lines beginning with "BEGIN_" and "END_".
 // These are markers used by a script for auto-generating build-able source
 // files.
+//
+// On completion of implementing a new type of Rdata, remove the corresponding
+// entry from the meta_types dictionary of gen-rdatacode.py.in.  Otherwise
+// it will cause build failure.
 
 class MyType : public Rdata {
 public:

+ 0 - 14
src/lib/dns/rrclass-placeholder.h

@@ -294,28 +294,14 @@ public:
 
     // BEGIN_WELL_KNOWN_CLASS_DECLARATIONS
     // END_WELL_KNOWN_CLASS_DECLARATIONS
-    
-    static const RRClass& NONE();
 
 private:
-    // \brief Meta-classes
-    enum {
-        RRCLASS_RESERVED0 = 0,
-        RRCLASS_NONE = 254
-    };
     uint16_t classcode_;
 };
 
 // BEGIN_WELL_KNOWN_CLASS_DEFINITIONS
 // END_WELL_KNOWN_CLASS_DEFINITIONS
 
-inline const RRClass&
-RRClass::NONE() {
-    static RRClass rrclass(RRCLASS_NONE);
-
-    return (rrclass);
-}
-
 ///
 /// \brief Insert the \c RRClass as a string into stream.
 ///

+ 0 - 30
src/lib/dns/rrtype-placeholder.h

@@ -262,43 +262,13 @@ public:
     // BEGIN_WELL_KNOWN_TYPE_DECLARATIONS
     // END_WELL_KNOWN_TYPE_DECLARATIONS
 
-    static const RRType& IXFR();
-    static const RRType& AXFR();
-    static const RRType& ANY();
-
 private:
-    // \brief Meta-classes
-    // XXX: these should be implemented using rrparamregistry
-    enum {
-        RRTYPE_IXFR = 251,
-        RRTYPE_AXFR = 252,
-        RRTYPE_ANY = 255
-    };
-
     uint16_t typecode_;
 };
 
 // BEGIN_WELL_KNOWN_TYPE_DEFINITIONS
 // END_WELL_KNOWN_TYPE_DEFINITIONS
 
-inline const RRType&
-RRType::IXFR() {
-    static RRType rrtype(RRTYPE_IXFR);
-    return (rrtype);
-}
-
-inline const RRType&
-RRType::AXFR() {
-    static RRType rrtype(RRTYPE_AXFR);
-    return (rrtype);
-}
-
-inline const RRType&
-RRType::ANY() {
-    static RRType rrtype(RRTYPE_ANY);
-    return (rrtype);
-}
-
 ///
 /// \brief Insert the \c RRType as a string into stream.
 ///

+ 25 - 0
src/lib/dns/tests/rrclass_unittest.cc

@@ -148,4 +148,29 @@ TEST_F(RRClassTest, LeftShiftOperator) {
     oss << RRClass::IN();
     EXPECT_EQ(RRClass::IN().toText(), oss.str());
 }
+
+// Below, we'll check definitions for all well-known RR classes; whether they
+// are defined and have the correct parameter values.  Test data are generated
+// from the list available at:
+// http://www.iana.org/assignments/dns-parameters/dns-parameters.xml
+struct ClassParam {
+    const char* const txt;      // "IN", "CH", etc
+    const uint16_t code;        // 1, 3,
+    const RRClass& (*obj)();     // RRClass::IN(), etc
+} known_classes[] = {
+    {"IN", 1, RRClass::IN}, {"CH", 3, RRClass::CH}, {"HS", 4, RRClass::HS},
+    {"NONE", 254, RRClass::NONE}, {"ANY", 255, RRClass::ANY},
+    {NULL, 0, NULL}
+};
+
+TEST(RRClassConstTest, wellKnowns) {
+    for (int i = 0; known_classes[i].txt; ++i) {
+        SCOPED_TRACE("Checking well known RRClass: " +
+                     string(known_classes[i].txt));
+        EXPECT_EQ(known_classes[i].code,
+                  RRClass(known_classes[i].txt).getCode());
+        EXPECT_EQ(known_classes[i].code,
+                  (*known_classes[i].obj)().getCode());
+    }
+}
 }

+ 1 - 1
src/lib/dns/tests/rrset_unittest.cc

@@ -205,7 +205,7 @@ TEST_F(RRsetTest, toText) {
     // Unless it is type ANY or NONE
     EXPECT_EQ("test.example.com. 3600 ANY A\n",
               rrset_any_a_empty.toText());
-    EXPECT_EQ("test.example.com. 3600 CLASS254 A\n",
+    EXPECT_EQ("test.example.com. 3600 NONE A\n",
               rrset_none_a_empty.toText());
 }
 

+ 53 - 0
src/lib/dns/tests/rrtype_unittest.cc

@@ -145,4 +145,57 @@ TEST_F(RRTypeTest, LeftShiftOperator) {
     oss << RRType::A();
     EXPECT_EQ(RRType::A().toText(), oss.str());
 }
+
+// Below, we'll check definitions for all well-known RR types; whether they
+// are defined and have the correct parameter values.  Test data are generated
+// from the list available at:
+// http://www.iana.org/assignments/dns-parameters/dns-parameters.xml
+struct TypeParam {
+    const char* const txt;      // "A", "AAAA", "NS", etc
+    const uint16_t code;        // 1, 28, 2, etc
+    const RRType& (*obj)();     // RRType::A(), etc
+} known_types[] = {
+    {"A", 1, RRType::A}, {"NS", 2, RRType::NS}, {"MD", 3, RRType::MD},
+    {"MF", 4, RRType::MF}, {"CNAME", 5, RRType::CNAME},
+    {"SOA", 6, RRType::SOA}, {"MB", 7, RRType::MB}, {"MG", 8, RRType::MG},
+    {"MR", 9, RRType::MR}, {"NULL", 10, RRType::Null},
+    {"WKS", 11, RRType::WKS}, {"PTR", 12, RRType::PTR},
+    {"HINFO", 13, RRType::HINFO}, {"MINFO", 14, RRType::MINFO},
+    {"MX", 15, RRType::MX}, {"TXT", 16, RRType::TXT}, {"RP", 17, RRType::RP},
+    {"AFSDB", 18, RRType::AFSDB}, {"X25", 19, RRType::X25},
+    {"ISDN", 20, RRType::ISDN}, {"RT", 21, RRType::RT},
+    {"NSAP", 22, RRType::NSAP}, {"NSAP-PTR", 23, RRType::NSAP_PTR},
+    {"SIG", 24, RRType::SIG}, {"KEY", 25, RRType::KEY},
+    {"PX", 26, RRType::PX}, {"GPOS", 27, RRType::GPOS},
+    {"AAAA", 28, RRType::AAAA}, {"LOC", 29, RRType::LOC},
+    {"NXT", 30, RRType::NXT}, {"SRV", 33, RRType::SRV},
+    {"NAPTR", 35, RRType::NAPTR}, {"KX", 36, RRType::KX},
+    {"CERT", 37, RRType::CERT}, {"A6", 38, RRType::A6},
+    {"DNAME", 39, RRType::DNAME}, {"OPT", 41, RRType::OPT},
+    {"APL", 42, RRType::APL}, {"DS", 43, RRType::DS},
+    {"SSHFP", 44, RRType::SSHFP}, {"IPSECKEY", 45, RRType::IPSECKEY},
+    {"RRSIG", 46, RRType::RRSIG}, {"NSEC", 47, RRType::NSEC},
+    {"DNSKEY", 48, RRType::DNSKEY}, {"DHCID", 49, RRType::DHCID},
+    {"NSEC3", 50, RRType::NSEC3}, {"NSEC3PARAM", 51, RRType::NSEC3PARAM},
+    {"TLSA", 52, RRType::TLSA}, {"HIP", 55, RRType::HIP},
+    {"SPF", 99, RRType::SPF}, {"UNSPEC", 103, RRType::UNSPEC},
+    {"NID", 104, RRType::NID}, {"L32", 105, RRType::L32},
+    {"L64", 106, RRType::L64}, {"LP", 107, RRType::LP},
+    {"TKEY", 249, RRType::TKEY}, {"TSIG", 250, RRType::TSIG},
+    {"IXFR", 251, RRType::IXFR}, {"AXFR", 252, RRType::AXFR},
+    {"MAILB", 253, RRType::MAILB}, {"MAILA", 254, RRType::MAILA},
+    {"ANY", 255, RRType::ANY}, {"URI", 256, RRType::URI},
+    {"CAA", 257, RRType::CAA}, {"DLV", 32769, RRType::DLV},
+    {NULL, 0, NULL}
+};
+
+TEST(RRTypeConstTest, wellKnowns) {
+    for (int i = 0; known_types[i].txt; ++i) {
+        SCOPED_TRACE("Checking well known RRType: " +
+                     string(known_types[i].txt));
+        EXPECT_EQ(known_types[i].code, RRType(known_types[i].txt).getCode());
+        EXPECT_EQ(known_types[i].code,
+                  (*known_types[i].obj)().getCode());
+    }
+}
 }

+ 3 - 7
src/lib/python/isc/__init__.py

@@ -1,7 +1,3 @@
-# On some systems, it appears the dynamic linker gets
-# confused if the order is not right here
-# There is probably a solution for this, but for now:
-# order is important here!
-import isc.cc
-import isc.config
-import isc.datasrc
+"""
+This is the top directory for common BIND 10 Python modules and packages.
+"""

+ 5 - 5
src/lib/python/isc/datasrc/tests/clientlist_test.py

@@ -43,8 +43,8 @@ class ClientListTest(unittest.TestCase):
         Test the constructor. It should accept an RRClass. Check it
         reject invalid inputs.
         """
-        isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN())
-        isc.datasrc.ConfigurableClientList(isc.dns.RRClass.CH())
+        isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
+        isc.datasrc.ConfigurableClientList(isc.dns.RRClass.CH)
         # Not enough arguments
         self.assertRaises(TypeError, isc.datasrc.ConfigurableClientList)
         # Bad types of arguments
@@ -52,7 +52,7 @@ class ClientListTest(unittest.TestCase):
         self.assertRaises(TypeError, isc.datasrc.ConfigurableClientList, "IN")
         # Too many arguments
         self.assertRaises(TypeError, isc.datasrc.ConfigurableClientList,
-                         isc.dns.RRClass.IN(), isc.dns.RRClass.IN())
+                         isc.dns.RRClass.IN, isc.dns.RRClass.IN)
 
     def test_configure(self):
         """
@@ -60,7 +60,7 @@ class ClientListTest(unittest.TestCase):
         ones are acceptend and invalid rejected. We check the changes
         have effect.
         """
-        self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN())
+        self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
         # This should be NOP now
         self.clist.configure("[]", True)
         # Check the zone is not there yet
@@ -102,7 +102,7 @@ class ClientListTest(unittest.TestCase):
         Test the find accepts the right arguments, some of them can be omitted,
         etc.
         """
-        self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN())
+        self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
         self.clist.configure('''[{
             "type": "MasterFiles",
             "params": {

+ 70 - 70
src/lib/python/isc/datasrc/tests/datasrc_test.py

@@ -51,8 +51,8 @@ def check_for_rrset(expected_rrsets, rrset):
     return False
 
 def create_soa(serial):
-    soa = RRset(Name('example.org'), RRClass.IN(), RRType.SOA(), RRTTL(3600))
-    soa.add_rdata(Rdata(RRType.SOA(), RRClass.IN(),
+    soa = RRset(Name('example.org'), RRClass.IN, RRType.SOA, RRTTL(3600))
+    soa.add_rdata(Rdata(RRType.SOA, RRClass.IN,
                         'ns1.example.org. admin.example.org. ' +
                         str(serial) + ' 3600 1800 2419200 7200'))
     return soa
@@ -66,13 +66,13 @@ def test_findall_common(self, tested):
     result, rrset, _ = tested.find_all(isc.dns.Name("www.sql1.example.com"),
                                        ZoneFinder.FIND_DEFAULT)
     self.assertEqual(ZoneFinder.DELEGATION, result)
-    expected = RRset(Name('sql1.example.com.'), RRClass.IN(), RRType.NS(),
+    expected = RRset(Name('sql1.example.com.'), RRClass.IN, RRType.NS,
                      RRTTL(3600))
-    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+    expected.add_rdata(Rdata(RRType.NS, RRClass.IN,
                              'dns01.example.com.'))
-    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+    expected.add_rdata(Rdata(RRType.NS, RRClass.IN,
                              'dns02.example.com.'))
-    expected.add_rdata(Rdata(RRType.NS(), RRClass.IN(),
+    expected.add_rdata(Rdata(RRType.NS, RRClass.IN,
                              'dns03.example.com.'))
     self.assertTrue(rrsets_equal(expected, rrset))
 
@@ -88,16 +88,16 @@ def test_findall_common(self, tested):
     self.assertEqual(2, len(rrsets))
     rrsets.sort(key=lambda rrset: rrset.get_type().to_text())
     expected = [
-        RRset(Name('mix.example.com.'), RRClass.IN(), RRType.A(),
+        RRset(Name('mix.example.com.'), RRClass.IN, RRType.A,
               RRTTL(3600)),
-        RRset(Name('mix.example.com.'), RRClass.IN(), RRType.AAAA(),
+        RRset(Name('mix.example.com.'), RRClass.IN, RRType.AAAA,
               RRTTL(3600))
     ]
-    expected[0].add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.1"))
-    expected[0].add_rdata(Rdata(RRType.A(), RRClass.IN(), "192.0.2.2"))
-    expected[1].add_rdata(Rdata(RRType.AAAA(), RRClass.IN(),
+    expected[0].add_rdata(Rdata(RRType.A, RRClass.IN, "192.0.2.1"))
+    expected[0].add_rdata(Rdata(RRType.A, RRClass.IN, "192.0.2.2"))
+    expected[1].add_rdata(Rdata(RRType.AAAA, RRClass.IN,
                                 "2001:db8::1"))
-    expected[1].add_rdata(Rdata(RRType.AAAA(), RRClass.IN(),
+    expected[1].add_rdata(Rdata(RRType.AAAA, RRClass.IN,
                                 "2001:db8::2"))
     for (rrset, exp) in zip(rrsets, expected):
         self.assertTrue(rrsets_equal(exp, rrset))
@@ -158,9 +158,9 @@ class DataSrcClient(unittest.TestCase):
         expected_rrset_list = []
 
         name = isc.dns.Name("sql1.example.com")
-        rrclass = isc.dns.RRClass.IN()
+        rrclass = isc.dns.RRClass.IN
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.DNSKEY(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.DNSKEY, isc.dns.RRTTL(3600),
                   [
                      "256 3 5 AwEAAdYdRhBAEY67R/8G1N5AjGF6asIiNh/pNGeQ8xDQP13J"+
                      "N2lo+sNqWcmpYNhuVqRbLB+mamsU1XcCICSBvAlSmfz/ZUdafX23knAr"+
@@ -168,7 +168,7 @@ class DataSrcClient(unittest.TestCase):
                      "5fs0dE/xLztL/CzZ"
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.DNSKEY(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.DNSKEY, isc.dns.RRTTL(3600),
                   [
                      "257 3 5 AwEAAbaKDSa9XEFTsjSYpUTHRotTS9Tz3krfDucugW5UokGQ"+
                      "KC26QlyHXlPTZkC+aRFUs/dicJX2kopndLcnlNAPWiKnKtrsFSCnIJDB"+
@@ -179,22 +179,22 @@ class DataSrcClient(unittest.TestCase):
                      "jRWAzGsxJiJyjd6w2k0="
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.NS(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.NS, isc.dns.RRTTL(3600),
                   [
                     "dns01.example.com."
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.NS(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.NS, isc.dns.RRTTL(3600),
                   [
                     "dns02.example.com."
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.NS(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.NS, isc.dns.RRTTL(3600),
                   [
                     "dns03.example.com."
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.NSEC(), isc.dns.RRTTL(7200),
+                  isc.dns.RRType.NSEC, isc.dns.RRTTL(7200),
                   [
                      "www.sql1.example.com. NS SOA RRSIG NSEC DNSKEY"
                   ])
@@ -204,36 +204,36 @@ class DataSrcClient(unittest.TestCase):
         # Since we passed separate_rrs = True to get_iterator, we get several
         # sets of RRSIGs, one for each TTL
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(3600), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(3600), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(3600), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(3600), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(3600), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(3600), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(3600), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(3600), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(7200), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(7200), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.SOA(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.SOA, isc.dns.RRTTL(3600),
                   [
                      "master.example.com. admin.example.com. 678 3600 1800 2419200 7200"
                   ])
         name = isc.dns.Name("www.sql1.example.com.")
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.A(), isc.dns.RRTTL(3600),
+                  isc.dns.RRType.A, isc.dns.RRTTL(3600),
                   [
                      "192.0.2.100"
                   ])
         name = isc.dns.Name("www.sql1.example.com.")
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.NSEC(), isc.dns.RRTTL(7200),
+                  isc.dns.RRType.NSEC, isc.dns.RRTTL(7200),
                   [
                      "sql1.example.com. A RRSIG NSEC"
                   ])
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(3600), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(3600), None)
         add_rrset(expected_rrset_list, name, rrclass,
-                  isc.dns.RRType.RRSIG(), isc.dns.RRTTL(7200), None)
+                  isc.dns.RRType.RRSIG, isc.dns.RRTTL(7200), None)
 
         # rrs is an iterator, but also has direct get_next_rrset(), use
         # the latter one here
@@ -287,11 +287,11 @@ class DataSrcClient(unittest.TestCase):
         dsc = isc.datasrc.DataSourceClient("sqlite3", READ_ZONE_DB_CONFIG)
         iterator = dsc.get_iterator(isc.dns.Name("sql1.example.com."))
         expected_soa = isc.dns.RRset(isc.dns.Name("sql1.example.com."),
-                                     isc.dns.RRClass.IN(),
-                                     isc.dns.RRType.SOA(),
+                                     isc.dns.RRClass.IN,
+                                     isc.dns.RRType.SOA,
                                      isc.dns.RRTTL(3600))
-        expected_soa.add_rdata(isc.dns.Rdata(isc.dns.RRType.SOA(),
-                                             isc.dns.RRClass.IN(),
+        expected_soa.add_rdata(isc.dns.Rdata(isc.dns.RRType.SOA,
+                                             isc.dns.RRClass.IN,
                                              "master.example.com. " +
                                              "admin.example.com. 678 " +
                                              "3600 1800 2419200 7200"))
@@ -337,7 +337,7 @@ class DataSrcClient(unittest.TestCase):
         result, finder = dsc.find_zone(isc.dns.Name("example.com"))
 
         self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual(isc.dns.RRClass.IN, finder.get_class())
         self.assertEqual("example.com.", finder.get_origin().to_text())
 
         test_findall_common(self, finder)
@@ -347,11 +347,11 @@ class DataSrcClient(unittest.TestCase):
 
         result, finder = dsc.find_zone(isc.dns.Name("example.com"))
         self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual(isc.dns.RRClass.IN, finder.get_class())
         self.assertEqual("example.com.", finder.get_origin().to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -359,13 +359,13 @@ class DataSrcClient(unittest.TestCase):
 
         # Check the optional parameters are optional
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A())
+                                       isc.dns.RRType.A)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
                          rrset.to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("www.sql1.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.DELEGATION, result)
         self.assertEqual("sql1.example.com. 3600 IN NS dns01.example.com.\n" +
@@ -374,7 +374,7 @@ class DataSrcClient(unittest.TestCase):
                          rrset.to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("doesnotexist.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
@@ -382,16 +382,16 @@ class DataSrcClient(unittest.TestCase):
 
         self.assertRaises(isc.datasrc.OutOfZone, finder.find,
                           isc.dns.Name("www.some.other.domain"),
-                          isc.dns.RRType.A())
+                          isc.dns.RRType.A)
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.TXT(),
+                                       isc.dns.RRType.TXT,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.NXRRSET, result)
         self.assertEqual(None, rrset)
 
         result, rrset, _ = finder.find(isc.dns.Name("cname-ext.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.CNAME, result)
         self.assertEqual(
@@ -400,14 +400,14 @@ class DataSrcClient(unittest.TestCase):
 
         result, rrset, flags = \
             finder.find(isc.dns.Name("foo.wild.example.com"),
-                        isc.dns.RRType.A(), finder.FIND_DEFAULT)
+                        isc.dns.RRType.A, finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual(finder.RESULT_WILDCARD, flags)
         self.assertEqual("foo.wild.example.com. 3600 IN A 192.0.2.255\n",
                          rrset.to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("foo.wild.example.com"),
-                                       isc.dns.RRType.TXT(),
+                                       isc.dns.RRType.TXT,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.NXRRSET, result)
         self.assertTrue(finder.RESULT_WILDCARD, flags)
@@ -415,7 +415,7 @@ class DataSrcClient(unittest.TestCase):
 
         self.assertRaises(TypeError, finder.find,
                           "foo",
-                          isc.dns.RRType.A(),
+                          isc.dns.RRType.A,
                           finder.FIND_DEFAULT)
         self.assertRaises(TypeError, finder.find,
                           isc.dns.Name("cname-ext.example.com"),
@@ -423,7 +423,7 @@ class DataSrcClient(unittest.TestCase):
                           finder.FIND_DEFAULT)
         self.assertRaises(TypeError, finder.find,
                           isc.dns.Name("cname-ext.example.com"),
-                          isc.dns.RRType.A(),
+                          isc.dns.RRType.A,
                           "foo")
 
 class DataSrcUpdater(unittest.TestCase):
@@ -451,7 +451,7 @@ class DataSrcUpdater(unittest.TestCase):
         dsc = isc.datasrc.DataSourceClient("sqlite3", WRITE_ZONE_DB_CONFIG)
         updater = dsc.get_updater(isc.dns.Name("example.com"), False)
         result, rrset, _ = updater.find(isc.dns.Name("www.example.com"),
-                                        isc.dns.RRType.A(),
+                                        isc.dns.RRType.A,
                                         ZoneFinder.FIND_DEFAULT)
         self.assertEqual(ZoneFinder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -459,7 +459,7 @@ class DataSrcUpdater(unittest.TestCase):
 
         # Omit optional parameters
         result, rrset, _ = updater.find(isc.dns.Name("www.example.com"),
-                                        isc.dns.RRType.A())
+                                        isc.dns.RRType.A)
         self.assertEqual(ZoneFinder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
                          rrset.to_text())
@@ -471,11 +471,11 @@ class DataSrcUpdater(unittest.TestCase):
         # first make sure, through a separate finder, that some record exists
         result, finder = dsc.find_zone(isc.dns.Name("example.com"))
         self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual(isc.dns.RRClass.IN, finder.get_class())
         self.assertEqual("example.com.", finder.get_origin().to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -490,13 +490,13 @@ class DataSrcUpdater(unittest.TestCase):
         # The record should be gone in the updater, but not in the original
         # finder (since we have not committed)
         result, rrset, _ = updater.find(isc.dns.Name("www.example.com"),
-                                        isc.dns.RRType.A(),
+                                        isc.dns.RRType.A,
                                         finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -508,7 +508,7 @@ class DataSrcUpdater(unittest.TestCase):
 
         # the record should be gone now in the 'real' finder as well
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
@@ -522,7 +522,7 @@ class DataSrcUpdater(unittest.TestCase):
         self.assertRaises(isc.datasrc.Error, updater.commit)
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -537,26 +537,26 @@ class DataSrcUpdater(unittest.TestCase):
         rrsets = updater.get_rrset_collection()
 
         # From this point we cannot make further updates
-        rrset = RRset(isc.dns.Name('www.example.com'), isc.dns.RRClass.IN(),
-                      isc.dns.RRType.AAAA(), isc.dns.RRTTL(10))
-        rrset.add_rdata(isc.dns.Rdata(isc.dns.RRType.AAAA(),
-                                      isc.dns.RRClass.IN(), '2001:db8::1'))
+        rrset = RRset(isc.dns.Name('www.example.com'), isc.dns.RRClass.IN,
+                      isc.dns.RRType.AAAA, isc.dns.RRTTL(10))
+        rrset.add_rdata(isc.dns.Rdata(isc.dns.RRType.AAAA,
+                                      isc.dns.RRClass.IN, '2001:db8::1'))
         self.assertRaises(isc.datasrc.Error, updater.add_rrset, rrset)
 
         # Checks basic API
         found = rrsets.find(isc.dns.Name("www.example.com"),
-                            isc.dns.RRClass.IN(), isc.dns.RRType.A())
+                            isc.dns.RRClass.IN, isc.dns.RRType.A)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
                          found.to_text())
         self.assertEqual(None, rrsets.find(isc.dns.Name("www.example.com"),
-                                           isc.dns.RRClass.IN(),
-                                           isc.dns.RRType.AAAA()))
+                                           isc.dns.RRClass.IN,
+                                           isc.dns.RRType.AAAA))
 
         # Once committed collection cannot be used any more.
         updater.commit()
         self.assertRaises(isc.dns.RRsetCollectionError,
                           rrsets.find, isc.dns.Name("www.example.com"),
-                          isc.dns.RRClass.IN(), isc.dns.RRType.A())
+                          isc.dns.RRClass.IN, isc.dns.RRType.A)
 
         # When we destroy the RRsetCollection it should release the refcount
         # to the updater.
@@ -578,10 +578,10 @@ class DataSrcUpdater(unittest.TestCase):
         # see if a lookup succeeds in sqlite3 ds
         result, finder = dsc_sql.find_zone(isc.dns.Name("example.com"))
         self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual(isc.dns.RRClass.IN, finder.get_class())
         self.assertEqual("example.com.", finder.get_origin().to_text())
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -600,11 +600,11 @@ class DataSrcUpdater(unittest.TestCase):
         # first make sure, through a separate finder, that some record exists
         result, finder = dsc.find_zone(isc.dns.Name("example.com"))
         self.assertEqual(finder.SUCCESS, result)
-        self.assertEqual(isc.dns.RRClass.IN(), finder.get_class())
+        self.assertEqual(isc.dns.RRClass.IN, finder.get_class())
         self.assertEqual("example.com.", finder.get_origin().to_text())
 
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -619,7 +619,7 @@ class DataSrcUpdater(unittest.TestCase):
         # The record should be gone in the updater, but not in the original
         # finder (since we have not committed)
         result, rrset, _ = updater.find(isc.dns.Name("www.example.com"),
-                                        isc.dns.RRType.A(),
+                                        isc.dns.RRType.A,
                                         finder.FIND_DEFAULT)
         self.assertEqual(finder.NXDOMAIN, result)
         self.assertEqual(None, rrset)
@@ -629,7 +629,7 @@ class DataSrcUpdater(unittest.TestCase):
 
         # the record should still be available in the 'real' finder as well
         result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
-                                       isc.dns.RRType.A(),
+                                       isc.dns.RRType.A,
                                        finder.FIND_DEFAULT)
         self.assertEqual(finder.SUCCESS, result)
         self.assertEqual("www.example.com. 3600 IN A 192.0.2.1\n",
@@ -755,9 +755,9 @@ class JournalWrite(unittest.TestCase):
         conn.close()
 
     def create_a(self, address):
-        a_rr = RRset(Name('www.example.org'), RRClass.IN(), RRType.A(),
+        a_rr = RRset(Name('www.example.org'), RRClass.IN, RRType.A,
                      RRTTL(3600))
-        a_rr.add_rdata(Rdata(RRType.A(), RRClass.IN(), address))
+        a_rr.add_rdata(Rdata(RRType.A, RRClass.IN, address))
         return (a_rr)
 
     def test_journal_write(self):

+ 0 - 0
src/lib/python/isc/datasrc/tests/zone_loader_test.py


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