* Only perform the update if the client is in the allow query acl and
* returning the update would not cause a DNSSEC validation failure.
*/
-static isc_boolean_t
+static isc_result_t
redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
dns_rdatatype_t qtype)
CTRACE("redirect");
if (client->view->redirect == NULL)
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
dns_fixedname_init(&fixed);
found = dns_fixedname_name(&fixed);
dns_clientinfo_init(&ci, client);
if (WANTDNSSEC(client) && dns_db_iszone(*dbp) && dns_db_issecure(*dbp))
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
if (WANTDNSSEC(client) && dns_rdataset_isassociated(rdataset)) {
if (rdataset->trust == dns_trust_secure)
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
if (rdataset->trust == dns_trust_ultimate &&
(rdataset->type == dns_rdatatype_nsec ||
rdataset->type == dns_rdatatype_nsec3))
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
if (type == dns_rdatatype_nsec ||
type == dns_rdatatype_nsec3 ||
type == dns_rdatatype_rrsig)
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
}
}
}
dns_zone_getqueryacl(client->view->redirect),
ISC_TRUE);
if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
result = dns_zone_getdb(client->view->redirect, &db);
if (result != ISC_R_SUCCESS)
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
dbversion = query_findversion(client, db);
if (dbversion == NULL) {
dns_db_detach(&db);
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
}
/*
result = dns_db_findext(db, client->query.qname, dbversion->version,
qtype, 0, client->now, &node, found, &cm, &ci,
&trdataset, NULL);
- if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
+ if (dns_rdataset_isassociated(rdataset))
+ dns_rdataset_disassociate(rdataset);
+ if (dns_rdataset_isassociated(&trdataset))
+ dns_rdataset_disassociate(&trdataset);
+ goto nxrrset;
+ } else if (result != ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(&trdataset))
dns_rdataset_disassociate(&trdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
dns_db_detach(&db);
- return (ISC_FALSE);
+ return (ISC_R_NOTFOUND);
}
- CTRACE("redirect: found data: done");
+ CTRACE("redirect: found data: done");
dns_name_copy(found, name, NULL);
if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(rdataset);
dns_rdataset_clone(&trdataset, rdataset);
dns_rdataset_disassociate(&trdataset);
}
+ nxrrset:
if (*nodep != NULL)
dns_db_detachnode(*dbp, nodep);
dns_db_detach(dbp);
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
NS_QUERYATTR_NOADDITIONAL);
- return (ISC_TRUE);
+ return (result);
}
/*
int order;
isc_buffer_t *dbuf;
isc_buffer_t b;
- isc_result_t result, eresult;
+ isc_result_t result, eresult, tresult;
dns_fixedname_t fixed;
dns_fixedname_t wildcardname;
dns_dbversion_t *version, *zversion;
int line = -1;
isc_boolean_t dns64_exclude, dns64;
isc_boolean_t nxrewrite = ISC_FALSE;
+ isc_boolean_t redirected = ISC_FALSE;
dns_clientinfomethods_t cm;
dns_clientinfo_t ci;
isc_boolean_t associated;
dns_db_t *tdb = NULL;
dns_zone_t *tzone = NULL;
dns_dbversion_t *tversion = NULL;
- isc_result_t tresult;
tresult = query_getzonedb(client, client->query.qname, qtype,
DNS_GETDB_PARTIAL, &tzone, &tdb,
* Look for a NSEC3 record if we don't have a NSEC record.
*/
nxrrset_rrsig:
+ if (redirected)
+ goto cleanup;
if (!dns_rdataset_isassociated(rdataset) &&
WANTDNSSEC(client)) {
if ((fname->attributes & DNS_NAMEATTR_WILDCARD) == 0) {
case DNS_R_NXDOMAIN:
INSIST(is_zone);
- if (!empty_wild &&
- redirect(client, fname, rdataset, &node, &db, &version,
- type))
- break;
+ if (!empty_wild) {
+ tresult = redirect(client, fname, rdataset, &node,
+ &db, &version, type);
+ if (tresult == ISC_R_SUCCESS)
+ break;
+ if (tresult == DNS_R_NXRRSET) {
+ redirected = ISC_TRUE;
+ goto iszone_nxrrset;
+ }
+ if (tresult == DNS_R_NCACHENXRRSET) {
+ redirected = ISC_TRUE;
+ is_zone = ISC_FALSE;
+ goto ncache_nxrrset;
+ }
+ }
if (dns_rdataset_isassociated(rdataset)) {
/*
* If we've got a NSEC record, we need to save the
goto cleanup;
case DNS_R_NCACHENXDOMAIN:
- if (redirect(client, fname, rdataset, &node, &db, &version,
- type))
+ tresult = redirect(client, fname, rdataset, &node,
+ &db, &version, type);
+ if (tresult == ISC_R_SUCCESS)
break;
+ if (tresult == DNS_R_NXRRSET) {
+ redirected = ISC_TRUE;
+ is_zone = ISC_TRUE;
+ goto iszone_nxrrset;
+ }
+ if (tresult == DNS_R_NCACHENXRRSET) {
+ redirected = ISC_TRUE;
+ result = tresult;
+ goto ncache_nxrrset;
+ }
+ /* FALLTHROUGH */
+
case DNS_R_NCACHENXRRSET:
ncache_nxrrset:
INSIST(!is_zone);