Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6014e73faa | ||
|
|
1c99e64a74 | ||
|
|
8532716753 | ||
|
|
c56a6d20f1 |
@@ -170,6 +170,8 @@ prio_type(dns_typepair_t type) {
|
||||
case DNS_SIGTYPE(dns_rdatatype_dname):
|
||||
case dns_rdatatype_svcb:
|
||||
case DNS_SIGTYPE(dns_rdatatype_svcb):
|
||||
case dns_rdatatype_deleg:
|
||||
case DNS_SIGTYPE(dns_rdatatype_deleg):
|
||||
case dns_rdatatype_https:
|
||||
case DNS_SIGTYPE(dns_rdatatype_https):
|
||||
case dns_rdatatype_dnskey:
|
||||
|
||||
+2
-1
@@ -422,7 +422,7 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
|
||||
/*
|
||||
* NS, SOA and DNSSKEY records are signed by their owner.
|
||||
* DS records are signed by the parent.
|
||||
* DS and DELEG records are signed by the parent.
|
||||
*/
|
||||
switch (set->type) {
|
||||
case dns_rdatatype_ns:
|
||||
@@ -434,6 +434,7 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
|
||||
}
|
||||
break;
|
||||
case dns_rdatatype_ds:
|
||||
case dns_rdatatype_deleg:
|
||||
if (dns_name_equal(name, &sig.signer)) {
|
||||
inc_stat(dns_dnssecstats_fail);
|
||||
return (DNS_R_SIGINVALID);
|
||||
|
||||
+1
-1
@@ -1895,7 +1895,7 @@ load_text(dns_loadctx_t *lctx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (type == dns_rdatatype_svcb &&
|
||||
if ((type == dns_rdatatype_svcb) &&
|
||||
(lctx->options & DNS_MASTER_ZONE) != 0 &&
|
||||
(lctx->options & DNS_MASTER_CHECKSVCB) != 0)
|
||||
{
|
||||
|
||||
@@ -1202,6 +1202,9 @@ auth_signed(dns_namelist_t *section) {
|
||||
case dns_rdatatype_nsec3:
|
||||
auth_dnssec |= 0x4;
|
||||
break;
|
||||
case dns_rdatatype_deleg:
|
||||
auth_dnssec |= 0x8;
|
||||
break;
|
||||
case dns_rdatatype_rrsig:
|
||||
break;
|
||||
default:
|
||||
@@ -1218,6 +1221,9 @@ auth_signed(dns_namelist_t *section) {
|
||||
case dns_rdatatype_nsec3:
|
||||
auth_rrsig |= 0x4;
|
||||
break;
|
||||
case dns_rdatatype_deleg:
|
||||
auth_rrsig |= 0x8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+9
-5
@@ -144,13 +144,16 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
|
||||
* 2) We set the RRSIG bit if we don't have
|
||||
* a NS record but do have other data.
|
||||
*/
|
||||
if (rdataset.type == dns_rdatatype_soa ||
|
||||
rdataset.type == dns_rdatatype_ds)
|
||||
{
|
||||
switch (rdataset.type) {
|
||||
case dns_rdatatype_soa:
|
||||
case dns_rdatatype_ds:
|
||||
case dns_rdatatype_deleg:
|
||||
need_rrsig = true;
|
||||
} else if (rdataset.type == dns_rdatatype_ns) {
|
||||
break;
|
||||
case dns_rdatatype_ns:
|
||||
found_ns = true;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -2106,6 +2109,7 @@ dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
|
||||
(dns_name_countlabels(closest) == 0 ||
|
||||
dns_name_issubdomain(qname, closest)) &&
|
||||
!dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
|
||||
!dns_nsec3_typepresent(&rdata, dns_rdatatype_deleg) &&
|
||||
!dns_nsec3_typepresent(&rdata,
|
||||
dns_rdatatype_dname) &&
|
||||
(dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
|
||||
|
||||
+30
-9
@@ -1984,6 +1984,8 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
qpc_search_t search;
|
||||
dns_slabheader_t *header = NULL;
|
||||
dns_slabheader_t *header_prev = NULL, *header_next = NULL;
|
||||
dns_slabheader_t *found_ns = NULL, *found_nssig = NULL;
|
||||
dns_slabheader_t *found_deleg = NULL, *found_delegsig = NULL;
|
||||
dns_slabheader_t *found = NULL, *foundsig = NULL;
|
||||
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
|
||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||
@@ -2072,21 +2074,30 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
* If we found a type we were looking for, remember
|
||||
* it.
|
||||
*/
|
||||
if (header->type == dns_rdatatype_ns) {
|
||||
switch (header->type) {
|
||||
case dns_rdatatype_ns:
|
||||
/*
|
||||
* Remember a NS rdataset even if we're
|
||||
* not specifically looking for it, because
|
||||
* we might need it later.
|
||||
*/
|
||||
found = header;
|
||||
} else if (header->type ==
|
||||
DNS_SIGTYPE(dns_rdatatype_ns))
|
||||
{
|
||||
found_ns = header;
|
||||
break;
|
||||
case DNS_SIGTYPE(dns_rdatatype_ns):
|
||||
/*
|
||||
* If we need the NS rdataset, we'll also
|
||||
* need its signature.
|
||||
*/
|
||||
foundsig = header;
|
||||
found_nssig = header;
|
||||
break;
|
||||
case dns_rdatatype_deleg:
|
||||
found_deleg = header;
|
||||
break;
|
||||
case DNS_SIGTYPE(dns_rdatatype_deleg):
|
||||
found_delegsig = header;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
header_prev = header;
|
||||
} else {
|
||||
@@ -2094,9 +2105,9 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NULL) {
|
||||
if (found_deleg == NULL && found_ns == NULL) {
|
||||
/*
|
||||
* No NS records here.
|
||||
* No NS nor DELEG records here.
|
||||
*/
|
||||
NODE_UNLOCK(lock, &nlocktype);
|
||||
result = find_deepest_zonecut(&search, node, nodep, foundname,
|
||||
@@ -2111,6 +2122,14 @@ findzonecut(dns_db_t *db, const dns_name_t *name, unsigned int options,
|
||||
*nodep = node;
|
||||
}
|
||||
|
||||
if (found_deleg) {
|
||||
found = found_deleg;
|
||||
foundsig = found_delegsig;
|
||||
} else if (found_ns) {
|
||||
found = found_ns;
|
||||
foundsig = found_nssig;
|
||||
}
|
||||
|
||||
bindrdataset(search.qpdb, node, found, search.now, nlocktype, tlocktype,
|
||||
rdataset DNS__DB_FLARG_PASS);
|
||||
if (foundsig != NULL) {
|
||||
@@ -3107,7 +3126,9 @@ find_header:
|
||||
(header->type == dns_rdatatype_a ||
|
||||
header->type == dns_rdatatype_aaaa ||
|
||||
header->type == dns_rdatatype_ds ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_ds)) &&
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_ds) ||
|
||||
header->type == dns_rdatatype_deleg ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_deleg)) &&
|
||||
!header_nx && !newheader_nx &&
|
||||
header->trust >= newheader->trust &&
|
||||
dns_rdataslab_equal((unsigned char *)header,
|
||||
|
||||
+33
-13
@@ -3153,6 +3153,7 @@ check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
|
||||
dns_slabheader_t *header = NULL, *header_next = NULL;
|
||||
dns_slabheader_t *dname_header = NULL, *sigdname_header = NULL;
|
||||
dns_slabheader_t *ns_header = NULL;
|
||||
dns_slabheader_t *deleg_header = NULL, *sigdeleg_header = NULL;
|
||||
dns_slabheader_t *found = NULL;
|
||||
isc_result_t result = DNS_R_CONTINUE;
|
||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||
@@ -3166,6 +3167,8 @@ check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
|
||||
for (header = node->data; header != NULL; header = header_next) {
|
||||
header_next = header->next;
|
||||
if (header->type == dns_rdatatype_ns ||
|
||||
header->type == dns_rdatatype_deleg ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_deleg) ||
|
||||
header->type == dns_rdatatype_dname ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_dname))
|
||||
{
|
||||
@@ -3181,22 +3184,35 @@ check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
|
||||
header = header->down;
|
||||
}
|
||||
} while (header != NULL);
|
||||
if (header != NULL) {
|
||||
if (header->type == dns_rdatatype_dname) {
|
||||
dname_header = header;
|
||||
} else if (header->type ==
|
||||
DNS_SIGTYPE(dns_rdatatype_dname))
|
||||
{
|
||||
sigdname_header = header;
|
||||
} else if (node != search->qpdb->origin ||
|
||||
IS_STUB(search->qpdb))
|
||||
{
|
||||
if (header == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (header->type) {
|
||||
case dns_rdatatype_dname:
|
||||
dname_header = header;
|
||||
break;
|
||||
case DNS_SIGTYPE(dns_rdatatype_dname):
|
||||
sigdname_header = header;
|
||||
break;
|
||||
case dns_rdatatype_deleg:
|
||||
if (node != search->qpdb->origin) {
|
||||
deleg_header = header;
|
||||
}
|
||||
break;
|
||||
case DNS_SIGTYPE(dns_rdatatype_deleg):
|
||||
sigdeleg_header = header;
|
||||
break;
|
||||
case dns_rdatatype_ns:
|
||||
if (node != search->qpdb->origin || IS_STUB(search->qpdb)) {
|
||||
/*
|
||||
* We've found an NS rdataset that
|
||||
* isn't at the origin node.
|
||||
* We've found an NS rdataset that isn't at the origin node.
|
||||
*/
|
||||
ns_header = header;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3204,7 +3220,11 @@ check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
|
||||
/*
|
||||
* Did we find anything?
|
||||
*/
|
||||
if (!IS_STUB(search->qpdb) && ns_header != NULL) {
|
||||
if (deleg_header != NULL) {
|
||||
/* DELEG has precedence over both NS and DNAME */
|
||||
found = deleg_header;
|
||||
search->zonecut_sigheader = sigdeleg_header;
|
||||
} else if (!IS_STUB(search->qpdb) && ns_header != NULL) {
|
||||
/*
|
||||
* Note that NS has precedence over DNAME if both exist
|
||||
* in a zone. Otherwise DNAME take precedence over NS.
|
||||
|
||||
+3
-1
@@ -2884,7 +2884,9 @@ find_header:
|
||||
(header->type == dns_rdatatype_a ||
|
||||
header->type == dns_rdatatype_aaaa ||
|
||||
header->type == dns_rdatatype_ds ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_ds)) &&
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_ds) ||
|
||||
header->type == dns_rdatatype_deleg ||
|
||||
header->type == DNS_SIGTYPE(dns_rdatatype_deleg)) &&
|
||||
!header_nx && !newheader_nx &&
|
||||
header->trust >= newheader->trust &&
|
||||
dns_rdataslab_equal((unsigned char *)header,
|
||||
|
||||
+4
-4
@@ -88,7 +88,7 @@
|
||||
#define ARGS_FROMTEXT \
|
||||
int rdclass, dns_rdatatype_t type, isc_lex_t *lexer, \
|
||||
const dns_name_t *origin, unsigned int options, \
|
||||
isc_buffer_t *target, dns_rdatacallbacks_t *callbacks
|
||||
isc_buffer_t *target, dns_rdatacallbacks_t *callbacks ISC_ATTR_UNUSED
|
||||
|
||||
#define CALL_FROMTEXT rdclass, type, lexer, origin, options, target, callbacks
|
||||
|
||||
@@ -136,8 +136,8 @@
|
||||
#define CALL_DIGEST rdata, digest, arg
|
||||
|
||||
#define ARGS_CHECKOWNER \
|
||||
const dns_name_t *name, dns_rdataclass_t rdclass, \
|
||||
dns_rdatatype_t type, bool wildcard
|
||||
const dns_name_t *name ISC_ATTR_UNUSED, dns_rdataclass_t rdclass, \
|
||||
dns_rdatatype_t type, bool wildcard ISC_ATTR_UNUSED
|
||||
|
||||
#define CALL_CHECKOWNER name, rdclass, type, wildcard
|
||||
|
||||
@@ -2448,7 +2448,7 @@ dns_rdata_checksvcb(const dns_name_t *owner, const dns_rdata_t *rdata) {
|
||||
|
||||
REQUIRE(owner != NULL);
|
||||
REQUIRE(rdata != NULL);
|
||||
REQUIRE(rdata->type == dns_rdatatype_svcb);
|
||||
REQUIRE(rdata->type == dns_rdatatype_svcb || rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
|
||||
|
||||
result = dns_rdata_tostruct(rdata, &svcb, NULL);
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
/* draft-wesplaap-deleg-01 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <isc/result.h>
|
||||
|
||||
#define RRTYPE_DELEG_ATTRIBUTES (DNS_RDATATYPEATTR_FOLLOWADDITIONAL)
|
||||
|
||||
static isc_result_t
|
||||
fromtext_in_deleg(ARGS_FROMTEXT) {
|
||||
REQUIRE(type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_fromtext_in_svcb(CALL_FROMTEXT));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
totext_in_deleg(ARGS_TOTEXT) {
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata->rdclass == dns_rdataclass_in);
|
||||
REQUIRE(rdata->length != 0);
|
||||
|
||||
return (generic_totext_in_svcb(CALL_TOTEXT));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
fromwire_in_deleg(ARGS_FROMWIRE) {
|
||||
REQUIRE(type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_fromwire_in_svcb(CALL_FROMWIRE));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
towire_in_deleg(ARGS_TOWIRE) {
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata->length != 0);
|
||||
|
||||
return (generic_towire_in_svcb(CALL_TOWIRE));
|
||||
}
|
||||
|
||||
static int
|
||||
compare_in_deleg(ARGS_COMPARE) {
|
||||
isc_region_t region1;
|
||||
isc_region_t region2;
|
||||
|
||||
REQUIRE(rdata1->type == rdata2->type);
|
||||
REQUIRE(rdata1->rdclass == rdata2->rdclass);
|
||||
REQUIRE(rdata1->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata1->rdclass == dns_rdataclass_in);
|
||||
REQUIRE(rdata1->length != 0);
|
||||
REQUIRE(rdata2->length != 0);
|
||||
|
||||
dns_rdata_toregion(rdata1, ®ion1);
|
||||
dns_rdata_toregion(rdata2, ®ion2);
|
||||
|
||||
return (isc_region_compare(®ion1, ®ion2));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
fromstruct_in_deleg(ARGS_FROMSTRUCT) {
|
||||
dns_rdata_in_deleg_t *deleg = source;
|
||||
|
||||
REQUIRE(type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdclass == dns_rdataclass_in);
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(deleg->common.rdtype == type);
|
||||
REQUIRE(deleg->common.rdclass == rdclass);
|
||||
|
||||
return (generic_fromstruct_in_svcb(CALL_FROMSTRUCT));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
tostruct_in_deleg(ARGS_TOSTRUCT) {
|
||||
dns_rdata_in_deleg_t *deleg = target;
|
||||
|
||||
REQUIRE(rdata->rdclass == dns_rdataclass_in);
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(rdata->length != 0);
|
||||
|
||||
return (generic_tostruct_in_svcb(CALL_TOSTRUCT));
|
||||
}
|
||||
|
||||
static void
|
||||
freestruct_in_deleg(ARGS_FREESTRUCT) {
|
||||
dns_rdata_in_deleg_t *deleg = source;
|
||||
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(deleg->common.rdclass == dns_rdataclass_in);
|
||||
REQUIRE(deleg->common.rdtype == dns_rdatatype_deleg);
|
||||
|
||||
generic_freestruct_in_svcb(CALL_FREESTRUCT);
|
||||
}
|
||||
|
||||
|
||||
static isc_result_t
|
||||
additionaldata_in_deleg(ARGS_ADDLDATA) {
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata->rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_additionaldata_in_svcb(CALL_ADDLDATA));
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
digest_in_deleg(ARGS_DIGEST) {
|
||||
isc_region_t region1;
|
||||
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata->rdclass == dns_rdataclass_in);
|
||||
|
||||
dns_rdata_toregion(rdata, ®ion1);
|
||||
return ((digest)(arg, ®ion1));
|
||||
}
|
||||
|
||||
static bool
|
||||
checkowner_in_deleg(ARGS_CHECKOWNER) {
|
||||
REQUIRE(type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdclass == dns_rdataclass_in);
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
static bool
|
||||
checknames_in_deleg(ARGS_CHECKNAMES) {
|
||||
REQUIRE(rdata->type == dns_rdatatype_deleg);
|
||||
REQUIRE(rdata->rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_checknames_in_svcb(CALL_CHECKNAMES));
|
||||
}
|
||||
|
||||
static int
|
||||
casecompare_in_deleg(ARGS_COMPARE) {
|
||||
return (compare_in_deleg(rdata1, rdata2));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdata_in_deleg_first(dns_rdata_in_deleg_t *deleg) {
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(deleg->common.rdtype == dns_rdatatype_deleg);
|
||||
REQUIRE(deleg->common.rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_rdata_in_svcb_first(deleg));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_rdata_in_deleg_next(dns_rdata_in_deleg_t *deleg) {
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(deleg->common.rdtype == dns_rdatatype_deleg);
|
||||
REQUIRE(deleg->common.rdclass == dns_rdataclass_in);
|
||||
|
||||
return (generic_rdata_in_svcb_next(deleg));
|
||||
}
|
||||
|
||||
void
|
||||
dns_rdata_in_deleg_current(dns_rdata_in_deleg_t *deleg, isc_region_t *region) {
|
||||
REQUIRE(deleg != NULL);
|
||||
REQUIRE(deleg->common.rdtype == dns_rdatatype_deleg);
|
||||
REQUIRE(deleg->common.rdclass == dns_rdataclass_in);
|
||||
REQUIRE(region != NULL);
|
||||
|
||||
generic_rdata_in_svcb_current(deleg, region);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*!
|
||||
* \brief Per draft-wesplaap-deleg-01
|
||||
*/
|
||||
|
||||
#include <isc/result.h>
|
||||
#include <isc/region.h>
|
||||
|
||||
typedef struct dns_rdata_in_svcb dns_rdata_in_deleg_t;
|
||||
|
||||
isc_result_t
|
||||
dns_rdata_in_deleg_first(dns_rdata_in_deleg_t *);
|
||||
|
||||
isc_result_t
|
||||
dns_rdata_in_deleg_next(dns_rdata_in_deleg_t *);
|
||||
|
||||
void
|
||||
dns_rdata_in_deleg_current(dns_rdata_in_deleg_t *, isc_region_t *);
|
||||
+131
-30
@@ -3417,7 +3417,6 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
|
||||
dns_forwarder_t *fwd;
|
||||
dns_adbaddrinfo_t *ai;
|
||||
bool all_bad;
|
||||
dns_rdata_ns_t ns;
|
||||
bool need_alternate = false;
|
||||
bool all_spilled = false;
|
||||
unsigned int no_addresses = 0;
|
||||
@@ -3600,35 +3599,76 @@ normal_nses:
|
||||
bool overquota = false;
|
||||
unsigned int static_stub = 0;
|
||||
|
||||
dns_rdataset_current(&fctx->nameservers, &rdata);
|
||||
/*
|
||||
* Extract the name from the NS record.
|
||||
*/
|
||||
result = dns_rdata_tostruct(&rdata, &ns, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
switch (fctx->nameservers.type) {
|
||||
case dns_rdatatype_ns: { /**/ }
|
||||
dns_rdata_ns_t ns;
|
||||
|
||||
if (STATICSTUB(&fctx->nameservers) &&
|
||||
dns_name_equal(&ns.name, fctx->domain))
|
||||
{
|
||||
static_stub = DNS_ADBFIND_STATICSTUB;
|
||||
}
|
||||
dns_rdataset_current(&fctx->nameservers, &rdata);
|
||||
/*
|
||||
* Extract the name from the NS record.
|
||||
*/
|
||||
result = dns_rdata_tostruct(&rdata, &ns, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (no_addresses > NS_FAIL_LIMIT &&
|
||||
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
|
||||
{
|
||||
stdoptions |= DNS_ADBFIND_NOFETCH;
|
||||
}
|
||||
findname(fctx, &ns.name, 0, stdoptions | static_stub, 0, now,
|
||||
&overquota, &need_alternate, &no_addresses);
|
||||
if (STATICSTUB(&fctx->nameservers) &&
|
||||
dns_name_equal(&ns.name, fctx->domain))
|
||||
{
|
||||
static_stub = DNS_ADBFIND_STATICSTUB;
|
||||
}
|
||||
|
||||
if (!overquota) {
|
||||
all_spilled = false;
|
||||
}
|
||||
if (no_addresses > NS_FAIL_LIMIT &&
|
||||
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
|
||||
{
|
||||
stdoptions |= DNS_ADBFIND_NOFETCH;
|
||||
}
|
||||
findname(fctx, &ns.name, 0, stdoptions | static_stub, 0, now,
|
||||
&overquota, &need_alternate, &no_addresses);
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdata_freestruct(&ns);
|
||||
if (!overquota) {
|
||||
all_spilled = false;
|
||||
}
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdata_freestruct(&ns);
|
||||
break;
|
||||
case dns_rdatatype_deleg: { /**/ }
|
||||
dns_rdata_in_deleg_t deleg;
|
||||
|
||||
dns_rdataset_current(&fctx->nameservers, &rdata);
|
||||
/*
|
||||
* Extract the name from the NS record.
|
||||
*/
|
||||
result = dns_rdata_tostruct(&rdata, &deleg, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (STATICSTUB(&fctx->nameservers) &&
|
||||
dns_name_equal(&deleg.svcdomain, fctx->domain))
|
||||
{
|
||||
static_stub = DNS_ADBFIND_STATICSTUB;
|
||||
}
|
||||
|
||||
if (no_addresses > NS_FAIL_LIMIT &&
|
||||
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
|
||||
{
|
||||
stdoptions |= DNS_ADBFIND_NOFETCH;
|
||||
}
|
||||
findname(fctx, &deleg.svcdomain, 0, stdoptions | static_stub, 0, now,
|
||||
&overquota, &need_alternate, &no_addresses);
|
||||
|
||||
if (!overquota) {
|
||||
all_spilled = false;
|
||||
}
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdata_freestruct(&ns);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (++ns_processed >= NS_PROCESSING_LIMIT) {
|
||||
result = ISC_R_NOMORE;
|
||||
@@ -3713,7 +3753,8 @@ out:
|
||||
result = isc_time_nowplusinterval(&expire, &i);
|
||||
if (badcache &&
|
||||
(fctx->type == dns_rdatatype_dnskey ||
|
||||
fctx->type == dns_rdatatype_ds) &&
|
||||
fctx->type == dns_rdatatype_ds ||
|
||||
fctx->type == dns_rdatatype_deleg) &&
|
||||
result == ISC_R_SUCCESS)
|
||||
{
|
||||
dns_resolver_addbadcache(res, fctx->name,
|
||||
@@ -5314,7 +5355,8 @@ validated(void *arg) {
|
||||
tresult = isc_time_nowplusinterval(&expire, &i);
|
||||
if (negative &&
|
||||
(fctx->type == dns_rdatatype_dnskey ||
|
||||
fctx->type == dns_rdatatype_ds) &&
|
||||
fctx->type == dns_rdatatype_ds ||
|
||||
fctx->type == dns_rdatatype_deleg) &&
|
||||
tresult == ISC_R_SUCCESS)
|
||||
{
|
||||
dns_resolver_addbadcache(res, fctx->name,
|
||||
@@ -5337,6 +5379,7 @@ validated(void *arg) {
|
||||
|
||||
/*
|
||||
* Cache DS NXDOMAIN separately to other types.
|
||||
* FIXME: What to do about DELEG?
|
||||
*/
|
||||
if (message->rcode == dns_rcode_nxdomain &&
|
||||
fctx->type != dns_rdatatype_ds)
|
||||
@@ -8879,7 +8922,7 @@ rctx_answer_none(respctx_t *rctx) {
|
||||
*/
|
||||
if (rctx->negative &&
|
||||
rctx->query->rmessage->rcode == dns_rcode_noerror &&
|
||||
fctx->type == dns_rdatatype_ds && rctx->soa_name != NULL &&
|
||||
(fctx->type == dns_rdatatype_ds || fctx->type == dns_rdatatype_deleg) && rctx->soa_name != NULL &&
|
||||
dns_name_equal(rctx->soa_name, fctx->name) &&
|
||||
!dns_name_equal(fctx->name, dns_rootname))
|
||||
{
|
||||
@@ -9097,6 +9140,7 @@ rctx_ncache(respctx_t *rctx) {
|
||||
|
||||
/*
|
||||
* Cache DS NXDOMAIN separately to other types.
|
||||
* TODO: What to do about DELEG?
|
||||
*/
|
||||
if (rctx->query->rmessage->rcode == dns_rcode_nxdomain &&
|
||||
fctx->type != dns_rdatatype_ds)
|
||||
@@ -9251,6 +9295,63 @@ rctx_authority_dnssec(respctx_t *rctx) {
|
||||
rdataset->trust = dns_trust_additional;
|
||||
}
|
||||
break;
|
||||
case dns_rdatatype_deleg:
|
||||
/*
|
||||
* DELEG or SIG DELEG.
|
||||
*
|
||||
* These should only be here if this is
|
||||
* a referral, and there should only be
|
||||
* one DS RRset.
|
||||
*/
|
||||
if (rctx->ns_name == NULL) {
|
||||
log_formerr(fctx, "DELEG with no "
|
||||
"referral");
|
||||
rctx->result = DNS_R_FORMERR;
|
||||
return (ISC_R_COMPLETE);
|
||||
}
|
||||
|
||||
if (rdataset->type == dns_rdatatype_deleg) {
|
||||
if (rctx->ds_name != NULL &&
|
||||
name != rctx->ds_name)
|
||||
{
|
||||
log_formerr(fctx, "DS doesn't "
|
||||
"match "
|
||||
"referral "
|
||||
"(NS)");
|
||||
rctx->result = DNS_R_FORMERR;
|
||||
return (ISC_R_COMPLETE);
|
||||
}
|
||||
rctx->ds_name = name;
|
||||
}
|
||||
|
||||
name->attributes.cache = true;
|
||||
rdataset->attributes |= DNS_RDATASETATTR_CACHE;
|
||||
|
||||
/* FIXME: NTA handling? */
|
||||
/* if ((fctx->options & DNS_FETCHOPT_NONTA) != 0) { */
|
||||
/* checknta = false; */
|
||||
/* } */
|
||||
if (fctx->res->view->enablevalidation) {
|
||||
result = issecuredomain(
|
||||
fctx->res->view, name,
|
||||
dns_rdatatype_ds, fctx->now,
|
||||
checknta, NULL, &secure_domain);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
if (secure_domain) {
|
||||
rdataset->trust =
|
||||
dns_trust_pending_answer;
|
||||
} else if (rctx->aa) {
|
||||
rdataset->trust =
|
||||
dns_trust_authauthority;
|
||||
} else if (ISFORWARDER(fctx->addrinfo)) {
|
||||
rdataset->trust = dns_trust_answer;
|
||||
} else {
|
||||
rdataset->trust = dns_trust_additional;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@@ -10450,7 +10551,7 @@ dns_resolver_createfetch(dns_resolver_t *res, const dns_name_t *name,
|
||||
/* XXXRTH Check for meta type */
|
||||
if (domain != NULL) {
|
||||
REQUIRE(DNS_RDATASET_VALID(nameservers));
|
||||
REQUIRE(nameservers->type == dns_rdatatype_ns);
|
||||
REQUIRE(nameservers->type == dns_rdatatype_ns || nameservers->type == dns_rdatatype_deleg);
|
||||
} else {
|
||||
REQUIRE(nameservers == NULL);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1413,7 +1413,7 @@ add_exposed_sigs(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db,
|
||||
* as they are handled elsewhere.
|
||||
*/
|
||||
if ((type == dns_rdatatype_rrsig) ||
|
||||
(cut && type != dns_rdatatype_ds))
|
||||
(cut && type != dns_rdatatype_ds && type != dns_rdatatype_deleg))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
+28
-8
@@ -3254,7 +3254,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
|
||||
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto checkfordname;
|
||||
goto checkfordeleg;
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
@@ -3268,6 +3268,24 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
|
||||
dns_zone_log(zone, level, "DS not at delegation point (%s)",
|
||||
namebuf);
|
||||
|
||||
checkfordeleg:
|
||||
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_deleg,
|
||||
0, 0, &rdataset, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto checkfordname;
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
|
||||
if (zone->type == dns_zone_primary) {
|
||||
level = ISC_LOG_ERROR;
|
||||
ok = false;
|
||||
} else {
|
||||
level = ISC_LOG_WARNING;
|
||||
}
|
||||
dns_name_format(name, namebuf, sizeof(namebuf));
|
||||
dns_zone_log(zone, level, "DELEG not at delegation point (%s)",
|
||||
namebuf);
|
||||
|
||||
checkfordname:
|
||||
result = dns_db_findrdataset(db, node, NULL,
|
||||
dns_rdatatype_dname, 0, 0,
|
||||
@@ -7520,7 +7538,7 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
||||
bool offlineksk = false;
|
||||
isc_buffer_t buffer;
|
||||
unsigned char data[1024];
|
||||
bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
|
||||
bool seen_soa = false, seen_ns = false, seen_rr = false, seen_nsec = false, seen_nsec3 = false, seen_ds = false, seen_deleg ISC_ATTR_UNUSED = false;
|
||||
|
||||
if (zone->kasp != NULL) {
|
||||
offlineksk = dns_kasp_offlineksk(zone->kasp);
|
||||
@@ -7536,7 +7554,6 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
isc_buffer_init(&buffer, data, sizeof(data));
|
||||
seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
|
||||
for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(iterator))
|
||||
{
|
||||
@@ -7547,6 +7564,8 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
||||
seen_ns = true;
|
||||
} else if (rdataset.type == dns_rdatatype_ds) {
|
||||
seen_ds = true;
|
||||
} else if (rdataset.type == dns_rdatatype_deleg) {
|
||||
seen_deleg = true;
|
||||
} else if (rdataset.type == dns_rdatatype_nsec) {
|
||||
seen_nsec = true;
|
||||
} else if (rdataset.type == dns_rdatatype_nsec3) {
|
||||
@@ -7616,7 +7635,7 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
|
||||
}
|
||||
}
|
||||
|
||||
if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds &&
|
||||
if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds && rdataset.type != dns_rdatatype_deleg &&
|
||||
rdataset.type != dns_rdatatype_nsec)
|
||||
{
|
||||
goto next_rdataset;
|
||||
@@ -8318,8 +8337,8 @@ zone_nsec3chain(dns_zone_t *zone) {
|
||||
unsigned int nkeys = 0;
|
||||
uint32_t nodes;
|
||||
bool unsecure = false;
|
||||
bool seen_soa, seen_ns, seen_dname, seen_ds;
|
||||
bool seen_nsec, seen_nsec3, seen_rr;
|
||||
bool seen_soa = false, seen_ns = false, seen_dname = false, seen_ds = false, seen_deleg ISC_ATTR_UNUSED = false;
|
||||
bool seen_nsec = false, seen_nsec3 = false, seen_rr = false;
|
||||
dns_rdatasetiter_t *iterator = NULL;
|
||||
bool buildnsecchain;
|
||||
bool updatensec = false;
|
||||
@@ -8498,7 +8517,6 @@ zone_nsec3chain(dns_zone_t *zone) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
|
||||
for (result = dns_rdatasetiter_first(iterator);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(iterator))
|
||||
@@ -8513,6 +8531,8 @@ zone_nsec3chain(dns_zone_t *zone) {
|
||||
seen_dname = true;
|
||||
} else if (rdataset.type == dns_rdatatype_ds) {
|
||||
seen_ds = true;
|
||||
} else if (rdataset.type == dns_rdatatype_deleg) {
|
||||
seen_deleg = true;
|
||||
} else if (rdataset.type == dns_rdatatype_nsec) {
|
||||
seen_nsec = true;
|
||||
}
|
||||
@@ -20940,7 +20960,7 @@ checkds_done(void *arg) {
|
||||
for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
|
||||
rdataset = ISC_LIST_NEXT(rdataset, link))
|
||||
{
|
||||
if (rdataset->type != dns_rdatatype_ds) {
|
||||
if (rdataset->type != dns_rdatatype_ds && rdataset->type != dns_rdatatype_deleg) {
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
||||
@@ -742,6 +742,7 @@ verifynsec3(const vctx_t *vctx, const dns_name_t *name,
|
||||
dns_rdatatype_nsec3, 0, 0,
|
||||
&rdataset, NULL);
|
||||
}
|
||||
/* FIXME: WTH does this do? */
|
||||
if (result != ISC_R_SUCCESS &&
|
||||
(!delegation || (empty && !optout) ||
|
||||
(!empty && dns_nsec_isset(types, dns_rdatatype_ds))))
|
||||
@@ -939,7 +940,7 @@ verifynode(vctx_t *vctx, const dns_name_t *name, dns_dbnode_t *node,
|
||||
* other than NSEC and DS is not signed at a delegation.
|
||||
*/
|
||||
if (rdataset.type != dns_rdatatype_rrsig &&
|
||||
(!delegation || rdataset.type == dns_rdatatype_ds ||
|
||||
(!delegation || rdataset.type == dns_rdatatype_ds || rdataset.type == dns_rdatatype_deleg ||
|
||||
rdataset.type == dns_rdatatype_nsec))
|
||||
{
|
||||
result = verifyset(vctx, &rdataset, name, node, dstkeys,
|
||||
|
||||
+165
-4
@@ -458,6 +458,9 @@ query_delegation_recurse(query_ctx_t *qctx);
|
||||
static void
|
||||
query_addds(query_ctx_t *qctx);
|
||||
|
||||
static void
|
||||
query_adddeleg(query_ctx_t *qctx);
|
||||
|
||||
static isc_result_t
|
||||
query_nodata(query_ctx_t *qctx, isc_result_t result);
|
||||
|
||||
@@ -5503,7 +5506,7 @@ ns__query_start(query_ctx_t *qctx) {
|
||||
qctx->qtype, qctx->options, &qctx->zone, &qctx->db,
|
||||
&qctx->version, &qctx->is_zone);
|
||||
if ((result != ISC_R_SUCCESS || !qctx->is_zone) &&
|
||||
qctx->qtype == dns_rdatatype_ds && !RECURSIONOK(qctx->client) &&
|
||||
(qctx->qtype == dns_rdatatype_ds || qctx->qtype == dns_rdatatype_deleg) && !RECURSIONOK(qctx->client) &&
|
||||
qctx->options.noexact)
|
||||
{
|
||||
/*
|
||||
@@ -6293,7 +6296,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
|
||||
/*
|
||||
* Invoke the resolver.
|
||||
*/
|
||||
REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
|
||||
REQUIRE(nameservers == NULL || (nameservers->type == dns_rdatatype_ns || nameservers->type == dns_rdatatype_deleg));
|
||||
REQUIRE(FETCH_RECTYPE_NORMAL(client) == NULL);
|
||||
|
||||
rdataset = ns_client_newrdataset(client);
|
||||
@@ -8516,7 +8519,8 @@ query_prepare_delegation_response(query_ctx_t *qctx) {
|
||||
|
||||
/*
|
||||
* qctx->fname could be released in query_addrrset(), so save a copy of
|
||||
* it here in case we need it.
|
||||
* it here in case we need it. The save name is used for both DS and
|
||||
* DELEG lookups.
|
||||
*/
|
||||
dns_fixedname_init(&qctx->dsname);
|
||||
dns_name_copy(qctx->fname, dns_fixedname_name(&qctx->dsname));
|
||||
@@ -8550,6 +8554,11 @@ query_prepare_delegation_response(query_ctx_t *qctx) {
|
||||
*/
|
||||
query_addds(qctx);
|
||||
|
||||
/*
|
||||
* Add DELEG/NSEC(3) record(s) if needed.
|
||||
*/
|
||||
query_adddeleg(qctx);
|
||||
|
||||
return (ns_query_done(qctx));
|
||||
|
||||
cleanup:
|
||||
@@ -8573,7 +8582,7 @@ query_zone_delegation(query_ctx_t *qctx) {
|
||||
* authoritative for the child zone
|
||||
*/
|
||||
if (!RECURSIONOK(qctx->client) &&
|
||||
(qctx->options.noexact && qctx->qtype == dns_rdatatype_ds))
|
||||
(qctx->options.noexact && (qctx->qtype == dns_rdatatype_ds || qctx->qtype == dns_rdatatype_deleg)))
|
||||
{
|
||||
dns_db_t *tdb = NULL;
|
||||
dns_zone_t *tzone = NULL;
|
||||
@@ -8955,6 +8964,158 @@ cleanup:
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
* Add DELEG/NSEC(3) record(s) if needed.
|
||||
*/
|
||||
static void
|
||||
query_adddeleg(query_ctx_t *qctx) {
|
||||
ns_client_t *client = qctx->client;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *fname = NULL;
|
||||
dns_name_t *rname = NULL;
|
||||
dns_name_t *name;
|
||||
dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;
|
||||
isc_buffer_t *dbuf, b;
|
||||
isc_result_t result;
|
||||
unsigned int count;
|
||||
|
||||
CTRACE(ISC_LOG_DEBUG(3), "query_adddeleg");
|
||||
|
||||
/*
|
||||
* DELEG not needed.
|
||||
*/
|
||||
if (!WANTDNSSEC(client)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll need some resources...
|
||||
*/
|
||||
rdataset = ns_client_newrdataset(client);
|
||||
sigrdataset = ns_client_newrdataset(client);
|
||||
|
||||
/*
|
||||
* Look for the DELEG record, which may or may not be present.
|
||||
*/
|
||||
result = dns_db_findrdataset(qctx->db, qctx->node, qctx->version,
|
||||
dns_rdatatype_deleg, 0, client->now, rdataset,
|
||||
sigrdataset);
|
||||
/*
|
||||
* If we didn't find it, look for an NSEC.
|
||||
*/
|
||||
if (result == ISC_R_NOTFOUND) {
|
||||
result = dns_db_findrdataset(
|
||||
qctx->db, qctx->node, qctx->version, dns_rdatatype_nsec,
|
||||
0, client->now, rdataset, sigrdataset);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
|
||||
goto addnsec3;
|
||||
}
|
||||
if (!dns_rdataset_isassociated(rdataset) ||
|
||||
!dns_rdataset_isassociated(sigrdataset))
|
||||
{
|
||||
goto addnsec3;
|
||||
}
|
||||
|
||||
/*
|
||||
* We've already added the NS record, so if the name's not there,
|
||||
* we have other problems.
|
||||
*/
|
||||
result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the delegation in the response message - it is not necessarily
|
||||
* the first name in the AUTHORITY section when wildcard processing is
|
||||
* involved.
|
||||
*/
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
rname = NULL;
|
||||
dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
|
||||
&rname);
|
||||
result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
result = dns_message_nextname(client->message,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the relevant RRset (DELEG or NSEC) to the delegation.
|
||||
*/
|
||||
query_addrrset(qctx, &rname, &rdataset, &sigrdataset, NULL,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
goto cleanup;
|
||||
|
||||
addnsec3:
|
||||
if (!dns_db_iszone(qctx->db)) {
|
||||
goto cleanup;
|
||||
}
|
||||
/*
|
||||
* Add the NSEC3 which proves the DELEG does not exist.
|
||||
*/
|
||||
dbuf = ns_client_getnamebuf(client);
|
||||
fname = ns_client_newname(client, dbuf, &b);
|
||||
dns_fixedname_init(&fixed);
|
||||
if (dns_rdataset_isassociated(rdataset)) {
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
}
|
||||
if (dns_rdataset_isassociated(sigrdataset)) {
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
}
|
||||
name = dns_fixedname_name(&qctx->dsname);
|
||||
query_findclosestnsec3(name, qctx->db, qctx->version, client, rdataset,
|
||||
sigrdataset, fname, true,
|
||||
dns_fixedname_name(&fixed));
|
||||
if (!dns_rdataset_isassociated(rdataset)) {
|
||||
goto cleanup;
|
||||
}
|
||||
query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
/*
|
||||
* Did we find the closest provable encloser instead?
|
||||
* If so add the nearest to the closest provable encloser.
|
||||
*/
|
||||
if (!dns_name_equal(name, dns_fixedname_name(&fixed))) {
|
||||
count = dns_name_countlabels(dns_fixedname_name(&fixed)) + 1;
|
||||
dns_name_getlabelsequence(name,
|
||||
dns_name_countlabels(name) - count,
|
||||
count, dns_fixedname_name(&fixed));
|
||||
fixfname(client, &fname, &dbuf, &b);
|
||||
fixrdataset(client, &rdataset);
|
||||
fixrdataset(client, &sigrdataset);
|
||||
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
query_findclosestnsec3(dns_fixedname_name(&fixed), qctx->db,
|
||||
qctx->version, client, rdataset,
|
||||
sigrdataset, fname, false, NULL);
|
||||
if (!dns_rdataset_isassociated(rdataset)) {
|
||||
goto cleanup;
|
||||
}
|
||||
query_addrrset(qctx, &fname, &rdataset, &sigrdataset, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (rdataset != NULL) {
|
||||
ns_client_putrdataset(client, &rdataset);
|
||||
}
|
||||
if (sigrdataset != NULL) {
|
||||
ns_client_putrdataset(client, &sigrdataset);
|
||||
}
|
||||
if (fname != NULL) {
|
||||
ns_client_releasename(client, &fname);
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
* Handle authoritative NOERROR/NODATA responses.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user