}
}
+static dns_trust_t
+header_trust(dns_slabheader_t *header) {
+ if (header == NULL) {
+ return dns_trust_none;
+ }
+ return atomic_load_acquire(&header->trust);
+}
+
static void
bindrdataset(qpcache_t *qpdb, qpcnode_t *node, dns_slabheader_t *header,
isc_stdtime_t now, isc_rwlocktype_t nlocktype,
rdataset->covers = DNS_TYPEPAIR_COVERS(header->typepair);
}
rdataset->ttl = !ZEROTTL(header) ? header->expire - now : 0;
- rdataset->trust = atomic_load(&header->trust);
+ rdataset->trust = header_trust(header);
rdataset->resign = 0;
if (NEGATIVE(header)) {
*/
find_headers(node, search, dns_rdatatype_dname, &found, &foundsig);
- if (found != NULL && (!DNS_TRUST_PENDING(atomic_load(&found->trust)) ||
+ if (found != NULL && (!DNS_TRUST_PENDING(header_trust(found)) ||
(search->options & DNS_DBFIND_PENDINGOK) != 0))
{
/*
find_headers(node, search, dns_rdatatype_nsec, &found, &foundsig);
- if (found != NULL) {
+ if (found != NULL && header_trust(found) == dns_trust_secure &&
+ (foundsig == NULL || header_trust(foundsig) == dns_trust_secure))
+ {
if (nodep != NULL) {
qpcnode_acquire(search->qpdb, node, nlocktype,
isc_rwlocktype_none DNS__DB_FLARG_PASS);
return true;
}
- dns_trust_t trust = atomic_load(&found->trust);
+ dns_trust_t trust = header_trust(found);
return (DNS_TRUST_ADDITIONAL(trust) &&
(options & DNS_DBFIND_ADDITIONALOK) == 0) ||
(DNS_TRUST_GLUE(trust) && (options & DNS_DBFIND_GLUEOK) == 0) ||
empty_node = false;
if (header != NULL && header->noqname != NULL &&
- atomic_load(&header->trust) == dns_trust_secure)
+ header_trust(header) == dns_trust_secure)
{
found_noqname = true;
}
* than the new data, evict it from the cache. Otherwise,
* bind to it and leave the cache unchanged.
*/
- if (trust >= header->trust) {
+ if (trust >= header_trust(header)) {
header_delete(qpnode, header);
return DNS_R_CONTINUE;
} else {
rdtype == dns_rdatatype_any && trust < dns_trust_secure)
{
DNS_SLABHEADER_FOREACH(header, &qpnode->headers) {
- if (header->trust >= dns_trust_secure) {
+ if (header_trust(header) >= dns_trust_secure) {
qpcache_hit(qpdb, header);
bindrdataset(qpdb, qpnode, header, now,
nlocktype, tlocktype,
* data will supersede it below. Unclear what the best
* policy is here.
*/
- dns_trust_t oldtrust = atomic_load(&oldheader->trust);
+ dns_trust_t oldtrust = header_trust(oldheader);
if (trust < oldtrust &&
(ACTIVE(oldheader, now) || !EXISTS(oldheader)))
{
dns_fixedname_t fsigner;
dns_fixedname_t fwild;
dns_name_t *fname = NULL;
- dns_name_t *namespace = NULL;
+ dns_name_t *namespace = dns_fixedname_initname(&fnamespace);
dns_name_t *nowild = NULL;
dns_name_t *signer = NULL;
dns_name_t *wild = NULL;
- dns_name_t qname;
+ dns_name_t qname = DNS_NAME_INITEMPTY;
dns_rdataset_t *soardataset = NULL, *sigsoardataset = NULL;
- dns_rdataset_t rdataset, sigrdataset;
+ dns_rdataset_t rdataset = DNS_RDATASET_INIT;
+ dns_rdataset_t sigrdataset = DNS_RDATASET_INIT;
bool done = false;
bool exists = true, data = true;
bool redirected = false;
CCTRACE(ISC_LOG_DEBUG(3), "query_coveringnsec");
- dns_name_init(&qname);
- dns_rdataset_init(&rdataset);
- dns_rdataset_init(&sigrdataset);
- namespace = dns_fixedname_initname(&fnamespace);
-
/*
* Check that the NSEC record is from the correct namespace.
* For records that belong to the parent zone (i.e. DS),
/*
* Check that we have the correct NOQNAME NSEC record.
*/
- result = dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
- qctx->fname, qctx->rdataset, &exists,
- &data, wild, log_noexistnodata, qctx);
-
- if (result != ISC_R_SUCCESS || (exists && data)) {
- goto cleanup;
- }
-
+ CHECK(dns_nsec_noexistnodata(qctx->qtype, qctx->client->query.qname,
+ qctx->fname, qctx->rdataset, &exists,
+ &data, wild, log_noexistnodata, qctx));
if (exists) {
+ /*
+ * If there's data at the name, or the NSEC isn't
+ * validated, we don't synthesize an answer.
+ */
+ if (data || qctx->rdataset->trust != dns_trust_secure ||
+ qctx->sigrdataset->trust != dns_trust_secure)
+ {
+ goto cleanup;
+ }
+
if (qctx->type == dns_rdatatype_any) { /* XXX not yet */
goto cleanup;
}
qctx->client->inner.now, &node, fname, &cm,
&ci, soardataset, sigsoardataset));
+ if (soardataset->trust != dns_trust_secure ||
+ sigsoardataset->trust != dns_trust_secure)
+ {
+ goto cleanup;
+ }
+
(void)query_synthnodata(qctx, signer, &soardataset,
&sigsoardataset);
done = true;
if (!dns_name_issubdomain(nowild, namespace)) {
goto cleanup;
}
- result = dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
- &rdataset, &exists, &data, NULL,
- log_noexistnodata, qctx);
- if (result != ISC_R_SUCCESS || (exists && data)) {
+ CHECK(dns_nsec_noexistnodata(qctx->qtype, wild, nowild,
+ &rdataset, &exists, &data, NULL,
+ log_noexistnodata, qctx));
+ /*
+ * If the name exists and contains data, we don't synthesize an
+ * answer. Note that the rdataset trust has been verified to be
+ * secure already.
+ */
+ if (exists && data) {
goto cleanup;
}
break;
dboptions, qctx->client->inner.now, &node, fname,
&cm, &ci, soardataset, sigsoardataset));
+ if (soardataset->trust != dns_trust_secure ||
+ sigsoardataset->trust != dns_trust_secure)
+ {
+ goto cleanup;
+ }
+
(void)query_synthnxdomainnodata(qctx, exists, nowild, &rdataset,
&sigrdataset, signer, &soardataset,
&sigsoardataset);