dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
const dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
dns_name_t *zonename, bool *exists, bool *data,
- bool *optout, bool *unknown, bool *setclosest,
- bool *setnearest, dns_name_t *closest,
- dns_name_t *nearest, dns_nseclog_t logit, void *arg);
+ bool *optout, bool *unknown, bool *setnearest,
+ dns_name_t *closest, dns_name_t *nearest,
+ dns_nseclog_t logit, void *arg);
dns__rdatalist_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg,
dns_rdataset_t *negsig DNS__DB_FLARG);
-isc_result_t
-dns__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name);
-isc_result_t
-dns__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig DNS__DB_FLARG);
void
dns__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name);
void
isc_result_t (*getnoqname)(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg,
dns_rdataset_t *negsig DNS__DB_FLARG);
- isc_result_t (*addclosest)(dns_rdataset_t *rdataset, dns_name_t *name);
- isc_result_t (*getclosest)(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig DNS__DB_FLARG);
void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust);
void (*expire)(dns_rdataset_t *rdataset DNS__DB_FLARG);
void (*clearprefetch)(dns_rdataset_t *rdataset);
bool checknames : 1; /*%< Used by resolver. */
bool required : 1;
bool resign : 1;
- bool closest : 1;
bool optout : 1; /*%< OPTOUT proof */
bool negative : 1;
bool prefetch : 1;
* a QP database, 'raw' will generally point to the
* memory immediately following a slabheader. (There
* is an exception in the case of rdatasets returned by
- * the `getnoqname` and `getclosest` methods; see
- * comments in rdataslab.c for details.)
+ * the `getnoqname` method; see comments in
+ * rdataslab.c for details.)
*/
struct {
dns_dbnode_t *node;
unsigned char *raw;
unsigned char *iter_pos;
unsigned int iter_count;
- dns_slabheader_proof_t *noqname, *closest;
+ dns_slabheader_proof_t *noqname;
} slab;
/*
* A vec rdataset provides access to an rdatavec. In
* a QP database, 'header' points to the vecheader
* structure. (There is an exception in the case of
- * rdatasets returned by the `getnoqname` and `getclosest`
- * methods; see comments in rdatavec.c for details.)
+ * rdatasets returned by the `getnoqname` method;
+ * see comments in rdatavec.c for details.)
*/
struct {
dns_vecheader_t *header;
struct dns_rdata *iter;
/*
- * These refer to names passed in by the caller of
- * dns_rdataset_addnoqname() and _addclosest()
+ * Refers to the name passed in by the caller of
+ * dns_rdataset_addnoqname().
*/
- struct dns_name *noqname, *closest;
+ struct dns_name *noqname;
dns_dbnode_t *node;
} rdlist;
};
* rdatasets.
*/
-#define dns_rdataset_getclosest(rdataset, name, nsec, nsecsig) \
- dns__rdataset_getclosest(rdataset, name, nsec, nsecsig DNS__DB_FILELINE)
-isc_result_t
-dns__rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *nsec,
- dns_rdataset_t *nsecsig DNS__DB_FLARG);
-/*%<
- * Return the closest encloser for this record.
- *
- * Requires:
- *\li 'rdataset' to be valid and 'closest' attribute to be set.
- *\li 'name' to be valid.
- *\li 'nsec' and 'nsecsig' to be valid and not associated.
- */
-
-isc_result_t
-dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name);
-/*%<
- * Associate a closest encloset proof with this record.
- * Sets 'closest' attribute if successful.
- * Adjusts the 'rdataset->ttl' to minimum of the 'rdataset->ttl' and
- * the 'nsec' and 'rrsig(nsec)' ttl.
- *
- * Requires:
- *\li 'rdataset' to be valid and 'closest' attribute to be set.
- *\li 'name' to be valid and have NSEC3 and RRSIG(NSEC3) rdatasets.
- */
-
void
dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
/*%<
dns_typepair_t typepair;
dns_slabheader_proof_t *noqname;
- dns_slabheader_proof_t *closest;
dns_slabheader_t *related;
#include <dst/dst.h>
-#define DNS_VALIDATOR_NOQNAMEPROOF 0
-#define DNS_VALIDATOR_NODATAPROOF 1
-#define DNS_VALIDATOR_NOWILDCARDPROOF 2
-#define DNS_VALIDATOR_CLOSESTENCLOSER 3
+typedef enum {
+ DNS_VALIDATOR_NOQNAMEPROOF = 0,
+ DNS_VALIDATOR_NODATAPROOF = 1,
+ DNS_VALIDATOR_NOWILDCARDPROOF = 2,
+ DNS_VALIDATOR_MAXPROOF
+} dns_validator_proof_t;
/*%
* A validator object represents a validation in progress.
/*
* Proofs to be cached.
*/
- dns_name_t *proofs[4];
+ dns_name_t *proofs[DNS_VALIDATOR_MAXPROOF];
/*
* Optout proof seen.
*/
dns_nsec3_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
const dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
dns_name_t *zonename, bool *exists, bool *data,
- bool *optout, bool *unknown, bool *setclosest,
- bool *setnearest, dns_name_t *closest,
- dns_name_t *nearest, dns_nseclog_t logit, void *arg) {
+ bool *optout, bool *unknown, bool *setnearest,
+ dns_name_t *closest, dns_name_t *nearest,
+ dns_nseclog_t logit, void *arg) {
char namebuf[DNS_NAME_FORMATSIZE];
dns_fixedname_t fzone;
dns_fixedname_t qfixed;
REQUIRE((exists == NULL && data == NULL) ||
(exists != NULL && data != NULL));
REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
- REQUIRE((setclosest == NULL && closest == NULL) ||
- (setclosest != NULL && closest != NULL));
REQUIRE((setnearest == NULL && nearest == NULL) ||
(setnearest != NULL && nearest != NULL));
"encloser: '%s'",
namebuf);
dns_name_copy(qname, closest);
- *setclosest = true;
}
dns_name_format(qname, namebuf, sizeof(namebuf));
(*logit)(arg, ISC_LOG_DEBUG(3),
if (header->noqname != NULL) {
rdataset->attributes.noqname = true;
}
- rdataset->slab.closest = header->closest;
- if (header->closest != NULL) {
- rdataset->attributes.closest = true;
- }
}
static void
oldheader->noqname = newheader->noqname;
newheader->noqname = NULL;
}
- if (oldheader->closest == NULL &&
- newheader->closest != NULL)
- {
- oldheader->closest = newheader->closest;
- newheader->closest = NULL;
- }
-
qpcache_hit(qpdb, oldheader);
bindrdataset(qpdb, qpnode, oldheader, now, nlocktype,
tlocktype,
oldheader->noqname = newheader->noqname;
newheader->noqname = NULL;
}
- if (oldheader->closest == NULL &&
- newheader->closest != NULL)
- {
- oldheader->closest = newheader->closest;
- newheader->closest = NULL;
- }
-
qpcache_hit(qpdb, oldheader);
bindrdataset(qpdb, qpnode, oldheader, now, nlocktype,
tlocktype,
return result;
}
-static isc_result_t
-addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
- dns_rdataset_t *rdataset) {
- isc_result_t result;
- dns_slabheader_proof_t *closest = NULL;
- dns_name_t name = DNS_NAME_INITEMPTY;
- dns_rdataset_t neg = DNS_RDATASET_INIT, negsig = DNS_RDATASET_INIT;
- isc_region_t r1 = { .base = NULL }, r2 = { .base = NULL };
-
- result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
-
- CHECK(dns_rdataslab_fromrdataset(&neg, mctx, &r1, maxrrperset));
-
- CHECK(dns_rdataslab_fromrdataset(&negsig, mctx, &r2, maxrrperset));
-
- closest = isc_mem_get(mctx, sizeof(*closest));
- *closest = (dns_slabheader_proof_t){
- .neg = ((dns_slabheader_t *)r1.base)->raw,
- .negsig = ((dns_slabheader_t *)r2.base)->raw,
- .name = DNS_NAME_INITEMPTY,
- .type = neg.type,
- };
- dns_name_dup(&name, mctx, &closest->name);
- newheader->closest = closest;
-
-cleanup:
- if (result != ISC_R_SUCCESS) {
- if (r1.base != NULL) {
- dns_slabheader_t *header = (dns_slabheader_t *)r1.base;
- dns_slabheader_detach(&header);
- }
- if (r2.base != NULL) {
- dns_slabheader_t *header = (dns_slabheader_t *)r2.base;
- dns_slabheader_detach(&header);
- }
- }
- dns_rdataset_disassociate(&neg);
- dns_rdataset_disassociate(&negsig);
- return result;
-}
-
static isc_result_t
qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t __now, dns_rdataset_t *rdataset,
CHECK(addnoqname(newheader->mctx, newheader, qpdb->maxrrperset,
rdataset));
}
- if (rdataset->attributes.closest) {
- CHECK(addclosest(newheader->mctx, newheader, qpdb->maxrrperset,
- rdataset));
- }
nlock = &qpdb->buckets[qpnode->locknum].lock;
.count = dns__rdatalist_count,
.addnoqname = dns__rdatalist_addnoqname,
.getnoqname = dns__rdatalist_getnoqname,
- .addclosest = dns__rdatalist_addclosest,
- .getclosest = dns__rdatalist_getclosest,
.setownercase = dns__rdatalist_setownercase,
.getownercase = dns__rdatalist_getownercase,
};
return ISC_R_SUCCESS;
}
-isc_result_t
-dns__rdatalist_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
- dns_rdataset_t *neg = NULL;
- dns_rdataset_t *negsig = NULL;
- dns_ttl_t ttl;
-
- REQUIRE(rdataset != NULL);
-
- ISC_LIST_FOREACH(name->list, rdset, link) {
- if (rdset->rdclass != rdataset->rdclass) {
- continue;
- }
- if (dns_rdatatype_isnsec(rdset->type)) {
- neg = rdset;
- }
- }
- if (neg == NULL) {
- return ISC_R_NOTFOUND;
- }
-
- ISC_LIST_FOREACH(name->list, rdset, link) {
- if (rdset->type == dns_rdatatype_rrsig &&
- rdset->covers == neg->type)
- {
- negsig = rdset;
- }
- }
-
- if (negsig == NULL) {
- return ISC_R_NOTFOUND;
- }
- /*
- * Minimise ttl.
- */
- ttl = rdataset->ttl;
- if (neg->ttl < ttl) {
- ttl = neg->ttl;
- }
- if (negsig->ttl < ttl) {
- ttl = negsig->ttl;
- }
- rdataset->ttl = neg->ttl = negsig->ttl = ttl;
- rdataset->attributes.closest = true;
- rdataset->rdlist.closest = name;
- return ISC_R_SUCCESS;
-}
-
-isc_result_t
-dns__rdatalist_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig DNS__DB_FLARG) {
- dns_rdataclass_t rdclass;
- dns_rdataset_t *tneg = NULL;
- dns_rdataset_t *tnegsig = NULL;
- dns_name_t *closest = NULL;
-
- REQUIRE(rdataset != NULL);
- REQUIRE(rdataset->attributes.closest);
-
- rdclass = rdataset->rdclass;
- closest = rdataset->rdlist.closest;
-
- (void)dns_name_dynamic(closest); /* Sanity Check. */
-
- ISC_LIST_FOREACH(closest->list, rdset, link) {
- if (rdset->rdclass != rdclass) {
- continue;
- }
- if (dns_rdatatype_isnsec(rdset->type)) {
- tneg = rdset;
- }
- }
- if (tneg == NULL) {
- return ISC_R_NOTFOUND;
- }
-
- ISC_LIST_FOREACH(closest->list, rdset, link) {
- if (rdset->type == dns_rdatatype_rrsig &&
- rdset->covers == tneg->type)
- {
- tnegsig = rdset;
- }
- }
- if (tnegsig == NULL) {
- return ISC_R_NOTFOUND;
- }
-
- dns_name_clone(closest, name);
- dns_rdataset_clone(tneg, neg);
- dns_rdataset_clone(tnegsig, negsig);
- return ISC_R_SUCCESS;
-}
-
void
dns__rdatalist_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
dns_rdatalist_t *rdatalist;
negsig DNS__DB_FLARG_PASS);
}
-isc_result_t
-dns_rdataset_addclosest(dns_rdataset_t *rdataset, dns_name_t *name) {
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
- if (rdataset->methods->addclosest == NULL) {
- return ISC_R_NOTIMPLEMENTED;
- }
- return (rdataset->methods->addclosest)(rdataset, name);
-}
-
-isc_result_t
-dns__rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg,
- dns_rdataset_t *negsig DNS__DB_FLARG) {
- REQUIRE(DNS_RDATASET_VALID(rdataset));
- REQUIRE(rdataset->methods != NULL);
-
- if (rdataset->methods->getclosest == NULL) {
- return ISC_R_NOTIMPLEMENTED;
- }
- return (rdataset->methods->getclosest)(rdataset, name, neg,
- negsig DNS__DB_FLARG_PASS);
-}
-
void
dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
REQUIRE(DNS_RDATASET_VALID(rdataset));
static isc_result_t
rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg, dns_rdataset_t *negsig DNS__DB_FLARG);
-static isc_result_t
-rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *neg, dns_rdataset_t *negsig DNS__DB_FLARG);
static void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
static void
.clone = rdataset_clone,
.count = rdataset_count,
.getnoqname = rdataset_getnoqname,
- .getclosest = rdataset_getclosest,
.settrust = rdataset_settrust,
.expire = rdataset_expire,
.clearprefetch = rdataset_clearprefetch,
.clone = slabheader_proof_clone,
.count = slabheader_proof_count,
.getnoqname = NULL,
- .getclosest = NULL,
.settrust = NULL,
.expire = NULL,
.clearprefetch = NULL,
if (header->noqname != NULL) {
dns_slabheader_freeproof(header->mctx, &header->noqname);
}
- if (header->closest != NULL) {
- dns_slabheader_freeproof(header->mctx, &header->closest);
- }
isc_mem_putanddetach(&header->mctx, header, size);
}
return ISC_R_SUCCESS;
}
-static isc_result_t
-rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
- dns_rdataset_t *nsec,
- dns_rdataset_t *nsecsig DNS__DB_FLARG) {
- dns_dbnode_t *node = rdataset->slab.node;
- dns_slabheader_t *header = rdataset_getheader(rdataset);
- const dns_slabheader_proof_t *closest = rdataset->slab.closest;
-
- /*
- * Normally, rdataset->slab.raw points to the data immediately
- * following a dns_slabheader in memory. Here, though, it will
- * point to a bare rdataslab, a pointer to which is stored in
- * the dns_slabheader's `closest` field.
- *
- * The 'keepcase' attribute is set to prevent setownercase and
- * getownercase methods from affecting the case of NSEC/NSEC3
- * owner names.
- */
- *nsec = (dns_rdataset_t){
- .methods = &dns_rdataslab_proof_rdatasetmethods,
- .rdclass = rdataset->rdclass,
- .type = closest->type,
- .ttl = rdataset->ttl,
- .trust = rdataset->trust,
- .proof.header = dns_slabheader_ref(header),
- .proof.raw = closest->neg,
- .link = nsec->link,
- .attributes = nsec->attributes,
- .magic = nsec->magic,
- };
- nsec->attributes.keepcase = true;
- dns__db_attachnode(node, &nsec->proof.node DNS__DB_FLARG_PASS);
-
- *nsecsig = (dns_rdataset_t){
- .methods = &dns_rdataslab_proof_rdatasetmethods,
- .rdclass = rdataset->rdclass,
- .type = dns_rdatatype_rrsig,
- .covers = closest->type,
- .ttl = rdataset->ttl,
- .trust = rdataset->trust,
- .proof.header = dns_slabheader_ref(header),
- .proof.raw = closest->negsig,
- .link = nsecsig->link,
- .attributes = nsecsig->attributes,
- .magic = nsecsig->magic,
- };
- nsecsig->attributes.keepcase = true;
- dns__db_attachnode(node, &nsecsig->proof.node DNS__DB_FLARG_PASS);
-
- dns_name_clone(&closest->name, name);
-
- return ISC_R_SUCCESS;
-}
-
static void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
dns_slabheader_t *header = rdataset_getheader(rdataset);
val->proofs[DNS_VALIDATOR_NOQNAMEPROOF]));
INSIST(val->sigrdataset != NULL);
val->sigrdataset->ttl = val->rdataset->ttl;
- if (val->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
- result = dns_rdataset_addclosest(
- val->rdataset,
- val->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- }
} else if (gettrust(val->rdataset) == dns_trust_answer) {
findnoqname(fctx, message, val->name, val->rdataset,
val->sigrdataset);
ISC_LIST_FOREACH(nsec->list, nrdataset, link) {
bool data = false, exists = false;
bool optout = false, unknown = false;
- bool setclosest = false;
bool setnearest = false;
if (!dns_rdatatype_isnsec(nrdataset->type)) {
NXND(dns_nsec3_noexistnodata(
type, name, nsec, nrdataset, zonename,
&exists, &data, &optout, &unknown,
- &setclosest, &setnearest, closest, nearest,
- fctx_log, fctx)))
+ &setnearest, closest, nearest, fctx_log,
+ fctx)))
{
if (!exists && setnearest) {
noqname = nsec;
!FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
dns_nsec3_noexistnodata(
val->type, wild, name, rdataset, zonename, &exists,
- &data, NULL, NULL, NULL, NULL, NULL, NULL,
- validator_log, val) == ISC_R_SUCCESS)
+ &data, NULL, NULL, NULL, NULL, NULL, validator_log,
+ val) == ISC_R_SUCCESS)
{
dns_name_t **proofs = val->proofs;
if (exists && !data) {
dns_name_t *zonename = dns_fixedname_initname(&fzonename);
dns_name_t *closestp = NULL;
dns_name_t **proofs = val->proofs;
- bool exists, data, optout, unknown;
- bool setclosest, setnearest, *setclosestp = NULL;
+ bool exists, data, optout, unknown, setnearest;
for (result = val_rdataset_first(val, &name, &rdataset);
result == ISC_R_SUCCESS;
continue;
}
- result = dns_nsec3_noexistnodata(val->type, val->name, name,
- rdataset, zonename, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL,
- NULL, validator_log, val);
+ result = dns_nsec3_noexistnodata(
+ val->type, val->name, name, rdataset, zonename, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, validator_log, val);
if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
CLEANUP(result);
}
namebuf);
dns_name_copy(dns_fixedname_name(&val->closest), closest);
closestp = NULL;
- setclosestp = NULL;
} else {
closestp = closest;
- setclosestp = &setclosest;
}
for (result = val_rdataset_first(val, &name, &rdataset);
* We process all NSEC3 records to find the closest
* encloser and nearest name to the closest encloser.
*/
- setclosest = setnearest = false;
+ setnearest = false;
optout = false;
unknown = false;
result = dns_nsec3_noexistnodata(
val->type, val->name, name, rdataset, zonename, &exists,
- &data, &optout, &unknown, setclosestp, &setnearest,
- closestp, nearest, validator_log, val);
+ &data, &optout, &unknown, &setnearest, closestp,
+ nearest, validator_log, val);
if (unknown) {
val->attributes |= VALATTR_FOUNDUNKNOWN;
}
proofs[DNS_VALIDATOR_NOQNAMEPROOF] == NULL)
{
proofs[DNS_VALIDATOR_NOQNAMEPROOF] = name;
- } else if (setclosest) {
- proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
} else if (NEEDNODATA(val) &&
proofs[DNS_VALIDATOR_NODATAPROOF] == NULL)
{
if (result != ISC_R_SUCCESS) {
continue;
}
-
- if (setclosest) {
- proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
- }
if (exists && !data && NEEDNODATA(val)) {
val->attributes |= VALATTR_FOUNDNODATA;
proofs[DNS_VALIDATOR_NODATAPROOF] = name;
isc_buffer_t *dbuf, b;
dns_name_t *fname = NULL;
dns_rdataset_t *neg = NULL, *negsig = NULL;
- isc_result_t result;
CTRACE(ISC_LOG_DEBUG(3), "query_addnoqnameproof");
neg = ns_client_newrdataset(client);
negsig = ns_client_newrdataset(client);
- CHECK(dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig));
-
- query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
- DNS_SECTION_AUTHORITY);
-
- if (!qctx->noqname->attributes.closest) {
- goto cleanup;
- }
-
- if (fname == NULL) {
- dbuf = ns_client_getnamebuf(client);
- fname = ns_client_newname(client, dbuf, &b);
- }
-
- if (neg == NULL) {
- neg = ns_client_newrdataset(client);
- } else {
- dns_rdataset_cleanup(neg);
- }
-
- if (negsig == NULL) {
- negsig = ns_client_newrdataset(client);
- } else {
- dns_rdataset_cleanup(negsig);
- }
-
- result = dns_rdataset_getclosest(qctx->noqname, fname, neg, negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(dns_rdataset_getnoqname(qctx->noqname, fname, neg,
+ negsig) == ISC_R_SUCCESS);
query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
DNS_SECTION_AUTHORITY);
-
-cleanup:
- if (neg != NULL) {
- ns_client_putrdataset(client, &neg);
- }
- if (negsig != NULL) {
- ns_client_putrdataset(client, &negsig);
- }
- if (fname != NULL) {
- ns_client_releasename(client, &fname);
- }
}
/*%