[bind/f19] update RRL patch to the latest version 9.9.3-rl.150.20

Tomas Hozza thozza at fedoraproject.org
Mon Jun 3 13:04:52 UTC 2013


commit df0cae9e8b391795a31e2b7056243c1072520ee2
Author: Tomas Hozza <thozza at redhat.com>
Date:   Mon Jun 3 14:40:31 2013 +0200

    update RRL patch to the latest version 9.9.3-rl.150.20
    
    Signed-off-by: Tomas Hozza <thozza at redhat.com>

 bind.spec                           |    5 +-
 rl-9.9.3rc2.patch => rl-9.9.3.patch | 1162 +++++++++++++++++++----------------
 2 files changed, 623 insertions(+), 544 deletions(-)
---
diff --git a/bind.spec b/bind.spec
index abd2280..923de0b 100644
--- a/bind.spec
+++ b/bind.spec
@@ -79,7 +79,7 @@ Patch131:bind-9.9.1-P2-multlib-conflict.patch
 Patch132:bind99-stat.patch
 Patch133:bind99-rh640538.patch
 Patch134:bind97-rh669163.patch
-Patch136:rl-9.9.3rc2.patch
+Patch136:rl-9.9.3.patch
 Patch137:bind99-rrl.patch
 # Install dns/update.h header for bind-dyndb-ldap plugin
 Patch138:bind-9.9.3-include-update-h.patch
@@ -279,7 +279,7 @@ popd
 %patch127 -p1 -b .forward
 %patch130 -p1 -b .libdb4
 %patch131 -p1 -b .multlib-conflict
-%patch136 -p1 -b .rl
+%patch136 -p0 -b .rl
 %patch137 -p1 -b .rrl
 %patch138 -p1 -b .update
 
@@ -782,6 +782,7 @@ rm -rf ${RPM_BUILD_ROOT}
 * Mon Jun 03 2013 Tomas Hozza <thozza at redhat.com> 32:9.9.3-1
 - update to 9.9.3
 - install dns/update.h header
+- update RRL patch to the latest version 9.9.3-rl.150.20
 
 * Fri May 17 2013 Tomas Hozza <thozza at redhat.com> 32:9.9.3-0.7.rc2
 - Fix segfault in host/nslookup (#878139)
diff --git a/rl-9.9.3rc2.patch b/rl-9.9.3.patch
similarity index 76%
rename from rl-9.9.3rc2.patch
rename to rl-9.9.3.patch
index 13d2fd9..90ad238 100644
--- a/rl-9.9.3rc2.patch
+++ b/rl-9.9.3.patch
@@ -1,7 +1,7 @@
-diff -up bind-9.9.3rc2/bin/named/client.c.rl bind-9.9.3rc2/bin/named/client.c
---- bind-9.9.3rc2/bin/named/client.c.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/client.c	2013-05-13 12:30:38.624659408 +0200
-@@ -994,6 +994,11 @@ ns_client_send(ns_client_t *client) {
+diff -r -u bin/named/client.c-orig bin/named/client.c
+--- bin/named/client.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/client.c	2004-01-01 00:00:00.000000000 +0000
+@@ -994,6 +994,11 @@
  	}
  	if (result != ISC_R_SUCCESS)
  		goto done;
@@ -13,7 +13,7 @@ diff -up bind-9.9.3rc2/bin/named/client.c.rl bind-9.9.3rc2/bin/named/client.c
  	result = dns_message_rendersection(client->message,
  					   DNS_SECTION_ANSWER,
  					   DNS_MESSAGERENDER_PARTIAL |
-@@ -1134,6 +1139,49 @@ ns_client_error(ns_client_t *client, isc
+@@ -1134,6 +1139,51 @@
  #endif
  
  	/*
@@ -26,8 +26,7 @@ diff -up bind-9.9.3rc2/bin/named/client.c.rl bind-9.9.3rc2/bin/named/client.c
 +
 +		INSIST(rcode != dns_rcode_noerror &&
 +		       rcode != dns_rcode_nxdomain);
-+		wouldlog = (ns_g_server->log_queries &&
-+			    isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP));
++		wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP);
 +		rrl_result = dns_rrl(client->view, &client->peeraddr,
 +				     TCP_CLIENT(client),
 +				     dns_rdataclass_in, dns_rdatatype_none,
@@ -41,18 +40,21 @@ diff -up bind-9.9.3rc2/bin/named/client.c.rl bind-9.9.3rc2/bin/named/client.c
 +			 * NS_LOGCATEGORY_RRL.
 +			 */
 +			if (wouldlog) {
-+				ns_client_log(client, NS_LOGCATEGORY_QUERIES,
++				ns_client_log(client,
++					      NS_LOGCATEGORY_QUERY_EERRORS,
 +					      NS_LOGMODULE_CLIENT,
 +					      DNS_RRL_LOG_DROP,
 +					      "%s", log_buf);
 +			}
 +			/*
 +			 * Some error responses cannot be 'slipped',
-+			 * so don't try.
-+			 * This will counted with dropped queries in the
-+			 * QryDropped counter.
++			 * so don't try to slip any error responses.
 +			 */
 +			if (!client->view->rrl->log_only) {
++				isc_stats_increment(ns_g_server->nsstats,
++						dns_nsstatscounter_ratedropped);
++				isc_stats_increment(ns_g_server->nsstats,
++						dns_nsstatscounter_dropped);
 +				ns_client_next(client, DNS_R_DROP);
 +				return;
 +			}
@@ -63,10 +65,10 @@ diff -up bind-9.9.3rc2/bin/named/client.c.rl bind-9.9.3rc2/bin/named/client.c
  	 * Message may be an in-progress reply that we had trouble
  	 * with, in which case QR will be set.  We need to clear QR before
  	 * calling dns_message_reply() to avoid triggering an assertion.
-diff -up bind-9.9.3rc2/bin/named/config.c.rl bind-9.9.3rc2/bin/named/config.c
---- bind-9.9.3rc2/bin/named/config.c.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/config.c	2013-05-13 12:30:38.625659408 +0200
-@@ -228,6 +228,13 @@ view \"_bind\" chaos {\n\
+diff -r -u bin/named/config.c-orig bin/named/config.c
+--- bin/named/config.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/config.c	2004-01-01 00:00:00.000000000 +0000
+@@ -228,6 +228,13 @@
  	notify no;\n\
  	allow-new-zones no;\n\
  \n\
@@ -80,10 +82,10 @@ diff -up bind-9.9.3rc2/bin/named/config.c.rl bind-9.9.3rc2/bin/named/config.c
  	zone \"version.bind\" chaos {\n\
  		type master;\n\
  		database \"_builtin version\";\n\
-diff -up bind-9.9.3rc2/bin/named/include/named/query.h.rl bind-9.9.3rc2/bin/named/include/named/query.h
---- bind-9.9.3rc2/bin/named/include/named/query.h.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/include/named/query.h	2013-05-13 12:30:38.625659408 +0200
-@@ -85,6 +85,7 @@ struct ns_query {
+diff -r -u bin/named/include/named/query.h-orig bin/named/include/named/query.h
+--- bin/named/include/named/query.h-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/include/named/query.h	2004-01-01 00:00:00.000000000 +0000
+@@ -85,6 +85,7 @@
  #define NS_QUERYATTR_CACHEACLOK		0x2000
  #define NS_QUERYATTR_DNS64		0x4000
  #define NS_QUERYATTR_DNS64EXCLUDE	0x8000
@@ -91,10 +93,10 @@ diff -up bind-9.9.3rc2/bin/named/include/named/query.h.rl bind-9.9.3rc2/bin/name
  
  
  isc_result_t
-diff -up bind-9.9.3rc2/bin/named/include/named/server.h.rl bind-9.9.3rc2/bin/named/include/named/server.h
---- bind-9.9.3rc2/bin/named/include/named/server.h.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/include/named/server.h	2013-05-13 12:30:38.626659408 +0200
-@@ -167,7 +167,10 @@ enum {
+diff -r -u bin/named/include/named/server.h-orig bin/named/include/named/server.h
+--- bin/named/include/named/server.h-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/include/named/server.h	2004-01-01 00:00:00.000000000 +0000
+@@ -167,7 +167,10 @@
  
  	dns_nsstatscounter_rpz_rewrites = 36,
  
@@ -106,23 +108,40 @@ diff -up bind-9.9.3rc2/bin/named/include/named/server.h.rl bind-9.9.3rc2/bin/nam
  };
  
  void
-diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
---- bind-9.9.3rc2/bin/named/query.c.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/query.c	2013-05-13 12:30:38.628659407 +0200
-@@ -5865,6 +5865,105 @@ query_find(ns_client_t *client, dns_fetc
+diff -r -u bin/named/query.c-orig bin/named/query.c
+--- bin/named/query.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/query.c	2004-01-01 00:00:00.000000000 +0000
+@@ -193,7 +193,7 @@
+ #ifdef NEWSTATS
+ 	/* Do query type statistics
+ 	 *
+-	 * We only increment per-type if we're using the authoriative
++	 * We only increment per-type if we're using the authoritative
+ 	 * answer counter, preventing double-counting.
+ 	 */
+ 	if (counter == dns_nsstatscounter_authans) {
+@@ -5865,6 +5865,128 @@
   resume:
  	CTRACE("query_find: resume");
  
 +	/*
 +	 * Rate limit these responses to this client.
++	 * Do not delay counting and handling obvious referrals,
++	 *	since those won't come here again.
++	 * Delay handling delegations for which we are certain to recurse and
++	 *	return here (DNS_R_DELEGATION, not a child of one of our
++	 *	own zones, and recursion enabled)
++	 * Count each response at most once.
 +	 */
 +	if (client->view->rrl != NULL &&
-+	    fname != NULL && dns_name_isabsolute(fname) &&
++	    ((fname != NULL && dns_name_isabsolute(fname)) ||
++	     (result == ISC_R_NOTFOUND && !RECURSIONOK(client))) &&
++	    !(result == DNS_R_DELEGATION && !is_zone && RECURSIONOK(client)) &&
 +	    (client->query.attributes & NS_QUERYATTR_RRL_CHECKED) == 0) {
 +		dns_rdataset_t nc_rdataset;
 +		isc_boolean_t wouldlog;
 +		char log_buf[DNS_RRL_LOG_BUF_LEN];
-+		isc_result_t nc_result;
++		isc_result_t nc_result, resp_result;
 +		dns_rrl_result_t rrl_result;
 +
 +		client->query.attributes |= NS_QUERYATTR_RRL_CHECKED;
@@ -135,7 +154,7 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
 +			 */
 +			if (db != NULL)
 +				tname = dns_db_origin(db);
-+			rrl_result = result;
++			resp_result = result;
 +		} else if (result == DNS_R_NCACHENXDOMAIN &&
 +			   rdataset != NULL &&
 +			   dns_rdataset_isassociated(rdataset) &&
@@ -159,17 +178,28 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
 +				}
 +				dns_rdataset_disassociate(&nc_rdataset);
 +			}
-+			rrl_result = DNS_R_NXDOMAIN;
++			resp_result = DNS_R_NXDOMAIN;
++		} else if (result == DNS_R_NXRRSET ||
++			   result == DNS_R_EMPTYNAME) {
++			resp_result = DNS_R_NXRRSET;
 +		} else if (result == DNS_R_DELEGATION) {
-+			rrl_result = result;
++			resp_result = result;
++		} else if (result == ISC_R_NOTFOUND) {
++			/*
++			 * Handle referral to ".", including when recursion
++			 * is off or not requested and the hints have not
++			 * been loaded or we have "additional-from-cache no".
++			 */
++			tname = dns_rootname;
++			resp_result = DNS_R_DELEGATION;
 +		} else {
-+			rrl_result = ISC_R_SUCCESS;
++			resp_result = ISC_R_SUCCESS;
 +		}
 +		rrl_result = dns_rrl(client->view, &client->peeraddr,
 +				     ISC_TF((client->attributes
 +					     & NS_CLIENTATTR_TCP) != 0),
 +				     client->message->rdclass, qtype, tname,
-+				     rrl_result, client->now,
++				     resp_result, client->now,
 +				     wouldlog, log_buf, sizeof(log_buf));
 +		if (rrl_result != DNS_RRL_RESULT_OK) {
 +			/*
@@ -182,9 +212,10 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
 +			 * in QryDropped while slipped responses are counted
 +			 * with other truncated responses in RespTruncated.
 +			 */
-+			if (wouldlog && ns_g_server->log_queries) {
-+				ns_client_log(client, NS_LOGCATEGORY_QUERIES,
-+					      NS_LOGMODULE_CLIENT,
++			if (wouldlog) {
++				ns_client_log(client,
++					      NS_LOGCATEGORY_QUERY_EERRORS,
++					      NS_LOGMODULE_QUERY,
 +					      DNS_RRL_LOG_DROP,
 +					      "%s", log_buf);
 +			}
@@ -206,6 +237,9 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
 +						dns_nsstatscounter_rateslipped);
 +					client->message->flags |=
 +						DNS_MESSAGEFLAG_TC;
++					if (resp_result == DNS_R_NXDOMAIN)
++						client->message->rcode =
++							dns_rcode_nxdomain;
 +				}
 +				goto cleanup;
 +			}
@@ -215,7 +249,7 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
  	if (!ISC_LIST_EMPTY(client->view->rpz_zones) &&
  	    (RECURSIONOK(client) || !client->view->rpz_recursive_only) &&
  	    rpz_ck_dnssec(client, result, rdataset, sigrdataset) &&
-@@ -7318,12 +7417,14 @@ query_find(ns_client_t *client, dns_fetc
+@@ -7318,12 +7440,14 @@
  	}
  
  	if (eresult != ISC_R_SUCCESS &&
@@ -233,14 +267,14 @@ diff -up bind-9.9.3rc2/bin/named/query.c.rl bind-9.9.3rc2/bin/named/query.c
  			 */
  			query_next(client, eresult);
  		} else {
-diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
---- bind-9.9.3rc2/bin/named/server.c.rl	2013-05-13 12:30:38.586659415 +0200
-+++ bind-9.9.3rc2/bin/named/server.c	2013-05-13 12:30:38.630659407 +0200
-@@ -1706,6 +1706,199 @@ configure_rpz(dns_view_t *view, const cf
+diff -r -u bin/named/server.c-orig bin/named/server.c
+--- bin/named/server.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/server.c	2004-01-01 00:00:00.000000000 +0000
+@@ -1639,6 +1639,168 @@
  	return (ISC_R_SUCCESS);
  }
  
-+#define CHECK_RRL(obj, cond, pat, val1, val2)				\
++#define CHECK_RRL(cond, pat, val1, val2)				\
 +	do {								\
 +		if (!(cond)) {						\
 +			cfg_obj_log(obj, ns_g_lctx, ISC_LOG_ERROR,	\
@@ -250,6 +284,22 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
 +		    }							\
 +	} while (0)
 +
++#define CHECK_RRL_RATE(rate, def, max_rate, name)			\
++	do {								\
++		obj = NULL;						\
++		rrl->rate.str = name;					\
++		result = cfg_map_get(map, name, &obj);			\
++		if (result == ISC_R_SUCCESS) {				\
++			rrl->rate.r = cfg_obj_asuint32(obj);		\
++			CHECK_RRL(rrl->rate.r <= max_rate,		\
++				  name" %d > %d",			\
++				  rrl->rate.r, max_rate);		\
++		} else {						\
++			rrl->rate.r = def;				\
++		}							\
++		rrl->rate.scaled = rrl->rate.r;				\
++	} while (0)
++
 +static isc_result_t
 +configure_rrl(dns_view_t *view, const cfg_obj_t *config, const cfg_obj_t *map) {
 +	const cfg_obj_t *obj;
@@ -280,86 +330,39 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
 +	result = cfg_map_get(map, "max-table-size", &obj);
 +	if (result == ISC_R_SUCCESS) {
 +		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i >= min_entries,
++		CHECK_RRL(i >= min_entries,
 +			  "max-table-size %d < min-table-size %d",
 +			  i, min_entries);
 +	}
 +	rrl->max_entries = i;
 +
-+	i = 0;
-+	obj = NULL;
-+	result = cfg_map_get(map, "responses-per-second", &obj);
-+	if (result == ISC_R_SUCCESS) {
-+		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i <= DNS_RRL_MAX_RATE,
-+			  "responses-per-second %d > %d",
-+			  i, DNS_RRL_MAX_RATE);
-+	}
-+	rrl->responses_per_second = i;
-+	rrl->scaled_responses_per_second = rrl->responses_per_second;
-+
-+	/*
-+	 * The default error rate is the response rate,
-+	 * and so off by default.
-+	 */
-+	i = rrl->responses_per_second;
-+	obj = NULL;
-+	result = cfg_map_get(map, "errors-per-second", &obj);
-+	if (result == ISC_R_SUCCESS) {
-+		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i <= DNS_RRL_MAX_RATE,
-+			  "errors-per-second %d > %d",
-+			  i, DNS_RRL_MAX_RATE);
-+	}
-+	rrl->errors_per_second = i;
-+	rrl->scaled_errors_per_second = rrl->errors_per_second;
-+	/*
-+	 * The default NXDOMAIN rate is the response rate,
-+	 * and so off by default.
-+	 */
-+	i = rrl->responses_per_second;
-+	obj = NULL;
-+	result = cfg_map_get(map, "nxdomains-per-second", &obj);
-+	if (result == ISC_R_SUCCESS) {
-+		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i <= DNS_RRL_MAX_RATE,
-+			  "nxdomains-per-second %d > %d",
-+			  i, DNS_RRL_MAX_RATE);
-+	}
-+	rrl->nxdomains_per_second = i;
-+	rrl->scaled_nxdomains_per_second = rrl->nxdomains_per_second;
-+
-+	/*
-+	 * The all-per-second rate is off by default.
-+	 */
-+	i = 0;
-+	obj = NULL;
-+	result = cfg_map_get(map, "all-per-second", &obj);
-+	if (result == ISC_R_SUCCESS) {
-+		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i <= DNS_RRL_MAX_RATE, "all-per-second %d > %d",
-+			  i, DNS_RRL_MAX_RATE);
-+	}
-+	rrl->all_per_second = i;
-+	rrl->scaled_all_per_second = rrl->all_per_second;
-+
-+	i = 2;
-+	obj = NULL;
-+	result = cfg_map_get(map, "slip", &obj);
-+	if (result == ISC_R_SUCCESS) {
-+		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i <= DNS_RRL_MAX_SLIP,
-+			  "slip %d > %d", i, DNS_RRL_MAX_SLIP);
-+	}
-+	rrl->slip = i;
-+	rrl->scaled_slip = rrl->slip;
++	CHECK_RRL_RATE(responses_per_second, 0, DNS_RRL_MAX_RATE,
++		       "responses-per-second");
++	CHECK_RRL_RATE(referrals_per_second,
++		       rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
++		       "referrals-per-second");
++	CHECK_RRL_RATE(nodata_per_second,
++		       rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
++		       "nodata-per-second");
++	CHECK_RRL_RATE(nxdomains_per_second,
++		       rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
++		       "nxdomains-per-second");
++	CHECK_RRL_RATE(errors_per_second,
++		       rrl->responses_per_second.r, DNS_RRL_MAX_RATE,
++		       "errors-per-second");
++
++	CHECK_RRL_RATE(all_per_second, 0, DNS_RRL_MAX_RATE,
++		       "all-per-second");
++
++	CHECK_RRL_RATE(slip, 2, DNS_RRL_MAX_SLIP,
++		       "slip");
 +
 +	i = 15;
 +	obj = NULL;
 +	result = cfg_map_get(map, "window", &obj);
 +	if (result == ISC_R_SUCCESS) {
 +		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i >= 1 && i <= DNS_RRL_MAX_WINDOW,
++		CHECK_RRL(i >= 1 && i <= DNS_RRL_MAX_WINDOW,
 +			  "window %d < 1 or > %d", i, DNS_RRL_MAX_WINDOW);
 +	}
 +	rrl->window = i;
@@ -369,18 +372,18 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
 +	result = cfg_map_get(map, "qps-scale", &obj);
 +	if (result == ISC_R_SUCCESS) {
 +		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i >= 1, "invalid 'qps-scale %d'%s", i, "");
++		CHECK_RRL(i >= 1, "invalid 'qps-scale %d'%s", i, "");
 +	}
 +	rrl->qps_scale = i;
 +	rrl->qps = 1.0;
 +
 +	i = 24;
 +	obj = NULL;
-+	result = cfg_map_get(map, "IPv4-prefix-length", &obj);
++	result = cfg_map_get(map, "ipv4-prefix-length", &obj);
 +	if (result == ISC_R_SUCCESS) {
 +		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i >= 8 && i <= 32,
-+			  "invalid 'IPv4-prefix-length %d'%s", i, "");
++		CHECK_RRL(i >= 8 && i <= 32,
++			  "invalid 'ipv4-prefix-length %d'%s", i, "");
 +	}
 +	rrl->ipv4_prefixlen = i;
 +	if (i == 32)
@@ -390,11 +393,11 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
 +
 +	i = 56;
 +	obj = NULL;
-+	result = cfg_map_get(map, "IPv6-prefix-length", &obj);
++	result = cfg_map_get(map, "ipv6-prefix-length", &obj);
 +	if (result == ISC_R_SUCCESS) {
 +		i = cfg_obj_asuint32(obj);
-+		CHECK_RRL(obj, i >= 16 && i <= DNS_RRL_MAX_PREFIX,
-+			  "IPv6-prefix-length %d < 16 or > %d",
++		CHECK_RRL(i >= 16 && i <= DNS_RRL_MAX_PREFIX,
++			  "ipv6-prefix-length %d < 16 or > %d",
 +			  i, DNS_RRL_MAX_PREFIX);
 +	}
 +	rrl->ipv6_prefixlen = i;
@@ -415,7 +418,7 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
 +		result = cfg_acl_fromconfig(obj, config, ns_g_lctx,
 +					    ns_g_aclconfctx, ns_g_mctx,
 +					    0, &rrl->exempt);
-+		CHECK_RRL(obj, result == ISC_R_SUCCESS,
++		CHECK_RRL(result == ISC_R_SUCCESS,
 +			  "invalid %s%s", "address match list", "");
 +	}
 +
@@ -436,7 +439,7 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
  /*
   * Configure 'view' according to 'vconfig', taking defaults from 'config'
   * where values are missing in 'vconfig'.
-@@ -3144,6 +3337,14 @@ configure_view(dns_view_t *view, cfg_obj
+@@ -3043,6 +3205,14 @@
  		}
  	}
  
@@ -451,10 +454,10 @@ diff -up bind-9.9.3rc2/bin/named/server.c.rl bind-9.9.3rc2/bin/named/server.c
  	result = ISC_R_SUCCESS;
  
   cleanup:
-diff -up bind-9.9.3rc2/bin/named/statschannel.c.rl bind-9.9.3rc2/bin/named/statschannel.c
---- bind-9.9.3rc2/bin/named/statschannel.c.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/named/statschannel.c	2013-05-13 12:30:38.630659407 +0200
-@@ -206,6 +206,10 @@ init_desc(void) {
+diff -r -u bin/named/statschannel.c-orig bin/named/statschannel.c
+--- bin/named/statschannel.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/named/statschannel.c	2004-01-01 00:00:00.000000000 +0000
+@@ -206,6 +206,10 @@
  	SET_NSSTATDESC(updatebadprereq,
  		       "updates rejected due to prerequisite failure",
  		       "UpdateBadPrereq");
@@ -465,10 +468,21 @@ diff -up bind-9.9.3rc2/bin/named/statschannel.c.rl bind-9.9.3rc2/bin/named/stats
  	SET_NSSTATDESC(rpz_rewrites, "response policy zone rewrites",
  		       "RPZRewrites");
  	INSIST(i == dns_nsstatscounter_max);
-diff -up bind-9.9.3rc2/bin/tests/system/conf.sh.in.rl bind-9.9.3rc2/bin/tests/system/conf.sh.in
---- bind-9.9.3rc2/bin/tests/system/conf.sh.in.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/tests/system/conf.sh.in	2013-05-13 12:36:29.878601499 +0200
-@@ -62,7 +62,7 @@ SUBDIRS="acl additional allow_query addz
+diff -r -u bin/tests/system/README-orig bin/tests/system/README
+--- bin/tests/system/README-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/README	2004-01-01 00:00:00.000000000 +0000
+@@ -17,6 +17,7 @@
+   nsupdate/	Dynamic update and IXFR tests
+   resolver/     Regression tests for resolver bugs that have been fixed
+ 		(not a complete resolver test suite)
++  rrl/		query rate limiting
+   rpz/		Tests of response policy zone (RPZ) rewriting
+   stub/		Tests of stub zone functionality
+   unknown/	Unknown type and class tests
+diff -r -u bin/tests/system/conf.sh.in-orig bin/tests/system/conf.sh.in
+--- bin/tests/system/conf.sh.in-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/conf.sh.in	2004-01-01 00:00:00.000000000 +0000
+@@ -62,7 +62,7 @@
           database dlv dlvauto dlz dlzexternal dname dns64 dnssec ecdsa
           formerr forward glue gost ixfr inline limits logfileconfig
           lwresd masterfile masterformat metadata notify nsupdate pending
@@ -477,20 +491,9 @@ diff -up bind-9.9.3rc2/bin/tests/system/conf.sh.in.rl bind-9.9.3rc2/bin/tests/sy
  	 smartsign sortlist spf staticstub stub tkey tsig tsiggss unknown
  	 upforwd verify views wildcard xfer xferquota zonechecks"
  
-diff -up bind-9.9.3rc2/bin/tests/system/README.rl bind-9.9.3rc2/bin/tests/system/README
---- bind-9.9.3rc2/bin/tests/system/README.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/bin/tests/system/README	2013-05-13 12:30:38.630659407 +0200
-@@ -17,6 +17,7 @@ involving a different DNS setup.  They a
-   nsupdate/	Dynamic update and IXFR tests
-   resolver/     Regression tests for resolver bugs that have been fixed
- 		(not a complete resolver test suite)
-+  rrl/		query rate limiting
-   rpz/		Tests of response policy zone (RPZ) rewriting
-   stub/		Tests of stub zone functionality
-   unknown/	Unknown type and class tests
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/clean.sh.rl bind-9.9.3rc2/bin/tests/system/rrl/clean.sh
---- bind-9.9.3rc2/bin/tests/system/rrl/clean.sh.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/clean.sh	2013-05-13 12:30:38.631659407 +0200
+diff -r -u bin/tests/system/rrl/clean.sh-orig bin/tests/system/rrl/clean.sh
+--- bin/tests/system/rrl/clean.sh-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/clean.sh	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,21 @@
 +# Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +#
@@ -511,11 +514,11 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/clean.sh.rl bind-9.9.3rc2/bin/tests/
 +# Clean up after rrl tests.
 +
 +rm -f dig.out*
-+rm -f  */named.memstats */named.run */named.stats */log */session.key
++rm -f  */named.memstats */named.run */named.stats */log-* */session.key
 +rm -f ns3/bl*.db */*.jnl */*.core */*.pid
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns1/named.conf.rl bind-9.9.3rc2/bin/tests/system/rrl/ns1/named.conf
---- bind-9.9.3rc2/bin/tests/system/rrl/ns1/named.conf.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns1/named.conf	2013-05-13 12:30:38.631659407 +0200
+diff -r -u bin/tests/system/rrl/ns1/named.conf-orig bin/tests/system/rrl/ns1/named.conf
+--- bin/tests/system/rrl/ns1/named.conf-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns1/named.conf	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,32 @@
 +/*
 + * Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
@@ -549,9 +552,9 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns1/named.conf.rl bind-9.9.3rc2/bin/
 +};
 +
 +zone "." {type master; file "root.db";};
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns1/root.db.rl bind-9.9.3rc2/bin/tests/system/rrl/ns1/root.db
---- bind-9.9.3rc2/bin/tests/system/rrl/ns1/root.db.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns1/root.db	2013-05-13 12:30:38.631659407 +0200
+diff -r -u bin/tests/system/rrl/ns1/root.db-orig bin/tests/system/rrl/ns1/root.db
+--- bin/tests/system/rrl/ns1/root.db-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns1/root.db	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,31 @@
 +; Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +;
@@ -584,9 +587,9 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns1/root.db.rl bind-9.9.3rc2/bin/tes
 +
 +; generate SERVFAIL
 +tld4.		NS	ns.tld3.
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/hints.rl bind-9.9.3rc2/bin/tests/system/rrl/ns2/hints
---- bind-9.9.3rc2/bin/tests/system/rrl/ns2/hints.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns2/hints	2013-05-13 12:30:38.631659407 +0200
+diff -r -u bin/tests/system/rrl/ns2/hints-orig bin/tests/system/rrl/ns2/hints
+--- bin/tests/system/rrl/ns2/hints-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns2/hints	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,18 @@
 +; Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +;
@@ -606,10 +609,10 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/hints.rl bind-9.9.3rc2/bin/tests
 +
 +.	0	NS	ns1.
 +ns1.	0	A	10.53.0.1
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf.rl bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf
---- bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf	2013-05-13 12:30:38.631659407 +0200
-@@ -0,0 +1,72 @@
+diff -r -u bin/tests/system/rrl/ns2/named.conf-orig bin/tests/system/rrl/ns2/named.conf
+--- bin/tests/system/rrl/ns2/named.conf-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns2/named.conf	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,71 @@
 +/*
 + * Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 + *
@@ -643,16 +646,15 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf.rl bind-9.9.3rc2/bin/
 +
 +	rate-limit {
 +	    responses-per-second 2;
-+	    all-per-second 70;
-+	    IPv4-prefix-length 24;
-+	    IPv6-prefix-length 64;
++	    all-per-second 50;
 +	    slip 3;
-+	    /* qps-scale 2; */
 +	    exempt-clients { 10.53.0.7; };
-+	    window 1;
-+	    max-table-size 100;
-+	    min-table-size 2;
++
++	    // small enough to force a table expansion
++	    min-table-size 75;
 +	};
++
++	additional-from-cache no;
 +};
 +
 +key rndc_key {
@@ -682,10 +684,10 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/named.conf.rl bind-9.9.3rc2/bin/
 +zone "." { type hint; file "hints"; };
 +
 +zone "tld2."{ type master; file "tld2.db"; };
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db.rl bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db
---- bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db.rl	2013-05-13 12:30:38.631659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db	2013-05-13 12:30:38.631659407 +0200
-@@ -0,0 +1,42 @@
+diff -r -u bin/tests/system/rrl/ns2/tld2.db-orig bin/tests/system/rrl/ns2/tld2.db
+--- bin/tests/system/rrl/ns2/tld2.db-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns2/tld2.db	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,47 @@
 +; Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +;
 +; Permission to use, copy, modify, and/or distribute this software for any
@@ -710,8 +712,10 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db.rl bind-9.9.3rc2/bin/tes
 +		NS	.
 +ns		A	10.53.0.2
 +
++; basic rate limiting
 +a1		A	192.0.2.1
 +
++; wildcards
 +*.a2		A	192.0.2.2
 +
 +; a3 is in tld3
@@ -726,11 +730,14 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns2/tld2.db.rl bind-9.9.3rc2/bin/tes
 +
 +; a7 for SERVFAIL
 +
-+; a8 for all-per-second limit
-+$GENERATE 101-180 all$.a8 A 192.0.2.8
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/hints.rl bind-9.9.3rc2/bin/tests/system/rrl/ns3/hints
---- bind-9.9.3rc2/bin/tests/system/rrl/ns3/hints.rl	2013-05-13 12:30:38.632659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns3/hints	2013-05-13 12:30:38.632659407 +0200
++; a8 for NODATA
++a8		A	192.0.2.8
++
++; a9 for all-per-second limit
++$GENERATE 101-180 all$.a9 A 192.0.2.8
+diff -r -u bin/tests/system/rrl/ns3/hints-orig bin/tests/system/rrl/ns3/hints
+--- bin/tests/system/rrl/ns3/hints-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns3/hints	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,18 @@
 +; Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +;
@@ -750,10 +757,10 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/hints.rl bind-9.9.3rc2/bin/tests
 +
 +.	0	NS	ns1.
 +ns1.	0	A	10.53.0.1
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/named.conf.rl bind-9.9.3rc2/bin/tests/system/rrl/ns3/named.conf
---- bind-9.9.3rc2/bin/tests/system/rrl/ns3/named.conf.rl	2013-05-13 12:30:38.632659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns3/named.conf	2013-05-13 12:30:38.632659407 +0200
-@@ -0,0 +1,34 @@
+diff -r -u bin/tests/system/rrl/ns3/named.conf-orig bin/tests/system/rrl/ns3/named.conf
+--- bin/tests/system/rrl/ns3/named.conf-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns3/named.conf	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,50 @@
 +/*
 + * Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 + *
@@ -783,14 +790,30 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/named.conf.rl bind-9.9.3rc2/bin/
 +	listen-on { 10.53.0.3; };
 +	listen-on-v6 { none; };
 +	notify no;
++
++	// check that all of the options are parsed without limiting anything
++	rate-limit {
++	    responses-per-second 200;
++	    referrals-per-second 220;
++	    nodata-per-second 230;
++	    nxdomains-per-second 240;
++	    errors-per-second 250;
++	    all-per-second 700;
++	    ipv4-prefix-length 24;
++	    ipv6-prefix-length 64;
++	    qps-scale 10;
++	    window 1;
++	    max-table-size 1000;
++	};
++
 +};
 +
 +zone "." { type hint; file "hints"; };
 +
 +zone "tld3."{ type master; file "tld3.db"; };
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/tld3.db.rl bind-9.9.3rc2/bin/tests/system/rrl/ns3/tld3.db
---- bind-9.9.3rc2/bin/tests/system/rrl/ns3/tld3.db.rl	2013-05-13 12:30:38.632659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/ns3/tld3.db	2013-05-13 12:30:38.632659407 +0200
+diff -r -u bin/tests/system/rrl/ns3/tld3.db-orig bin/tests/system/rrl/ns3/tld3.db
+--- bin/tests/system/rrl/ns3/tld3.db-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/ns3/tld3.db	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,25 @@
 +; Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +;
@@ -817,9 +840,9 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/ns3/tld3.db.rl bind-9.9.3rc2/bin/tes
 +ns		A	10.53.0.3
 +
 +*.a3		A	192.0.3.3
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/setup.sh.rl bind-9.9.3rc2/bin/tests/system/rrl/setup.sh
---- bind-9.9.3rc2/bin/tests/system/rrl/setup.sh.rl	2013-05-13 12:30:38.632659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/setup.sh	2013-05-13 12:30:38.632659407 +0200
+diff -r -u bin/tests/system/rrl/setup.sh-orig bin/tests/system/rrl/setup.sh
+--- bin/tests/system/rrl/setup.sh-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/setup.sh	2004-01-01 00:00:00.000000000 +0000
 @@ -0,0 +1,21 @@
 +#!/bin/sh
 +#
@@ -842,10 +865,10 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/setup.sh.rl bind-9.9.3rc2/bin/tests/
 +. $SYSTEMTESTTOP/conf.sh
 +. ./clean.sh
 +
-diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/system/rrl/tests.sh
---- bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl	2013-05-13 12:30:38.632659407 +0200
-+++ bind-9.9.3rc2/bin/tests/system/rrl/tests.sh	2013-05-13 12:30:38.632659407 +0200
-@@ -0,0 +1,225 @@
+diff -r -u bin/tests/system/rrl/tests.sh-orig bin/tests/system/rrl/tests.sh
+--- bin/tests/system/rrl/tests.sh-orig	2004-01-01 00:00:00.000000000 +0000
++++ bin/tests/system/rrl/tests.sh	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,258 @@
 +# Copyright (C) 2012, 2013  Internet Systems Consortium, Inc. ("ISC")
 +#
 +# Permission to use, copy, modify, and/or distribute this software for any
@@ -867,7 +890,6 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/
 +. $SYSTEMTESTTOP/conf.sh
 +
 +#set -x
-+#set -o noclobber
 +
 +ns1=10.53.0.1			    # root, defining the others
 +ns2=10.53.0.2			    # test server
@@ -912,15 +934,20 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/
 +}
 +
 +
++# turn off ${HOME}/.digrc
++HOME=/dev/null; export HOME
++
 +#   $1=result name  $2=domain name  $3=dig options
 +digcmd () {
 +    OFILE=$1; shift
 +    DIG_DOM=$1; shift
-+    ARGS="+noadd +noauth +nosearch +time=1 +tries=1 +ignore $* -p 5300 $DIG_DOM @$ns2"
++    ARGS="+nosearch +time=1 +tries=1 +ignore -p 5300 $* $DIG_DOM @$ns2"
 +    #echo I:dig $ARGS 1>&2
 +    START=`date +%y%m%d%H%M.%S`
 +    RESULT=`$DIG $ARGS 2>&1 | tee $OFILE=TEMP				\
-+	    | sed -n -e  's/^[^;].*	\([^	 ]\{1,\}\)$/\1/p'	\
++	    | sed -n -e '/^;; AUTHORITY/,/^$/d'				\
++		-e '/^;; ADDITIONAL/,/^$/d'				\
++		-e  's/^[^;].*	\([^	 ]\{1,\}\)$/\1/p'		\
 +		-e 's/;; flags.* tc .*/TC/p'				\
 +		-e 's/;; .* status: NXDOMAIN.*/NXDOMAIN/p'		\
 +		-e 's/;; .* status: SERVFAIL.*/SERVFAIL/p'		\
@@ -933,22 +960,16 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/
 +
 +
 +#   $1=number of tests  $2=target domain  $3=dig options
-+CNT=1
++QNUM=1
 +burst () {
 +    BURST_LIMIT=$1; shift
 +    BURST_DOM_BASE="$1"; shift
 +    while test "$BURST_LIMIT" -ge 1; do
-+	if test $CNT -lt 10; then
-+	    CNT="00$CNT"
-+	else
-+	    if test $CNT -lt 100; then
-+		CNT="0$CNT"
-+	    fi
-+	fi
++	CNT=`expr "00$QNUM" : '.*\(...\)'`
 +	eval BURST_DOM="$BURST_DOM_BASE"
 +	FILE="dig.out-$BURST_DOM-$CNT"
 +	digcmd $FILE $BURST_DOM $* &
-+	CNT=`expr $CNT + 1`
++	QNUM=`expr $QNUM + 1`
 +	BURST_LIMIT=`expr "$BURST_LIMIT" - 1`
 +    done
 +}
@@ -959,29 +980,32 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/
 +ck_result() {
 +    BAD=
 +    wait
-+    ADDRS=`ls dig.out-$1-*=$2		2>/dev/null	| wc -l | tr -d ' '`
-+    TC=`ls dig.out-$1-*=TC		2>/dev/null	| wc -l | tr -d ' '`
-+    DROP=`ls dig.out-$1-*=drop		2>/dev/null	| wc -l | tr -d ' '`
-+    NXDOMAIN=`ls dig.out-$1-*=NXDOMAIN	2>/dev/null	| wc -l | tr -d ' '`
-+    SERVFAIL=`ls dig.out-$1-*=SERVFAIL	2>/dev/null	| wc -l | tr -d ' '`
++    ADDRS=`ls dig.out-$1-*=$2				2>/dev/null | wc -l`
++    # count simple truncated and truncated NXDOMAIN as TC
++    TC=`ls dig.out-$1-*=TC dig.out-$1-*=NXDOMAINTC	2>/dev/null | wc -l`
++    DROP=`ls dig.out-$1-*=drop				2>/dev/null | wc -l`
++    # count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN
++    NXDOMAIN=`ls dig.out-$1-*=NXDOMAIN  dig.out-$1-*=NXDOMAINTC	2>/dev/null \
++							| wc -l`
++    SERVFAIL=`ls dig.out-$1-*=SERVFAIL			2>/dev/null | wc -l`
 +    if test $ADDRS -ne "$3"; then
-+	setret "I:$ADDRS instead of $3 $2 responses for $1"
++	setret "I:"$ADDRS" instead of $3 '$2' responses for $1"
 +	BAD=yes
 +    fi
 +    if test $TC -ne "$4"; then
-+	setret "I:$TC instead of $4 truncation responses for $1"
++	setret "I:"$TC" instead of $4 truncation responses for $1"
 +	BAD=yes
 +    fi
 +    if test $DROP -ne "$5"; then
-+	setret "I:$DROP instead of $5 dropped responses for $1"
++	setret "I:"$DROP" instead of $5 dropped responses for $1"
 +	BAD=yes
 +    fi
 +    if test $NXDOMAIN -ne "$6"; then
-+	setret "I:$NXDOMAIN instead of $6 NXDOMAIN responses for $1"
++	setret "I:"$NXDOMAIN" instead of $6 NXDOMAIN responses for $1"
 +	BAD=yes
 +    fi
 +    if test $SERVFAIL -ne "$7"; then
-+	setret "I:$SERVFAIL instead of $7 error responses for $1"
++	setret "I:"$SERVFAIL" instead of $7 error responses for $1"
 +	BAD=yes
 +    fi
 +    if test -z "$BAD"; then
@@ -990,91 +1014,123 @@ diff -up bind-9.9.3rc2/bin/tests/system/rrl/tests.sh.rl bind-9.9.3rc2/bin/tests/
 +}
 +
 +
++ckstats () {
++    LABEL="$1"; shift
++    TYPE="$1"; shift
++    EXPECTED="$1"; shift
++    C=`sed -n -e "s/[	 ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p"  \
++	    ns2/named.stats | tail -1`
++    C=`expr 0$C + 0`
++    if test "$C" -ne $EXPECTED; then
++	setret "I:wrong $LABEL $TYPE statistics of $C instead of $EXPECTED"
++    fi
++}
++
++
 +#########
 +sec_start
 +
++# Tests of referrals to "." must be done before the hints are loaded
++#   or with "additional-from-cache no"
++burst 5 a1.tld3 +norec
 +# basic rate limiting
 +burst 3 a1.tld2
 +# 1 second delay allows an additional response.
 +sleep 1
-+burst 21 a1.tld2
-+# request 30 different qnames to try a wild card
++burst 10 a1.tld2
++# Request 30 different qnames to try a wildcard.
 +burst 30 'x$CNT.a2.tld2'
++# These should be counted and limited but are not.  See RT33138.
++burst 10 'y.x$CNT.a2.tld2'
 +
 +#					IP      TC      drop  NXDOMAIN SERVFAIL
-+# check for 24 results
-+# including the 1 second delay
-+ck_result   a1.tld2	192.0.2.1	3	7	14	0	0
++# referrals to "."
++ck_result   a1.tld3	''		2	1	2	0	0
++# check 13 results including 1 second delay that allows an additional response
++ck_result   a1.tld2	192.0.2.1	3	4	6	0	0
 +
 +# Check the wild card answers.
 +# The parent name of the 30 requests is counted.
 +ck_result 'x*.a2.tld2'	192.0.2.2	2	10	18	0	0
 +
++# These should be limited but are not.  See RT33138.
++ck_result 'y.x*.a2.tld2' 192.0.2.2	10	0	0	0	0
 +
 +#########
 +sec_start
 +
-+burst 1 'y$CNT.a3.tld3'; wait; burst 20 'y$CNT.a3.tld3'
-+burst 20 'z$CNT.a4.tld2'
++burst 10 'x.a3.tld3'
++burst 10 'y$CNT.a3.tld3'
++burst 10 'z$CNT.a4.tld2'
++
++# 10 identical recursive responses are limited
++ck_result 'x.a3.tld3'	192.0.3.3	2	3	5	0	0
 +
-+# Recursion.
-+#   The first answer is counted separately because it is counted against
-+#   the rate limit on recursing to the server for a3.tld3.  The remaining 20
-+#   are counted as local responses from the cache.
-+ck_result 'y*.a3.tld3'	192.0.3.3	3	6	12	0	0
++# 10 different recursive responses are not limited
++ck_result 'y*.a3.tld3'	192.0.3.3	10	0	0	0	0
 +
-+# NXDOMAIN responses are also limited based on the parent name.
-+ck_result 'z*.a4.tld2'	x		0	6	12	2	0
++# 10 different NXDOMAIN responses are limited based on the parent name.
++#   We count 13 responses because we count truncated NXDOMAIN responses
++#   as both truncated and NXDOMAIN.
++ck_result 'z*.a4.tld2'	x		0	3	5	5	0
++
++$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
++ckstats first dropped 36
++ckstats first truncated 21
 +
 +
 +#########
 +sec_start
 +
-+burst 20 a5.tld2 +tcp
-+burst 20 a6.tld2 -b $ns7
-+burst 20 a7.tld4
++burst 10 a5.tld2 +tcp
++burst 10 a6.tld2 -b $ns7
++burst 10 a7.tld4
++burst 2 a8.tld2 AAAA
++burst 2 a8.tld2 TXT
++burst 2 a8.tld2 SPF
 +
++#					IP      TC      drop  NXDOMAIN SERVFAIL
 +# TCP responses are not rate limited
-+ck_result a5.tld2	192.0.2.5	20	0	0	0	0
++ck_result a5.tld2	192.0.2.5	10	0	0	0	0
 +
 +# whitelisted client is not rate limited
-+ck_result a6.tld2	192.0.2.6	20	0	0	0	0
++ck_result a6.tld2	192.0.2.6	10	0	0	0	0
++
++# Errors such as SERVFAIL are rate limited.
++ck_result a7.tld4	x		0	0	8	0	2
++
++# NODATA responses are counted as the same regardless of qtype.
++ck_result a8.tld2	''		2	2	2	0	0
 +
-+# Errors such as SERVFAIL are rate limited.  The numbers are confusing, because
-+#   other rate limiting can be triggered before the SERVFAIL limit is reached.
-+ck_result a7.tld4	192.0.2.1	0	6	12	0	2
++$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
++ckstats second dropped 46
++ckstats second truncated 23
 +
 +
 +#########
 +sec_start
 +
++#					IP      TC      drop  NXDOMAIN SERVFAIL
 +# all-per-second
 +#   The qnames are all unique but the client IP address is constant.
-+CNT=101
-+burst 80 'all$CNT.a8.tld2'
-+ck_result 'a*.a8.tld2'	192.0.2.8	70	0	10	0	0
++QNUM=101
++burst 60 'all$CNT.a9.tld2'
 +
++ck_result 'a*.a9.tld2'	192.0.2.8	50	0	10	0	0
 +
 +$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats
-+ckstats () {
-+    CNT=`sed -n -e "s/[	 ]*\([0-9]*\).responses $1 for rate limits.*/\1/p"  \
-+		ns2/named.stats`
-+    CNT=`expr 0$CNT + 0`
-+    if test "$CNT" -ne $2; then
-+	setret "I:wrong $1 statistics of $CNT instead of $2"
-+    fi
-+}
-+ckstats dropped 77
-+ckstats truncated 35
++ckstats final dropped 56
++ckstats final truncated 23
++
 +
 +echo "I:exit status: $ret"
 +# exit $ret
 +[ $ret -ne 0 ] && echo "I:test failure overridden"
 +exit 0
-diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml
---- bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml	2013-05-13 12:30:38.635659407 +0200
-@@ -4818,6 +4818,34 @@ category notify { null; };
+diff -r -u doc/arm/Bv9ARM-book.xml-orig doc/arm/Bv9ARM-book.xml
+--- doc/arm/Bv9ARM-book.xml-orig	2004-01-01 00:00:00.000000000 +0000
++++ doc/arm/Bv9ARM-book.xml	2004-01-01 00:00:00.000000000 +0000
+@@ -4818,6 +4818,32 @@
  		    </para>
  		  </entry>
  		</row>
@@ -1100,29 +1156,38 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
 +		    </para>
 +		    <para>
 +		      Rate limiting of individual requests
-+		      is logged in the <command>queries</command> category
-+		      and can be controlled with the
-+		      <command>querylog</command> option.
++		      is logged in the <command>query-errors</command> category.
 +		    </para>
 +		  </entry>
 +		</row>
  	      </tbody>
  	    </tgroup>
  	  </informaltable>
-@@ -5351,6 +5379,21 @@ badresp:1,adberr:0,findfail:0,valfail:0]
+@@ -5318,7 +5344,7 @@
+     <optional> match-mapped-addresses <replaceable>yes_or_no</replaceable>; </optional>
+     <optional> filter-aaaa-on-v4 ( <replaceable>yes_or_no</replaceable> | <replaceable>break-dnssec</replaceable> ); </optional>
+     <optional> filter-aaaa { <replaceable>address_match_list</replaceable> }; </optional>
+-    <optional> dns64 <replaceable>IPv6-prefix</replaceable> {
++    <optional> dns64 <replaceable>ipv6-prefix</replaceable> {
+ 	<optional> clients { <replaceable>address_match_list</replaceable> }; </optional>
+ 	<optional> mapped { <replaceable>address_match_list</replaceable> }; </optional>
+         <optional> exclude { <replaceable>address_match_list</replaceable> }; </optional>
+@@ -5351,6 +5377,23 @@
      <optional> resolver-query-timeout <replaceable>number</replaceable> ; </optional>
      <optional> deny-answer-addresses { <replaceable>address_match_list</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
      <optional> deny-answer-aliases { <replaceable>namelist</replaceable> } <optional> except-from { <replaceable>namelist</replaceable> } </optional>;</optional>
 +    <optional> rate-limit {
 +	<optional> responses-per-second <replaceable>number</replaceable> ; </optional>
-+	<optional> errors-per-second <replaceable>number</replaceable> ; </optional>
++	<optional> referrals-per-second <replaceable>number</replaceable> ; </optional>
++	<optional> nodata-per-second <replaceable>number</replaceable> ; </optional>
 +	<optional> nxdomains-per-second <replaceable>number</replaceable> ; </optional>
++	<optional> errors-per-second <replaceable>number</replaceable> ; </optional>
 +	<optional> all-per-second <replaceable>number</replaceable> ; </optional>
 +	<optional> window <replaceable>number</replaceable> ; </optional>
 +	<optional> log-only <replaceable>yes_or_no</replaceable> ; </optional>
 +	<optional> qps-scale <replaceable>number</replaceable> ; </optional>
-+	<optional> IPv4-prefix-length <replaceable>number</replaceable> ; </optional>
-+	<optional> IPv6-prefix-length <replaceable>number</replaceable> ; </optional>
++	<optional> ipv4-prefix-length <replaceable>number</replaceable> ; </optional>
++	<optional> ipv6-prefix-length <replaceable>number</replaceable> ; </optional>
 +	<optional> slip <replaceable>number</replaceable> ; </optional>
 +	<optional> exempt-clients  { <replaceable>address_match_list</replaceable> } ; </optional>
 +	<optional> max-table-size <replaceable>number</replaceable> ; </optional>
@@ -1131,100 +1196,107 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
      <optional> response-policy { <replaceable>zone_name</replaceable>
  	<optional> policy given | disabled | passthru | nxdomain | nodata | cname <replaceable>domain</replaceable> </optional>
  	<optional> recursive-only <replaceable>yes_or_no</replaceable> </optional> <optional> max-policy-ttl <replaceable>number</replaceable> </optional> ;
-@@ -9896,6 +9939,215 @@ ns.domain.com.rpz-nsdname   CNAME   .
+@@ -9897,6 +9940,223 @@
              <command>RPZRewrites</command> statistics.
            </para>
          </sect3>
 +
 +	<sect3>
-+	  <title>Rate Limiting</title>
++	  <title>Response Rate Limiting</title>
 +	  <para>
-+	    Excessive essentially identical UDP <emphasis>responses</emphasis>
-+	    can be discarded by configuring a
++	    Excessive almost-identical UDP <emphasis>responses</emphasis>
++	    can be controlled by configuring a
 +	    <command>rate-limit</command> clause in an
-+	    <command>options</command> statement.
-+	    This mechanism keeps BIND 9 from being used
-+	    in amplifying reflection denial of service attacks
-+	    as well as partially protecting BIND 9 itself from
-+	    some denial of service attacks.
-+	    Very short truncated responses can be sent to provide
-+	    rate-limited responses to legitimate
-+	    clients within a range of attacked and forged IP addresses,
-+	    Legitimate clients react to truncated response by retrying
-+	    with TCP.
++	    <command>options</command> or <command>view</command> statement.
++	    This mechanism keeps authoritative BIND 9 from being used
++	    in amplifying reflection denial of service (DoS) attacks.
++	    Short truncated (TC=1) responses can be sent to provide
++	    rate-limited responses to legitimate clients within
++	    a range of forged, attacked IP addresses.
++	    Legitimate clients react to dropped or truncated response
++	    by retrying with UDP or with TCP respectively.
 +	  </para>
 +
 +	  <para>
-+	    Rate limiting works by setting
-+	    <command>responses-per-second</command>
-+	    to a number of repetitions per second for responses for a given name
-+	    and record type to a DNS client.
++	    This mechanism is intended for authoritative DNS servers.
++	    It can be used on recursive servers but can slow
++	    applications such as SMTP servers (mail receivers) and
++	    HTTP clients (web browsers) that repeatedly request the
++	    same domains.
++	    When possible, closing "open" recursive servers is better.
 +	  </para>
 +
 +	  <para>
-+	    <command>Responses-per-second</command> is a limit on
-+	    identical responses instead of a limit on all responses or
-+	    even all responses to a single client.
-+	    10 identical responses per second is a generous limit except perhaps
-+	    when many clients are using a single IP address via network
-+	    address translation (NAT).
-+	    The default limit of zero specifies an unbounded limit to turn off
-+	    rate-limiting in a view or to only rate-limit NXDOMAIN or other
-+	    errors.
++	    Response rate limiting uses a "credit" or "token bucket" scheme.
++	    Each combination of identical response and client
++	    has a conceptual account that earns a specified number
++	    of credits every second.
++	    A prospective response debits its account by one.
++	    Responses are dropped or truncated
++	    while the account is negative.
++            Responses are tracked within a rolling window of time
++            which defaults to 15 seconds, but can be configured with
++            the <command>window</command> option to any value from
++            1 to 3600 seconds (1 hour).
++	    The account cannot become more positive than
++	    the per-second limit
++	    or more negative than <command>window</command>
++	    times the per-second limit.
++            When the specified number of credits for a class of
++            responses is set to 0, those responses are not rate limited.
 +	  </para>
 +
 +	  <para>
-+	    The notion of "identical responses"
-+	    and "single DNS client" cannot be simplistic.
-+	    All responses to a CIDR block with prefix
-+	    length specified with <command>IPv4-prefix-length</command>
-+	    (default 24) or <command>IPv6-prefix-length</command>
-+	    (default 56) are assumed to come from a single DNS client.
-+	    Requests for a name that result in DNS NXDOMAIN
-+	    errors are considered identical.
-+	    This controls some attacks using random names, but
-+	    accommodates servers that expect many legitimate NXDOMAIN responses
-+	    such as anti-spam blacklists.
-+	    By default the limit on NXDOMAIN errors is the same as the
-+	    <command>responses-per-second</command> value,
-+	    but it can be set separately with
-+	    <command>nxdomains-per-second</command>.
-+	    All requests for all names or types that result in DNS errors
-+	    such as SERVFAIL and FORMERR (but not NXDOMAIN) are considered
-+	    identical.
-+	    This controls attacks using invalid requests or distant,
-+	    broken authoritative servers.
-+	    By default the limit on errors is the same as the
-+	    <command>responses-per-second</command> value,
-+	    but it can be set separately with
-+	    <command>errors-per-second</command>.
++	    The notions of "identical response" and "DNS client"
++	    for rate limiting are not simplistic.
++	    All responses to an address block are counted as if to a
++	    single client.
++	    The prefix lengths of addresses blocks are
++	    specified with <command>ipv4-prefix-length</command> (default 24)
++	    and <command>ipv6-prefix-length</command> (default 56).
 +	  </para>
 +
 +	  <para>
-+	    Rate limiting uses a "credit" or "token bucket" scheme.
-+	    Each identical response has a conceptual account
-+	    that is given <command>responses-per-second</command>,
-+	    <command>errors-per-second</command>, and
-+	    <command>nxdomains-per-second</command> credits every second.
-+	    A DNS request triggering some desired response debits
-+	    the account by one.
-+	    Responses are not sent while the account is negative.
-+	    The account cannot become more positive than
-+	    the per-second limit
-+	    or more negative than <command>window</command>
-+	    times the per-second limit.
-+	    A DNS client that sends requests that are not
-+	    answered can be penalized for up to <command>window</command>
-+	    seconds (default 15).
++	    All non-empty responses for a valid domain name (qname)
++	    and record type (qtype) are identical and have a limit specified
++	    with <command>responses-per-second</command>
++	    (default 0 or no limit).
++	    All empty (NODATA) responses for a valid domain,
++	    regardless of query type, are identical.
++	    Responses in the NODATA class are limited by
++	    <command>nodata-per-second</command>
++	    (default <command>responses-per-second</command>).
++	    Requests for any and all undefined subdomains of a given
++            valid domain result in NXDOMAIN errors, and are identical
++            regardless of query type.
++	    They are limited by <command>nxdomain-per-second</command>
++	    (default <command>responses-per-second</command>).
++	    This controls some attacks using random names, but
++	    can be relaxed or turned off (set to 0)
++	    on servers that expect many legitimate
++	    NXDOMAIN responses, such as from anti-spam blacklists.
++	    Referrals or delegations to the server of a given
++	    domain are identical and are limited by
++	    <command>referrals-per-second</command>
++	    (default <command>responses-per-second</command>).
 +	  </para>
 +
 +	  <para>
 +	    Responses generated from local wildcards are counted and limited
 +	    as if they were for the parent domain name.
-+	    This prevents flooding by requesting random.wild.example.com.
-+	    For similar reasons, NXDOMAIN responses are counted and rate
-+	    limited by the valid domain name nearest to the
-+	    query name with an SOA record.
++	    This controls flooding using random.wild.example.com.
++	  </para>
++
++	  <para>
++            All requests that result in DNS errors other
++	    than NXDOMAIN, such as SERVFAIL and FORMERR, are identical
++            regardless of requested name (qname) or record type (qtype).
++	    This controls attacks using invalid requests or distant,
++	    broken authoritative servers.
++	    By default the limit on errors is the same as the
++	    <command>responses-per-second</command> value,
++	    but it can be set separately with
++	    <command>errors-per-second</command>.
 +	  </para>
 +
 +	  <para>
@@ -1236,14 +1308,15 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
 +	    There is a mechanism that can answer some legitimate
 +	    requests from a client whose address is being forged in a flood.
 +	    Setting <command>slip</command> to 2 (its default) causes every
-+	    other UDP request to be answered with a small response
-+	    claiming that the response would have been truncated.
-+	    The small size and relative infrequency of the response make
-+	    it unattractive for abuse.
-+	    <command>Slip</command> must be between 0 and 10.
-+	    A value of 0 does not "slip"
-+	    or sends no rate limiting truncated responses.
-+	    Some error responses includinge REFUSED and SERVFAIL
++	    other UDP request to be answered with a small truncated (TC=1)
++	    response.
++	    The small size and reduced frequency, and so lack of
++	    amplification, of "slipped" responses make them unattractive
++	    for reflection DoS attacks.
++	    <command>slip</command> must be between 0 and 10.
++	    A value of 0 does not "slip";
++	    no truncated responses are sent due to rate limiting.
++	    Some error responses including REFUSED and SERVFAIL
 +	    cannot be replaced with truncated responses and are instead
 +	    leaked at the <command>slip</command> rate.
 +	  </para>
@@ -1273,8 +1346,8 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
 +	    <command>rate-limit</command> statements in <command>view</command>
 +	    statements instead of the global <command>option</command>
 +	    statement.
-+	    A <command>rate-limit</command> statement in a view replaces
-+	    instead of being merged with a <command>rate-limit</command>
++	    A <command>rate-limit</command> statement in a view replaces,
++	    rather than supplementing, a <command>rate-limit</command>
 +	    statement among the main options.
 +	    DNS clients within a view can be exempted from rate limits
 +	    with the <command>exempt-clients</command> clause.
@@ -1347,7 +1420,7 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
        </sect2>
  
        <sect2 id="server_statement_grammar">
-@@ -14648,6 +14900,32 @@ HOST-127.EXAMPLE. MX 0 .
+@@ -14649,6 +14909,32 @@
  		      </para>
  		    </entry>
  		  </row>
@@ -1380,10 +1453,33 @@ diff -up bind-9.9.3rc2/doc/arm/Bv9ARM-book.xml.rl bind-9.9.3rc2/doc/arm/Bv9ARM-b
  		</tbody>
                </tgroup>
              </informaltable>
-diff -up bind-9.9.3rc2/lib/dns/include/dns/log.h.rl bind-9.9.3rc2/lib/dns/include/dns/log.h
---- bind-9.9.3rc2/lib/dns/include/dns/log.h.rl	2013-05-13 12:30:38.489659430 +0200
-+++ bind-9.9.3rc2/lib/dns/include/dns/log.h	2013-05-13 12:30:38.636659406 +0200
-@@ -43,6 +43,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodul
+diff -r -u lib/dns/Makefile.in-orig lib/dns/Makefile.in
+--- lib/dns/Makefile.in-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/Makefile.in	2004-01-01 00:00:00.000000000 +0000
+@@ -67,8 +67,8 @@
+ 		portlist. at O@ private. at O@ \
+ 		rbt. at O@ rbtdb. at O@ rbtdb64. at O@ rcode. at O@ rdata. at O@ \
+ 		rdatalist. at O@ rdataset. at O@ rdatasetiter. at O@ rdataslab. at O@ \
+-		request. at O@ resolver. at O@ result. at O@ rootns. at O@ rpz. at O@ \
+-		rriterator. at O@ sdb. at O@ \
++		request. at O@ resolver. at O@ result. at O@ rootns. at O@ \
++		rpz. at O@ rrl. at O@ rriterator. at O@ sdb. at O@ \
+ 		sdlz. at O@ soa. at O@ ssu. at O@ ssu_external. at O@ \
+ 		stats. at O@ tcpmsg. at O@ time. at O@ timer. at O@ tkey. at O@ \
+ 		tsec. at O@ tsig. at O@ ttl. at O@ update. at O@ validator. at O@ \
+@@ -95,7 +95,7 @@
+ 		name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \
+ 		rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
+ 		rdataset.c rdatasetiter.c rdataslab.c request.c \
+-		resolver.c result.c rootns.c rpz.c rriterator.c \
++		resolver.c result.c rootns.c rpz.c rrl.c rriterator.c \
+ 		sdb.c sdlz.c soa.c ssu.c ssu_external.c \
+ 		stats.c tcpmsg.c time.c timer.c tkey.c \
+ 		tsec.c tsig.c ttl.c update.c validator.c \
+diff -r -u lib/dns/include/dns/log.h-orig lib/dns/include/dns/log.h
+--- lib/dns/include/dns/log.h-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/include/dns/log.h	2004-01-01 00:00:00.000000000 +0000
+@@ -43,6 +43,7 @@
  #define DNS_LOGCATEGORY_DELEGATION_ONLY	(&dns_categories[10])
  #define DNS_LOGCATEGORY_EDNS_DISABLED	(&dns_categories[11])
  #define DNS_LOGCATEGORY_RPZ		(&dns_categories[12])
@@ -1391,10 +1487,10 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/log.h.rl bind-9.9.3rc2/lib/dns/includ
  
  /* Backwards compatibility. */
  #define DNS_LOGCATEGORY_GENERAL		ISC_LOGCATEGORY_GENERAL
-diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/include/dns/rrl.h
---- bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl	2013-05-13 12:30:38.636659406 +0200
-+++ bind-9.9.3rc2/lib/dns/include/dns/rrl.h	2013-05-13 12:30:38.636659406 +0200
-@@ -0,0 +1,273 @@
+diff -r -u lib/dns/include/dns/rrl.h-orig lib/dns/include/dns/rrl.h
+--- lib/dns/include/dns/rrl.h-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/include/dns/rrl.h	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,278 @@
 +/*
 + * Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
 + *
@@ -1468,7 +1564,8 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/includ
 +typedef enum {
 +	DNS_RRL_RTYPE_FREE = 0,
 +	DNS_RRL_RTYPE_QUERY,
-+	DNS_RRL_RTYPE_DELEGATION,
++	DNS_RRL_RTYPE_REFERRAL,
++	DNS_RRL_RTYPE_NODATA,
 +	DNS_RRL_RTYPE_NXDOMAIN,
 +	DNS_RRL_RTYPE_ERROR,
 +	DNS_RRL_RTYPE_ALL,
@@ -1587,6 +1684,13 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/includ
 +	dns_fixedname_t	    qname;
 +};
 +
++typedef struct dns_rrl_rate dns_rrl_rate_t;
++struct dns_rrl_rate {
++	int	    r;
++	int	    scaled;
++	const char  *str;
++};
++
 +/*
 + * Per-view query rate limit parameters and a pointer to database.
 + */
@@ -1596,12 +1700,14 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/includ
 +	isc_mem_t	*mctx;
 +
 +	isc_boolean_t	log_only;
-+	int		responses_per_second;
-+	int		errors_per_second;
-+	int		nxdomains_per_second;
-+	int		all_per_second;
++	dns_rrl_rate_t	responses_per_second;
++	dns_rrl_rate_t	referrals_per_second;
++	dns_rrl_rate_t	nodata_per_second;
++	dns_rrl_rate_t	nxdomains_per_second;
++	dns_rrl_rate_t	errors_per_second;
++	dns_rrl_rate_t	all_per_second;
++	dns_rrl_rate_t	slip;
 +	int		window;
-+	int		slip;
 +	double		qps_scale;
 +	int		max_entries;
 +
@@ -1612,11 +1718,6 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/includ
 +	int		qps_responses;
 +	isc_stdtime_t	qps_time;
 +	double		qps;
-+	int		scaled_responses_per_second;
-+	int		scaled_errors_per_second;
-+	int		scaled_nxdomains_per_second;
-+	int		scaled_all_per_second;
-+	int		scaled_slip;
 +
 +	unsigned int	probes;
 +	unsigned int	searches;
@@ -1668,9 +1769,9 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/rrl.h.rl bind-9.9.3rc2/lib/dns/includ
 +ISC_LANG_ENDDECLS
 +
 +#endif /* DNS_RRL_H */
-diff -up bind-9.9.3rc2/lib/dns/include/dns/view.h.rl bind-9.9.3rc2/lib/dns/include/dns/view.h
---- bind-9.9.3rc2/lib/dns/include/dns/view.h.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/lib/dns/include/dns/view.h	2013-05-13 12:30:38.636659406 +0200
+diff -r -u lib/dns/include/dns/view.h-orig lib/dns/include/dns/view.h
+--- lib/dns/include/dns/view.h-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/include/dns/view.h	2004-01-01 00:00:00.000000000 +0000
 @@ -73,6 +73,7 @@
  
  #include <dns/acl.h>
@@ -1679,7 +1780,7 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/view.h.rl bind-9.9.3rc2/lib/dns/inclu
  #include <dns/rdatastruct.h>
  #include <dns/rpz.h>
  #include <dns/types.h>
-@@ -142,6 +143,7 @@ struct dns_view {
+@@ -142,6 +143,7 @@
  	dns_rbt_t *			answeracl_exclude;
  	dns_rbt_t *			denyanswernames;
  	dns_rbt_t *			answernames_exclude;
@@ -1687,10 +1788,10 @@ diff -up bind-9.9.3rc2/lib/dns/include/dns/view.h.rl bind-9.9.3rc2/lib/dns/inclu
  	isc_boolean_t			provideixfr;
  	isc_boolean_t			requestnsid;
  	dns_ttl_t			maxcachettl;
-diff -up bind-9.9.3rc2/lib/dns/log.c.rl bind-9.9.3rc2/lib/dns/log.c
---- bind-9.9.3rc2/lib/dns/log.c.rl	2013-05-13 12:30:38.489659430 +0200
-+++ bind-9.9.3rc2/lib/dns/log.c	2013-05-13 12:30:38.637659406 +0200
-@@ -45,6 +45,7 @@ LIBDNS_EXTERNAL_DATA isc_logcategory_t d
+diff -r -u lib/dns/log.c-orig lib/dns/log.c
+--- lib/dns/log.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/log.c	2004-01-01 00:00:00.000000000 +0000
+@@ -45,6 +45,7 @@
  	{ "delegation-only", 0 },
  	{ "edns-disabled", 0 },
  	{ "rpz",	0 },
@@ -1698,33 +1799,10 @@ diff -up bind-9.9.3rc2/lib/dns/log.c.rl bind-9.9.3rc2/lib/dns/log.c
  	{ NULL, 	0 }
  };
  
-diff -up bind-9.9.3rc2/lib/dns/Makefile.in.rl bind-9.9.3rc2/lib/dns/Makefile.in
---- bind-9.9.3rc2/lib/dns/Makefile.in.rl	2013-05-13 12:30:38.515659426 +0200
-+++ bind-9.9.3rc2/lib/dns/Makefile.in	2013-05-13 12:30:38.636659406 +0200
-@@ -63,8 +63,8 @@ DNSOBJS =	acache. at O@ acl. at O@ adb. at O@ bya
- 		portlist. at O@ private. at O@ \
- 		rbt. at O@ rbtdb. at O@ rbtdb64. at O@ rcode. at O@ rdata. at O@ \
- 		rdatalist. at O@ rdataset. at O@ rdatasetiter. at O@ rdataslab. at O@ \
--		request. at O@ resolver. at O@ result. at O@ rootns. at O@ rpz. at O@ \
--		rriterator. at O@ sdb. at O@ \
-+		request. at O@ resolver. at O@ result. at O@ rootns. at O@ \
-+		rpz. at O@ rrl. at O@ rriterator. at O@ sdb. at O@ \
- 		sdlz. at O@ soa. at O@ ssu. at O@ ssu_external. at O@ \
- 		stats. at O@ tcpmsg. at O@ time. at O@ timer. at O@ tkey. at O@ \
- 		tsec. at O@ tsig. at O@ ttl. at O@ update. at O@ validator. at O@ \
-@@ -91,7 +91,7 @@ DNSSRCS =	acache.c acl.c adb.c byaddr.c
- 		name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \
- 		rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
- 		rdataset.c rdatasetiter.c rdataslab.c request.c \
--		resolver.c result.c rootns.c rpz.c rriterator.c \
-+		resolver.c result.c rootns.c rpz.c rrl.c rriterator.c \
- 		sdb.c sdlz.c soa.c ssu.c ssu_external.c \
- 		stats.c tcpmsg.c time.c timer.c tkey.c \
- 		tsec.c tsig.c ttl.c update.c validator.c \
-diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
---- bind-9.9.3rc2/lib/dns/rrl.c.rl	2013-05-13 12:30:38.637659406 +0200
-+++ bind-9.9.3rc2/lib/dns/rrl.c	2013-05-13 12:30:38.637659406 +0200
-@@ -0,0 +1,1335 @@
+diff -r -u lib/dns/rrl.c-orig lib/dns/rrl.c
+--- lib/dns/rrl.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/rrl.c	2004-01-01 00:00:00.000000000 +0000
+@@ -0,0 +1,1324 @@
 +/*
 + * Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
 + *
@@ -1894,11 +1972,11 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	if (ts >= DNS_RRL_MAX_TS) {
 +		ts_gen = (ts_gen + 1) % DNS_RRL_TS_BASES;
 +		for (e_old = ISC_LIST_TAIL(rrl->lru), i = 0;
-+		     e_old != NULL && e_old->ts_gen == ts_gen;
++		     e_old != NULL && (e_old->ts_gen == ts_gen ||
++				       !ISC_LINK_LINKED(e_old, hlink));
 +		     e_old = ISC_LIST_PREV(e_old, lru), ++i)
 +		{
-+			if (e_old->ts_valid)
-+				e_old->ts_valid = ISC_FALSE;
++			e_old->ts_valid = ISC_FALSE;
 +		}
 +		if (i != 0)
 +			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
@@ -2130,9 +2208,16 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	memset(key, 0, sizeof(*key));
 +
 +	key->s.rtype = rtype;
-+	if (rtype == DNS_RRL_RTYPE_QUERY || rtype == DNS_RRL_RTYPE_DELEGATION) {
-+		key->s.qclass = qclass & 0xff;
++	if (rtype == DNS_RRL_RTYPE_QUERY) {
 +		key->s.qtype = qtype;
++		key->s.qclass = qclass & 0xff;
++	} else if (rtype == DNS_RRL_RTYPE_REFERRAL ||
++		   rtype == DNS_RRL_RTYPE_NODATA) {
++		/*
++		 * Because there is no qtype in the empty answer sections of
++		 * referral and NODATA responses, count them as the same.
++		 */
++		key->s.qclass = qclass & 0xff;
 +	}
 +
 +	if (qname != NULL && qname->labels != 0) {
@@ -2167,33 +2252,40 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	}
 +}
 +
-+static inline int
-+response_balance(const dns_rrl_t *rrl, const dns_rrl_entry_t *e, int age) {
-+	int balance, rate = 0;
-+
-+	balance = e->responses;
-+	if (balance < 0)
-+		switch (e->key.s.rtype) {
-+		case DNS_RRL_RTYPE_QUERY:
-+		case DNS_RRL_RTYPE_DELEGATION:
-+			rate = rrl->scaled_responses_per_second;
-+			break;
-+		case DNS_RRL_RTYPE_NXDOMAIN:
-+			rate = rrl->scaled_nxdomains_per_second;
-+			break;
-+		case DNS_RRL_RTYPE_ERROR:
-+			rate = rrl->scaled_errors_per_second;
-+			break;
-+		case DNS_RRL_RTYPE_ALL:
-+			rate = rrl->scaled_all_per_second;
-+			break;
-+		case DNS_RRL_RTYPE_TCP:
-+			rate = 1;
-+			break;
-+		default:
-+			INSIST(0);
++static inline dns_rrl_rate_t *
++get_rate(dns_rrl_t *rrl, dns_rrl_rtype_t rtype) {
++	switch (rtype) {
++	case DNS_RRL_RTYPE_QUERY:
++		return (&rrl->responses_per_second);
++	case DNS_RRL_RTYPE_REFERRAL:
++		return (&rrl->referrals_per_second);
++	case DNS_RRL_RTYPE_NODATA:
++		return (&rrl->nodata_per_second);
++	case DNS_RRL_RTYPE_NXDOMAIN:
++		return (&rrl->nxdomains_per_second);
++	case DNS_RRL_RTYPE_ERROR:
++		return (&rrl->errors_per_second);
++	case DNS_RRL_RTYPE_ALL:
++		return (&rrl->all_per_second);
++	default:
++		INSIST(0);
++	}
++	return (NULL);
++}
++
++static int
++response_balance(dns_rrl_t *rrl, const dns_rrl_entry_t *e, int age) {
++	dns_rrl_rate_t *ratep;
++	int balance, rate;
++
++	if (e->key.s.rtype == DNS_RRL_RTYPE_TCP) {
++		rate = 1;
++	} else {
++		ratep = get_rate(rrl, e->key.s.rtype);
++		rate = ratep->scaled;
 +	}
-+	balance += age * rate;
++
++	balance = e->responses + age * rate;
 +	if (balance > rate)
 +		balance = rate;
 +	return (balance);
@@ -2278,7 +2370,7 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +			e = NULL;
 +			break;
 +		}
-+		if (!e->logged && response_balance(rrl, e, age) >= 0)
++		if (!e->logged && response_balance(rrl, e, age) > 0)
 +			break;
 +	}
 +	if (e == NULL) {
@@ -2325,35 +2417,16 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +		const isc_sockaddr_t *client_addr, isc_stdtime_t now,
 +		char *log_buf, unsigned int log_buf_len)
 +{
-+	int rate, new_rate, *ratep, slip, new_slip, age, log_secs, min;
-+	const char *rate_str = NULL;
++	int rate, new_rate, slip, new_slip, age, log_secs, min;
++	dns_rrl_rate_t *ratep;
 +	dns_rrl_entry_t const *credit_e;
 +
 +	/*
 +	 * Pick the rate counter.
 +	 * Optionally adjust the rate by the estimated query/second rate.
 +	 */
-+	switch (e->key.s.rtype) {
-+	case DNS_RRL_RTYPE_QUERY:
-+	case DNS_RRL_RTYPE_DELEGATION:
-+		rate = rrl->responses_per_second;
-+		ratep = &rrl->scaled_responses_per_second;
-+		break;
-+	case DNS_RRL_RTYPE_NXDOMAIN:
-+		rate = rrl->nxdomains_per_second;
-+		ratep = &rrl->scaled_nxdomains_per_second;
-+		break;
-+	case DNS_RRL_RTYPE_ERROR:
-+		rate = rrl->errors_per_second;
-+		ratep = &rrl->scaled_errors_per_second;
-+		break;
-+	case DNS_RRL_RTYPE_ALL:
-+		rate = rrl->all_per_second;
-+		ratep = &rrl->scaled_all_per_second;
-+		break;
-+	default:
-+		INSIST(0);
-+	}
++	ratep = get_rate(rrl, e->key.s.rtype);
++	rate = ratep->r;
 +	if (rate == 0)
 +		return (DNS_RRL_RESULT_OK);
 +
@@ -2375,36 +2448,16 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +		new_rate = (int) (rate * scale);
 +		if (new_rate < 1)
 +			new_rate = 1;
-+		if (*ratep != new_rate) {
-+			if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) {
-+				switch (e->key.s.rtype) {
-+				case DNS_RRL_RTYPE_QUERY:
-+				case DNS_RRL_RTYPE_DELEGATION:
-+					rate_str = "responses-per-second";
-+					break;
-+				case DNS_RRL_RTYPE_NXDOMAIN:
-+					rate_str = "nxdomains-per-second";
-+					break;
-+				case DNS_RRL_RTYPE_ERROR:
-+					rate_str = "errors-per-second";
-+					break;
-+				case DNS_RRL_RTYPE_ALL:
-+					rate_str = "all-per-second";
-+					break;
-+				case DNS_RRL_RTYPE_FREE:
-+				case DNS_RRL_RTYPE_TCP:
-+					INSIST(0);
-+				}
-+				isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
-+					      DNS_LOGMODULE_REQUEST,
-+					      DNS_RRL_LOG_DEBUG1,
-+					      "%d qps scaled %s by %.2f"
-+					      " from %d to %d",
-+					      (int)qps, rate_str, scale,
-+					      rate, new_rate);
-+			}
++		if (ratep->scaled != new_rate) {
++			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
++				      DNS_LOGMODULE_REQUEST,
++				      DNS_RRL_LOG_DEBUG1,
++				      "%d qps scaled %s by %.2f"
++				      " from %d to %d",
++				      (int)qps, ratep->str, scale,
++				      rate, new_rate);
 +			rate = new_rate;
-+			*ratep = rate;
++			ratep->scaled = rate;
 +		}
 +	}
 +
@@ -2463,22 +2516,21 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	/*
 +	 * Drop this response unless it should slip or leak.
 +	 */
-+	slip = rrl->slip;
++	slip = rrl->slip.r;
 +	if (slip > 2 && scale < 1.0) {
 +		new_slip = (int) (slip * scale);
 +		if (new_slip < 2)
 +			new_slip = 2;
-+		if (rrl->scaled_slip != new_slip) {
-+			if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1))
-+				isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
-+					      DNS_LOGMODULE_REQUEST,
-+					      DNS_RRL_LOG_DEBUG1,
-+					      "%d qps scaled slip"
-+					      " by %.2f from %d to %d",
-+					      (int)qps, scale,
-+					      slip, new_slip);
++		if (rrl->slip.scaled != new_slip) {
++			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
++				      DNS_LOGMODULE_REQUEST,
++				      DNS_RRL_LOG_DEBUG1,
++				      "%d qps scaled slip"
++				      " by %.2f from %d to %d",
++				      (int)qps, scale,
++				      slip, new_slip);
 +			slip = new_slip;
-+			rrl->scaled_slip = slip;
++			rrl->slip.scaled = slip;
 +		}
 +	}
 +	if (slip != 0 && e->key.s.rtype != DNS_RRL_RTYPE_ALL) {
@@ -2580,34 +2632,36 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +
 +	switch (e->key.s.rtype) {
 +	case DNS_RRL_RTYPE_QUERY:
-+		ADD_LOG_CSTR(&lb, "response");
 +		break;
-+	case DNS_RRL_RTYPE_DELEGATION:
-+		ADD_LOG_CSTR(&lb, "referral");
++	case DNS_RRL_RTYPE_REFERRAL:
++		ADD_LOG_CSTR(&lb, "referral ");
++		break;
++	case DNS_RRL_RTYPE_NODATA:
++		ADD_LOG_CSTR(&lb, "NODATA ");
 +		break;
 +	case DNS_RRL_RTYPE_NXDOMAIN:
-+		ADD_LOG_CSTR(&lb, "NXDOMAIN response");
++		ADD_LOG_CSTR(&lb, "NXDOMAIN ");
 +		break;
 +	case DNS_RRL_RTYPE_ERROR:
 +		if (resp_result == ISC_R_SUCCESS) {
-+			ADD_LOG_CSTR(&lb, "error response");
++			ADD_LOG_CSTR(&lb, "error ");
 +		} else {
 +			rstr = isc_result_totext(resp_result);
 +			add_log_str(&lb, rstr, strlen(rstr));
-+			ADD_LOG_CSTR(&lb, " response");
++			ADD_LOG_CSTR(&lb, " error ");
 +		}
 +		break;
 +	case DNS_RRL_RTYPE_ALL:
-+		ADD_LOG_CSTR(&lb, "all response");
++		ADD_LOG_CSTR(&lb, "all ");
 +		break;
 +	default:
 +		INSIST(0);
 +	}
 +
 +	if (plural)
-+		ADD_LOG_CSTR(&lb, "s to ");
++		ADD_LOG_CSTR(&lb, "responses to ");
 +	else
-+		ADD_LOG_CSTR(&lb, " to ");
++		ADD_LOG_CSTR(&lb, "response to ");
 +
 +	memset(&cidr, 0, sizeof(cidr));
 +	if (e->key.s.ipv6) {
@@ -2626,7 +2680,8 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	add_log_str(&lb, strbuf, strlen(strbuf));
 +
 +	if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY ||
-+	    e->key.s.rtype == DNS_RRL_RTYPE_DELEGATION ||
++	    e->key.s.rtype == DNS_RRL_RTYPE_REFERRAL ||
++	    e->key.s.rtype == DNS_RRL_RTYPE_NODATA ||
 +	    e->key.s.rtype == DNS_RRL_RTYPE_NXDOMAIN) {
 +		qbuf = get_qname(rrl, e);
 +		if (save_qname && qbuf == NULL &&
@@ -2674,8 +2729,10 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +		if (e->key.s.rtype != DNS_RRL_RTYPE_NXDOMAIN) {
 +			ADD_LOG_CSTR(&lb, " ");
 +			(void)dns_rdataclass_totext(e->key.s.qclass, &lb);
-+			ADD_LOG_CSTR(&lb, " ");
-+			(void)dns_rdatatype_totext(e->key.s.qtype, &lb);
++			if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY) {
++				ADD_LOG_CSTR(&lb, " ");
++				(void)dns_rdatatype_totext(e->key.s.qtype, &lb);
++			}
 +		}
 +		snprintf(strbuf, sizeof(strbuf), "  (%08x)",
 +			 e->key.s.qname_hash);
@@ -2844,14 +2901,23 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	 * Find the right kind of entry, creating it if necessary.
 +	 * If that is impossible, then nothing more can be done
 +	 */
-+	if (resp_result == ISC_R_SUCCESS)
++	switch (resp_result) {
++	case ISC_R_SUCCESS:
 +		rtype = DNS_RRL_RTYPE_QUERY;
-+	else if (resp_result == DNS_R_DELEGATION)
-+		rtype = DNS_RRL_RTYPE_DELEGATION;
-+	else if (resp_result == DNS_R_NXDOMAIN)
++		break;
++	case DNS_R_DELEGATION:
++		rtype = DNS_RRL_RTYPE_REFERRAL;
++		break;
++	case DNS_R_NXRRSET:
++		rtype = DNS_RRL_RTYPE_NODATA;
++		break;
++	case DNS_R_NXDOMAIN:
 +		rtype = DNS_RRL_RTYPE_NXDOMAIN;
-+	else
++		break;
++	default:
 +		rtype = DNS_RRL_RTYPE_ERROR;
++		break;
++	}
 +	e = get_entry(rrl, client_addr, qclass, qtype, qname, rtype,
 +		      now, ISC_TRUE, log_buf, log_buf_len);
 +	if (e == NULL) {
@@ -2875,7 +2941,7 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	rrl_result = debit_rrl_entry(rrl, e, qps, scale, client_addr, now,
 +				     log_buf, log_buf_len);
 +
-+	if (rrl->all_per_second != 0) {
++	if (rrl->all_per_second.r != 0) {
 +		/*
 +		 * We must debit the all-per-second token bucket if we have
 +		 * an all-per-second limit for the IP address.
@@ -2958,7 +3024,8 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	 * Make a log message for the caller.
 +	 */
 +	if (wouldlog)
-+		make_log_buf(rrl, e, rrl->log_only ? "would " : NULL,
++		make_log_buf(rrl, e,
++			     rrl->log_only ? "would rate limit " : "rate limit ",
 +			     NULL, ISC_FALSE, qname, ISC_FALSE,
 +			     rrl_result, resp_result, log_buf, log_buf_len);
 +
@@ -3060,9 +3127,9 @@ diff -up bind-9.9.3rc2/lib/dns/rrl.c.rl bind-9.9.3rc2/lib/dns/rrl.c
 +	*rrlp = rrl;
 +	return (ISC_R_SUCCESS);
 +}
-diff -up bind-9.9.3rc2/lib/dns/view.c.rl bind-9.9.3rc2/lib/dns/view.c
---- bind-9.9.3rc2/lib/dns/view.c.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/lib/dns/view.c	2013-05-13 12:30:38.638659406 +0200
+diff -r -u lib/dns/view.c-orig lib/dns/view.c
+--- lib/dns/view.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/view.c	2004-01-01 00:00:00.000000000 +0000
 @@ -49,6 +49,7 @@
  #include <dns/masterdump.h>
  #include <dns/order.h>
@@ -3071,7 +3138,7 @@ diff -up bind-9.9.3rc2/lib/dns/view.c.rl bind-9.9.3rc2/lib/dns/view.c
  #include <dns/rbt.h>
  #include <dns/rdataset.h>
  #include <dns/request.h>
-@@ -184,6 +185,7 @@ dns_view_create(isc_mem_t *mctx, dns_rda
+@@ -184,6 +185,7 @@
  	view->answeracl_exclude = NULL;
  	view->denyanswernames = NULL;
  	view->answernames_exclude = NULL;
@@ -3079,7 +3146,7 @@ diff -up bind-9.9.3rc2/lib/dns/view.c.rl bind-9.9.3rc2/lib/dns/view.c
  	view->provideixfr = ISC_TRUE;
  	view->maxcachettl = 7 * 24 * 3600;
  	view->maxncachettl = 3 * 3600;
-@@ -335,9 +337,11 @@ destroy(dns_view_t *view) {
+@@ -335,9 +337,11 @@
  		dns_acache_detach(&view->acache);
  	}
  	dns_rpz_view_destroy(view);
@@ -3091,10 +3158,10 @@ diff -up bind-9.9.3rc2/lib/dns/view.c.rl bind-9.9.3rc2/lib/dns/view.c
  #endif
  	if (view->requestmgr != NULL)
  		dns_requestmgr_detach(&view->requestmgr);
-diff -up bind-9.9.3rc2/lib/dns/win32/libdns.def.rl bind-9.9.3rc2/lib/dns/win32/libdns.def
---- bind-9.9.3rc2/lib/dns/win32/libdns.def.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/lib/dns/win32/libdns.def	2013-05-13 12:30:38.638659406 +0200
-@@ -656,6 +656,9 @@ dns_rriterator_init
+diff -r -u lib/dns/win32/libdns.def-orig lib/dns/win32/libdns.def
+--- lib/dns/win32/libdns.def-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/win32/libdns.def	2004-01-01 00:00:00.000000000 +0000
+@@ -657,6 +657,9 @@
  dns_rriterator_next
  dns_rriterator_nextrrset
  dns_rriterator_pause
@@ -3104,10 +3171,10 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.def.rl bind-9.9.3rc2/lib/dns/win32/l
  dns_sdb_putnamedrr
  dns_sdb_putrdata
  dns_sdb_putrr
-diff -up bind-9.9.3rc2/lib/dns/win32/libdns.dsp.rl bind-9.9.3rc2/lib/dns/win32/libdns.dsp
---- bind-9.9.3rc2/lib/dns/win32/libdns.dsp.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/lib/dns/win32/libdns.dsp	2013-05-13 12:30:38.638659406 +0200
-@@ -346,6 +346,10 @@ SOURCE=..\include\dns\rpz.h
+diff -r -u lib/dns/win32/libdns.dsp-orig lib/dns/win32/libdns.dsp
+--- lib/dns/win32/libdns.dsp-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/win32/libdns.dsp	2004-01-01 00:00:00.000000000 +0000
+@@ -346,6 +346,10 @@
  # End Source File
  # Begin Source File
  
@@ -3118,7 +3185,7 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.dsp.rl bind-9.9.3rc2/lib/dns/win32/l
  SOURCE=..\include\dns\rriterator.h
  # End Source File
  # Begin Source File
-@@ -650,6 +654,10 @@ SOURCE=..\rpz.c
+@@ -650,6 +654,10 @@
  # End Source File
  # Begin Source File
  
@@ -3129,10 +3196,10 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.dsp.rl bind-9.9.3rc2/lib/dns/win32/l
  SOURCE=..\rriterator.c
  # End Source File
  # Begin Source File
-diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/libdns.mak
---- bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl	2013-04-30 08:38:46.000000000 +0200
-+++ bind-9.9.3rc2/lib/dns/win32/libdns.mak	2013-05-13 12:30:38.638659406 +0200
-@@ -184,6 +184,7 @@ CLEAN :
+diff -r -u lib/dns/win32/libdns.mak-orig lib/dns/win32/libdns.mak
+--- lib/dns/win32/libdns.mak-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/dns/win32/libdns.mak	2004-01-01 00:00:00.000000000 +0000
+@@ -184,6 +184,7 @@
  	- at erase "$(INTDIR)\result.obj"
  	- at erase "$(INTDIR)\rootns.obj"
  	- at erase "$(INTDIR)\rpz.obj"
@@ -3140,7 +3207,7 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
  	- at erase "$(INTDIR)\sdb.obj"
  	- at erase "$(INTDIR)\sdlz.obj"
  	- at erase "$(INTDIR)\soa.obj"
-@@ -309,6 +310,7 @@ LINK32_OBJS= \
+@@ -309,6 +310,7 @@
  	"$(INTDIR)\result.obj" \
  	"$(INTDIR)\rootns.obj" \
  	"$(INTDIR)\rpz.obj" \
@@ -3148,7 +3215,7 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
  	"$(INTDIR)\rriterator.obj" \
  	"$(INTDIR)\sdb.obj" \
  	"$(INTDIR)\sdlz.obj" \
-@@ -505,6 +507,8 @@ CLEAN :
+@@ -505,6 +507,8 @@
  	- at erase "$(INTDIR)\rootns.sbr"
  	- at erase "$(INTDIR)\rpz.obj"
  	- at erase "$(INTDIR)\rpz.sbr"
@@ -3157,7 +3224,7 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
  	- at erase "$(INTDIR)\rriterator.obj"
  	- at erase "$(INTDIR)\rriterator.sbr"
  	- at erase "$(INTDIR)\sdb.obj"
-@@ -651,6 +655,7 @@ BSC32_SBRS= \
+@@ -651,6 +655,7 @@
  	"$(INTDIR)\result.sbr" \
  	"$(INTDIR)\rootns.sbr" \
  	"$(INTDIR)\rpz.sbr" \
@@ -3165,7 +3232,7 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
  	"$(INTDIR)\rriterator.sbr" \
  	"$(INTDIR)\sdb.sbr" \
  	"$(INTDIR)\sdlz.sbr" \
-@@ -748,6 +753,7 @@ LINK32_OBJS= \
+@@ -748,6 +753,7 @@
  	"$(INTDIR)\result.obj" \
  	"$(INTDIR)\rootns.obj" \
  	"$(INTDIR)\rpz.obj" \
@@ -3173,12 +3240,10 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
  	"$(INTDIR)\rriterator.obj" \
  	"$(INTDIR)\sdb.obj" \
  	"$(INTDIR)\sdlz.obj" \
-@@ -1724,6 +1730,24 @@ SOURCE=..\rpz.c
- 	$(CPP) $(CPP_PROJ) $(SOURCE)
+@@ -1726,6 +1732,24 @@
  
+ !ENDIF 
  
-+!ENDIF 
-+
 +SOURCE=..\rrl.c
 +
 +!IF  "$(CFG)" == "libdns - Win32 Release"
@@ -3195,13 +3260,15 @@ diff -up bind-9.9.3rc2/lib/dns/win32/libdns.mak.rl bind-9.9.3rc2/lib/dns/win32/l
 +	$(CPP) $(CPP_PROJ) $(SOURCE)
 +
 +
- !ENDIF 
- 
++!ENDIF 
++
  SOURCE=..\rriterator.c
-diff -up bind-9.9.3rc2/lib/isccfg/namedconf.c.rl bind-9.9.3rc2/lib/isccfg/namedconf.c
---- bind-9.9.3rc2/lib/isccfg/namedconf.c.rl	2013-05-13 12:30:38.490659430 +0200
-+++ bind-9.9.3rc2/lib/isccfg/namedconf.c	2013-05-13 12:30:38.639659406 +0200
-@@ -1272,6 +1272,39 @@ static cfg_type_t cfg_type_rpz = {
+ 
+ !IF  "$(CFG)" == "libdns - Win32 Release"
+diff -r -u lib/isccfg/namedconf.c-orig lib/isccfg/namedconf.c
+--- lib/isccfg/namedconf.c-orig	2004-01-01 00:00:00.000000000 +0000
++++ lib/isccfg/namedconf.c	2004-01-01 00:00:00.000000000 +0000
+@@ -1270,6 +1270,40 @@
  };
  
  
@@ -3210,16 +3277,17 @@ diff -up bind-9.9.3rc2/lib/isccfg/namedconf.c.rl bind-9.9.3rc2/lib/isccfg/namedc
 + */
 +static cfg_clausedef_t rrl_clauses[] = {
 +	{ "responses-per-second", &cfg_type_uint32, 0 },
-+	{ "errors-per-second", &cfg_type_uint32, 0 },
++	{ "referrals-per-second", &cfg_type_uint32, 0 },
++	{ "nodata-per-second", &cfg_type_uint32, 0 },
 +	{ "nxdomains-per-second", &cfg_type_uint32, 0 },
-+	{ "responses-per-second", &cfg_type_uint32, 0 },
++	{ "errors-per-second", &cfg_type_uint32, 0 },
 +	{ "all-per-second", &cfg_type_uint32, 0 },
 +	{ "slip", &cfg_type_uint32, 0 },
 +	{ "window", &cfg_type_uint32, 0 },
 +	{ "log-only", &cfg_type_boolean, 0 },
 +	{ "qps-scale", &cfg_type_uint32, 0 },
-+	{ "IPv4-prefix-length", &cfg_type_uint32, 0 },
-+	{ "IPv6-prefix-length", &cfg_type_uint32, 0 },
++	{ "ipv4-prefix-length", &cfg_type_uint32, 0 },
++	{ "ipv6-prefix-length", &cfg_type_uint32, 0 },
 +	{ "exempt-clients", &cfg_type_bracketed_aml, 0 },
 +	{ "max-table-size", &cfg_type_uint32, 0 },
 +	{ "min-table-size", &cfg_type_uint32, 0 },
@@ -3241,7 +3309,7 @@ diff -up bind-9.9.3rc2/lib/isccfg/namedconf.c.rl bind-9.9.3rc2/lib/isccfg/namedc
  /*%
   * dnssec-lookaside
   */
-@@ -1425,6 +1458,7 @@ view_clauses[] = {
+@@ -1423,6 +1457,7 @@
  	   CFG_CLAUSEFLAG_NOTCONFIGURED },
  #endif
  	{ "response-policy", &cfg_type_rpz, 0 },
@@ -3249,4 +3317,14 @@ diff -up bind-9.9.3rc2/lib/isccfg/namedconf.c.rl bind-9.9.3rc2/lib/isccfg/namedc
  	{ NULL, NULL, 0 }
  };
  
-diff -up bind-9.9.3rc2/version.rl bind-9.9.3rc2/version
+diff -r -u version-orig version
+--- version-orig	2004-01-01 00:00:00.000000000 +0000
++++ version	2004-01-01 00:00:00.000000000 +0000
+@@ -7,6 +7,6 @@
+ DESCRIPTION="(Extended Support Version)"
+ MAJORVER=9
+ MINORVER=9
+-PATCHVER=3
++PATCHVER=3-rl.150.20
+ RELEASETYPE=
+ RELEASEVER=


More information about the scm-commits mailing list