2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

[master] minimal-any

4371.	[func]		New "minimal-any" option reduces the size of UDP
			responses for qtype ANY by returning a single
			arbitrarily selected RRset instead of all RRsets.
			Thanks to Tony Finch. [RT #41615]
This commit is contained in:
Evan Hunt
2016-05-25 13:54:34 -07:00
parent 9c6a57d7c7
commit 0cbe448914
12 changed files with 149 additions and 0 deletions

View File

@@ -1,3 +1,8 @@
4371. [func] New "minimal-any" option reduces the size of UDP
responses for qtype ANY by returning a single
arbitrarily selected RRset instead of all RRsets.
Thanks to Tony Finch. [RT #41615]
4370. [bug] Address python3 compatibility issues with RNDC module.
[RT #42499]

View File

@@ -141,6 +141,7 @@ options {\n\
# sortlist <none>\n\
# topology <none>\n\
auth-nxdomain false;\n\
minimal-any false;\n\
minimal-responses false;\n\
recursion true;\n\
provide-ixfr true;\n\

View File

@@ -248,6 +248,7 @@ options {
sortlist { <replaceable>address_match_element</replaceable>; ... };
topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented
auth-nxdomain <replaceable>boolean</replaceable>; // default changed
minimal-any <replaceable>boolean</replaceable>;
minimal-responses <replaceable>boolean</replaceable>;
recursion <replaceable>boolean</replaceable>;
rrset-order {
@@ -446,6 +447,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
sortlist { <replaceable>address_match_element</replaceable>; ... };
topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented
auth-nxdomain <replaceable>boolean</replaceable>; // default changed
minimal-any <replaceable>boolean</replaceable>;
minimal-responses <replaceable>boolean</replaceable>;
recursion <replaceable>boolean</replaceable>;
rrset-order {

View File

@@ -8339,6 +8339,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
#endif
if (type == dns_rdatatype_any) {
/*
* For minimal-any, we only add records that
* match this type or cover this type.
*/
dns_rdatatype_t onetype = 0;
#ifdef ALLOW_FILTER_AAAA
isc_boolean_t have_aaaa, have_a, have_sig;
@@ -8402,6 +8407,21 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* ANY queries.
*/
dns_rdataset_disassociate(rdataset);
} else if (client->view->minimal_any &&
!TCP(client) && !WANTDNSSEC(client) &&
qtype == dns_rdatatype_any &&
(rdataset->type == dns_rdatatype_sig ||
rdataset->type == dns_rdatatype_rrsig)) {
CTRACE(ISC_LOG_DEBUG(5), "query_find: "
"minimal-any skip signature");
dns_rdataset_disassociate(rdataset);
} else if (client->view->minimal_any &&
!TCP(client) && onetype != 0 &&
rdataset->type != onetype &&
rdataset->covers != onetype) {
CTRACE(ISC_LOG_DEBUG(5), "query_find: "
"minimal-any skip rdataset");
dns_rdataset_disassociate(rdataset);
} else if ((qtype == dns_rdatatype_any ||
rdataset->type == qtype) && rdataset->type != 0) {
#ifdef ALLOW_FILTER_AAAA
@@ -8421,6 +8441,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
name = (fname != NULL) ? fname : tname;
query_prefetch(client, name, rdataset);
}
/*
* Remember the first RRtype we find so we
* can skip others with minimal-any.
*/
if (rdataset->type == dns_rdatatype_sig ||
rdataset->type == dns_rdatatype_rrsig)
onetype = rdataset->covers;
else
onetype = rdataset->type;
query_addrrset(client,
fname != NULL ? &fname : &tname,
&rdataset, NULL,
@@ -9096,6 +9125,14 @@ ns_query_start(ns_client_t *client) {
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL);
/*
* Maybe turn on minimal responses for ANY queries.
*/
if (qtype == dns_rdatatype_any &&
client->view->minimal_any && !TCP(client))
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL);
/*
* Turn on minimal responses for EDNS/UDP bufsize 512 queries.
*/

View File

@@ -3545,6 +3545,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
INSIST(result == ISC_R_SUCCESS);
view->auth_nxdomain = cfg_obj_asboolean(obj);
obj = NULL;
result = ns_config_get(maps, "minimal-any", &obj);
INSIST(result == ISC_R_SUCCESS);
view->minimal_any = cfg_obj_asboolean(obj);
obj = NULL;
result = ns_config_get(maps, "minimal-responses", &obj);
INSIST(result == ISC_R_SUCCESS);

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
recursion no;
additional-from-auth no;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
notify no;
minimal-any yes;
};
include "../../common/rndc.key";
controls {
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; };
};
zone "rt.example" {
type master;
file "rt.db";
};

View File

@@ -118,4 +118,25 @@ echo "I:testing with 'minimal-responses no;'"
minimal=no
dotests
echo "I:testing with 'minimal-any no;'"
n=`expr $n + 1`
$DIG -t ANY www.rt.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
grep "ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
echo "I:reconfiguring server"
cp ns1/named3.conf ns1/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reconfig 2>&1 | sed 's/^/I:ns1 /'
sleep 2
echo "I:testing with 'minimal-any yes;'"
n=`expr $n + 1`
$DIG -t ANY www.rt.example @10.53.0.1 -p 5300 > dig.out.$n || ret=1
grep "ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo "I: failed"; status=1
fi
exit $status

View File

@@ -4438,6 +4438,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> has-old-clients <replaceable>yes_or_no</replaceable>; </optional>
<optional> host-statistics <replaceable>yes_or_no</replaceable>; </optional>
<optional> host-statistics-max <replaceable>number</replaceable>; </optional>
<optional> minimal-any <replaceable>yes_or_no</replaceable>; </optional>
<optional> minimal-responses <replaceable>yes_or_no</replaceable>; </optional>
<optional> multiple-cnames <replaceable>yes_or_no</replaceable>; </optional>
<optional> notify <replaceable>yes_or_no</replaceable> | <replaceable>explicit</replaceable> | <replaceable>master-only</replaceable>; </optional>
@@ -6196,6 +6197,30 @@ options {
</listitem>
</varlistentry>
<varlistentry>
<term><command>minimal-any</command></term>
<listitem>
<para>
If set to <userinput>yes</userinput>, then when
generating a positive response to a query of type
ANY over UDP, the server will reply with only one
of the RRsets for the query name, and its covering
RRSIGs if any, instead of replying with all known
RRsets for the name. Similarly, a query for type
RRSIG will be answered with the RRSIG records covering
only one type. This can reduce the impact of some kinds
of attack traffic, without harming legitimate
clients. (Note, however, that the RRset returned is the
first one found in the database; it is not necessarily
the smallest available RRset.)
Additionally, <option>minimal-responses</option> is
turned on for these queries, so no unnecessary records
will be added to the authority or additional sections.
The default is <userinput>no</userinput>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>multiple-cnames</command></term>
<listitem>

View File

@@ -484,6 +484,16 @@
when a system's clock needs to be reset backwards.
</para>
</listitem>
<listitem>
<para>
The new <command>minimal-any</option> reduces the size of
answers to UDP queries for type ANY by implementing one of
the strategies in "draft-ietf-dnsop-refuse-any": returning
a single arbitrarily-selected RRset that matches the query
name rather than returning all of the matching RRsets.
Thanks to Tony Finch for the contribution. [RT #41615]
</para>
</listitem>
</itemizedlist>
</section>

View File

@@ -124,6 +124,7 @@ struct dns_view {
isc_boolean_t auth_nxdomain;
isc_boolean_t additionalfromcache;
isc_boolean_t additionalfromauth;
isc_boolean_t minimal_any;
isc_boolean_t minimalresponses;
isc_boolean_t enablednssec;
isc_boolean_t enablevalidation;

View File

@@ -190,6 +190,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->enablednssec = ISC_TRUE;
view->enablevalidation = ISC_TRUE;
view->acceptexpired = ISC_FALSE;
view->minimal_any = ISC_FALSE;
view->minimalresponses = ISC_FALSE;
view->transfer_format = dns_one_answer;
view->cacheacl = NULL;

View File

@@ -1685,6 +1685,7 @@ view_clauses[] = {
{ "max-recursion-queries", &cfg_type_uint32, 0 },
{ "max-udp-size", &cfg_type_uint32, 0 },
{ "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
{ "minimal-any", &cfg_type_boolean, 0 },
{ "minimal-responses", &cfg_type_boolean, 0 },
{ "nta-recheck", &cfg_type_ttlval, 0 },
{ "nta-lifetime", &cfg_type_ttlval, 0 },