Commit fad7b2a6 authored by Evan Hunt's avatar Evan Hunt
Browse files

Merge branch '817-out-of-zone-additional' into 'master'

out of zone additional data

Closes #817

See merge request !1366
parents d134dd9c 5071e43c
Pipeline #13465 passed with stages
in 59 seconds
5211. [bug] Allow out-of-zone additional data to be included
in authoritative responses if recursion is allowed
and "minimal-responses" is disabled. This behavior
was inadvertently removed in change #4605. [GL #817]
5210. [bug] When dnstap is enabled and recursion is not
available, incoming queries are now logged
as "auth". Previously, this depended on whether
......
......@@ -10,7 +10,7 @@
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 127.0.0.0
ns1 A 10.53.0.1
nap IN NAPTR 50 50 "S" "SIPS+D2T" "" server
server SRV 0 0 5061 server
......
......@@ -10,7 +10,7 @@
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 127.0.0.0
ns1 A 10.53.0.1
nap IN NAPTR 50 50 "S" "SIPS+D2T" "" server.hang3a.zone.
www AAAA 192::99
......
......@@ -10,7 +10,7 @@
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 127.0.0.0
ns1 A 10.53.0.1
ns1 NID 2 0:0:0:0
ns1 L64 2 0:0:0:0
......
......@@ -10,7 +10,8 @@
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 127.0.0.0
NS ns1.rt2.example.
ns1 A 10.53.0.1
rt RT 2 www
www AAAA 192::99
......
......@@ -10,7 +10,7 @@
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 127.0.0.0
ns1 A 10.53.0.1
rt RT 2 www.hang3b.zone.
server SRV 0 0 5061 server
......
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
NS ns1.ex2.
ns1 A 10.53.0.1
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 86400
@ IN SOA ns1 hostmaster ( 2 8H 2H 4W 1D );
NS ns1
ns1 A 10.53.0.1
......@@ -21,9 +21,20 @@ options {
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
minimal-responses no;
};
zone "." {
type hint;
file "root.hint";
};
zone "ex" {
type master;
file "ex.db";
};
zone "ex2" {
type master;
file "ex2.db";
};
......@@ -228,7 +228,7 @@ n=`expr $n + 1`
echo_i "testing with 'minimal-any no;' ($n)"
ret=0
$DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 > dig.out.$n || ret=1
grep "ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo_i " failed"; status=1
fi
......@@ -322,5 +322,23 @@ if [ $ret -eq 1 ] ; then
echo_i " failed"; status=1
fi
n=`expr $n + 1`
echo_i "testing out-of-zone additional data from auth zones (authoritative) ($n)"
ret=0
$DIG $DIGOPTS -t NS rt.example @10.53.0.1 > dig.out.$n || ret=1
grep "ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo_i " failed"; status=1
fi
n=`expr $n + 1`
echo_i "testing out-of-zone additional data from auth zones (recursive) ($n)"
ret=0
$DIG $DIGOPTS -t NS ex @10.53.0.3 > dig.out.$n || ret=1
grep "ADDITIONAL: 3" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo_i " failed"; status=1
fi
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
......@@ -5809,30 +5809,55 @@ options {
<term><command>minimal-responses</command></term>
<listitem>
<para>
If set to <userinput>yes</userinput>, then when generating
responses the server will only add records to the authority
and additional data sections when they are required (e.g.
delegations, negative responses). This may improve the
performance of the server.
</para>
<para>
When set to <userinput>no-auth</userinput>, the
server will omit records from the authority section
unless they are required, but it may still add
records to the additional section. When set to
<userinput>no-auth-recursive</userinput>, this
is only done if the query is recursive. When the
query is not recursive, the effect is same as if
<userinput>no</userinput> was specified. These
settings are useful when answering stub clients,
which usually ignore the authority section.
<userinput>no-auth-recursive</userinput> is
designed for mixed-mode servers which handle
both authoritative and recursive queries.
</para>
<para>
The default is
<userinput>no-auth-recursive</userinput>.
This option controls the addition of records to the
authority and additional sections of responses. Such
records may be included in responses to be helpful
to clients; for example, NS or MX records may
have associated address records included in the additional
section, obviating the need for a separate address lookup.
However, adding these records to responses is not mandatory
and requires additional database lookups, causing extra
latency when marshalling responses.
<command>minimal-responses</command> takes one of
four values:
</para>
<itemizedlist>
<listitem>
<userinput>no</userinput>: the server will be
as complete as possible when generating responses.
</listitem>
<listitem>
<userinput>yes</userinput>: the server will only add
records to the authority and additional sections when
such records are required by the DNS protocol (for
example, when returning delegations or negative
responses). This provides the best server performance
but may result in more client queries.
</listitem>
<listitem>
<userinput>no-auth</userinput>: the server
will omit records from the authority section except
when they are required, but it may still add records
to the additional section.
</listitem>
<listitem>
<userinput>no-auth-recursive</userinput>: the same
as <userinput>no-auth</userinput> when recursion is
requested in the query (RD=1), or the same as
<userinput>no</userinput> if recursion is not
requested.
</listitem>
</itemizedlist>
<para>
<userinput>no-auth</userinput> and
<userinput>no-auth-recursive</userinput> are useful when
answering stub clients, which usually ignore the
authority section. <userinput>no-auth-recursive</userinput>
is meant for use in mixed-mode servers that handle both
authoritative and recursive queries.
</para>
<para>
The default is <userinput>no-auth-recursive</userinput>.
</para>
</listitem>
</varlistentry>
......
......@@ -1442,6 +1442,175 @@ query_isduplicate(ns_client_t *client, dns_name_t *name,
return (false);
}
/*
* Look up data for given 'name' and 'type' in given 'version' of 'db' for
* 'client'. Called from query_additionalauth().
*
* If the lookup is successful:
*
* - store the node containing the result at 'nodep',
*
* - store the owner name of the returned node in 'fname',
*
* - if 'type' is not ANY, dns_db_findext() will put the exact rdataset being
* looked for in 'rdataset' and its signatures (if any) in 'sigrdataset',
*
* - if 'type' is ANY, dns_db_findext() will leave 'rdataset' and
* 'sigrdataset' disassociated and the returned node will be iterated in
* query_additional_cb().
*
* If the lookup is not successful:
*
* - 'nodep' will not be written to,
* - 'fname' may still be modified as it is passed to dns_db_findext(),
* - 'rdataset' and 'sigrdataset' will remain disassociated.
*/
static isc_result_t
query_additionalauthfind(dns_db_t *db, dns_dbversion_t *version,
const dns_name_t *name, dns_rdatatype_t type,
ns_client_t *client, dns_dbnode_t **nodep,
dns_name_t *fname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset)
{
dns_clientinfomethods_t cm;
dns_dbnode_t *node = NULL;
dns_clientinfo_t ci;
isc_result_t result;
dns_clientinfomethods_init(&cm, ns_client_sourceip);
dns_clientinfo_init(&ci, client, NULL);
/*
* Since we are looking for authoritative data, we do not set
* the GLUEOK flag. Glue will be looked for later, but not
* necessarily in the same database.
*/
result = dns_db_findext(db, name, version, type,
client->query.dboptions, client->now, &node,
fname, &cm, &ci, rdataset, sigrdataset);
if (result != ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(rdataset)) {
dns_rdataset_disassociate(rdataset);
}
if (sigrdataset != NULL &&
dns_rdataset_isassociated(sigrdataset))
{
dns_rdataset_disassociate(sigrdataset);
}
if (node != NULL) {
dns_db_detachnode(db, &node);
}
return (result);
}
/*
* Do not return signatures if the zone is not fully signed.
*/
if (sigrdataset != NULL && !dns_db_issecure(db) &&
dns_rdataset_isassociated(sigrdataset))
{
dns_rdataset_disassociate(sigrdataset);
}
*nodep = node;
return (ISC_R_SUCCESS);
}
/*
* For query context 'qctx', try finding authoritative additional data for
* given 'name' and 'type'. Called from query_additional_cb().
*
* If successful:
*
* - store pointers to the database and node which contain the result in
* 'dbp' and 'nodep', respectively,
*
* - store the owner name of the returned node in 'fname',
*
* - potentially bind 'rdataset' and 'sigrdataset', as explained in the
* comment for query_additionalauthfind().
*
* If unsuccessful:
*
* - 'dbp' and 'nodep' will not be written to,
* - 'fname' may still be modified as it is passed to dns_db_findext(),
* - 'rdataset' and 'sigrdataset' will remain disassociated.
*/
static isc_result_t
query_additionalauth(query_ctx_t *qctx, const dns_name_t *name,
dns_rdatatype_t type, dns_db_t **dbp,
dns_dbnode_t **nodep, dns_name_t *fname,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
ns_client_t *client = qctx->client;
ns_dbversion_t *dbversion = NULL;
dns_dbversion_t *version = NULL;
dns_dbnode_t *node = NULL;
dns_zone_t *zone = NULL;
dns_db_t *db = NULL;
isc_result_t result;
/*
* First, look within the same zone database for authoritative
* additional data.
*/
if (!client->query.authdbset || client->query.authdb == NULL) {
return (ISC_R_NOTFOUND);
}
dbversion = ns_client_findversion(client, client->query.authdb);
if (dbversion == NULL) {
return (ISC_R_NOTFOUND);
}
dns_db_attach(client->query.authdb, &db);
version = dbversion->version;
CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: same zone");
result = query_additionalauthfind(db, version, name, type, client,
&node, fname, rdataset, sigrdataset);
if (result != ISC_R_SUCCESS &&
qctx->view->minimalresponses == dns_minimal_no &&
RECURSIONOK(client))
{
/*
* If we aren't doing response minimization and recursion is
* allowed, we can try and see if any other zone matches.
*/
version = NULL;
dns_db_detach(&db);
result = query_getzonedb(client, name, type, DNS_GETDB_NOLOG,
&zone, &db, &version);
if (result != ISC_R_SUCCESS) {
return (result);
}
dns_zone_detach(&zone);
CTRACE(ISC_LOG_DEBUG(3), "query_additionalauth: other zone");
result = query_additionalauthfind(db, version, name, type,
client, &node, fname,
rdataset, sigrdataset);
}
if (result != ISC_R_SUCCESS) {
dns_db_detach(&db);
} else {
*nodep = node;
node = NULL;
*dbp = db;
db = NULL;
}
return (result);
}
static isc_result_t
query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
query_ctx_t *qctx = arg;
......@@ -1515,58 +1684,17 @@ query_additional_cb(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) {
}
/*
* Look within the same zone database for authoritative
* additional data.
* First, look for authoritative additional data.
*/
if (!client->query.authdbset || client->query.authdb == NULL) {
goto try_cache;
}
dbversion = ns_client_findversion(client, client->query.authdb);
if (dbversion == NULL) {
goto try_cache;
}
dns_db_attach(client->query.authdb, &db);
version = dbversion->version;
CTRACE(ISC_LOG_DEBUG(3), "query_additional_cb: db_find");
/*
* Since we are looking for authoritative data, we do not set
* the GLUEOK flag. Glue will be looked for later, but not
* necessarily in the same database.
*/
result = dns_db_findext(db, name, version, type,
client->query.dboptions,
client->now, &node, fname, &cm, &ci,
rdataset, sigrdataset);
result = query_additionalauth(qctx, name, type, &db, &node, fname,
rdataset, sigrdataset);
if (result == ISC_R_SUCCESS) {
if (sigrdataset != NULL && !dns_db_issecure(db) &&
dns_rdataset_isassociated(sigrdataset))
{
dns_rdataset_disassociate(sigrdataset);
}
goto found;
}
if (dns_rdataset_isassociated(rdataset)) {
dns_rdataset_disassociate(rdataset);
}
if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) {
dns_rdataset_disassociate(sigrdataset);
}
if (node != NULL) {
dns_db_detachnode(db, &node);
}
version = NULL;
dns_db_detach(&db);
/*
* No authoritative data was found. The cache is our next best bet.
*/
try_cache:
if (!qctx->view->recursion) {
goto try_glue;
}
......
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