Commit 0cbe4489 authored by Evan Hunt's avatar Evan Hunt
Browse files

[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]
parent 9c6a57d7
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. 4370. [bug] Address python3 compatibility issues with RNDC module.
[RT #42499] [RT #42499]
......
...@@ -141,6 +141,7 @@ options {\n\ ...@@ -141,6 +141,7 @@ options {\n\
# sortlist <none>\n\ # sortlist <none>\n\
# topology <none>\n\ # topology <none>\n\
auth-nxdomain false;\n\ auth-nxdomain false;\n\
minimal-any false;\n\
minimal-responses false;\n\ minimal-responses false;\n\
recursion true;\n\ recursion true;\n\
provide-ixfr true;\n\ provide-ixfr true;\n\
......
...@@ -248,6 +248,7 @@ options { ...@@ -248,6 +248,7 @@ options {
sortlist { <replaceable>address_match_element</replaceable>; ... }; sortlist { <replaceable>address_match_element</replaceable>; ... };
topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented
auth-nxdomain <replaceable>boolean</replaceable>; // default changed auth-nxdomain <replaceable>boolean</replaceable>; // default changed
minimal-any <replaceable>boolean</replaceable>;
minimal-responses <replaceable>boolean</replaceable>; minimal-responses <replaceable>boolean</replaceable>;
recursion <replaceable>boolean</replaceable>; recursion <replaceable>boolean</replaceable>;
rrset-order { rrset-order {
...@@ -446,6 +447,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable> ...@@ -446,6 +447,7 @@ view <replaceable>string</replaceable> <replaceable>optional_class</replaceable>
sortlist { <replaceable>address_match_element</replaceable>; ... }; sortlist { <replaceable>address_match_element</replaceable>; ... };
topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented topology { <replaceable>address_match_element</replaceable>; ... }; // not implemented
auth-nxdomain <replaceable>boolean</replaceable>; // default changed auth-nxdomain <replaceable>boolean</replaceable>; // default changed
minimal-any <replaceable>boolean</replaceable>;
minimal-responses <replaceable>boolean</replaceable>; minimal-responses <replaceable>boolean</replaceable>;
recursion <replaceable>boolean</replaceable>; recursion <replaceable>boolean</replaceable>;
rrset-order { rrset-order {
......
...@@ -8339,6 +8339,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) ...@@ -8339,6 +8339,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
#endif #endif
if (type == dns_rdatatype_any) { 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 #ifdef ALLOW_FILTER_AAAA
isc_boolean_t have_aaaa, have_a, have_sig; 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) ...@@ -8402,6 +8407,21 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
* ANY queries. * ANY queries.
*/ */
dns_rdataset_disassociate(rdataset); 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 || } else if ((qtype == dns_rdatatype_any ||
rdataset->type == qtype) && rdataset->type != 0) { rdataset->type == qtype) && rdataset->type != 0) {
#ifdef ALLOW_FILTER_AAAA #ifdef ALLOW_FILTER_AAAA
...@@ -8421,6 +8441,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) ...@@ -8421,6 +8441,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
name = (fname != NULL) ? fname : tname; name = (fname != NULL) ? fname : tname;
query_prefetch(client, name, rdataset); 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, query_addrrset(client,
fname != NULL ? &fname : &tname, fname != NULL ? &fname : &tname,
&rdataset, NULL, &rdataset, NULL,
...@@ -9096,6 +9125,14 @@ ns_query_start(ns_client_t *client) { ...@@ -9096,6 +9125,14 @@ ns_query_start(ns_client_t *client) {
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY | client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL); 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. * Turn on minimal responses for EDNS/UDP bufsize 512 queries.
*/ */
......
...@@ -3545,6 +3545,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, ...@@ -3545,6 +3545,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
INSIST(result == ISC_R_SUCCESS); INSIST(result == ISC_R_SUCCESS);
view->auth_nxdomain = cfg_obj_asboolean(obj); 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; obj = NULL;
result = ns_config_get(maps, "minimal-responses", &obj); result = ns_config_get(maps, "minimal-responses", &obj);
INSIST(result == ISC_R_SUCCESS); INSIST(result == ISC_R_SUCCESS);
......
/*
* 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";
};
...@@ -118,4 +118,25 @@ echo "I:testing with 'minimal-responses no;'" ...@@ -118,4 +118,25 @@ echo "I:testing with 'minimal-responses no;'"
minimal=no minimal=no
dotests 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 exit $status
...@@ -4438,6 +4438,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] ...@@ -4438,6 +4438,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
<optional> has-old-clients <replaceable>yes_or_no</replaceable>; </optional> <optional> has-old-clients <replaceable>yes_or_no</replaceable>; </optional>
<optional> host-statistics <replaceable>yes_or_no</replaceable>; </optional> <optional> host-statistics <replaceable>yes_or_no</replaceable>; </optional>
<optional> host-statistics-max <replaceable>number</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> minimal-responses <replaceable>yes_or_no</replaceable>; </optional>
<optional> multiple-cnames <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> <optional> notify <replaceable>yes_or_no</replaceable> | <replaceable>explicit</replaceable> | <replaceable>master-only</replaceable>; </optional>
...@@ -6196,6 +6197,30 @@ options { ...@@ -6196,6 +6197,30 @@ options {
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><command>multiple-cnames</command></term> <term><command>multiple-cnames</command></term>
<listitem> <listitem>
......
...@@ -484,6 +484,16 @@ ...@@ -484,6 +484,16 @@
when a system's clock needs to be reset backwards. when a system's clock needs to be reset backwards.
</para> </para>
</listitem> </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> </itemizedlist>
</section> </section>
......
...@@ -124,6 +124,7 @@ struct dns_view { ...@@ -124,6 +124,7 @@ struct dns_view {
isc_boolean_t auth_nxdomain; isc_boolean_t auth_nxdomain;
isc_boolean_t additionalfromcache; isc_boolean_t additionalfromcache;
isc_boolean_t additionalfromauth; isc_boolean_t additionalfromauth;
isc_boolean_t minimal_any;
isc_boolean_t minimalresponses; isc_boolean_t minimalresponses;
isc_boolean_t enablednssec; isc_boolean_t enablednssec;
isc_boolean_t enablevalidation; isc_boolean_t enablevalidation;
......
...@@ -190,6 +190,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, ...@@ -190,6 +190,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->enablednssec = ISC_TRUE; view->enablednssec = ISC_TRUE;
view->enablevalidation = ISC_TRUE; view->enablevalidation = ISC_TRUE;
view->acceptexpired = ISC_FALSE; view->acceptexpired = ISC_FALSE;
view->minimal_any = ISC_FALSE;
view->minimalresponses = ISC_FALSE; view->minimalresponses = ISC_FALSE;
view->transfer_format = dns_one_answer; view->transfer_format = dns_one_answer;
view->cacheacl = NULL; view->cacheacl = NULL;
......
...@@ -1685,6 +1685,7 @@ view_clauses[] = { ...@@ -1685,6 +1685,7 @@ view_clauses[] = {
{ "max-recursion-queries", &cfg_type_uint32, 0 }, { "max-recursion-queries", &cfg_type_uint32, 0 },
{ "max-udp-size", &cfg_type_uint32, 0 }, { "max-udp-size", &cfg_type_uint32, 0 },
{ "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
{ "minimal-any", &cfg_type_boolean, 0 },
{ "minimal-responses", &cfg_type_boolean, 0 }, { "minimal-responses", &cfg_type_boolean, 0 },
{ "nta-recheck", &cfg_type_ttlval, 0 }, { "nta-recheck", &cfg_type_ttlval, 0 },
{ "nta-lifetime", &cfg_type_ttlval, 0 }, { "nta-lifetime", &cfg_type_ttlval, 0 },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment