mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-28 13:08:06 +00:00
1410. [func] handle records that live in the parent zone, e.g. DS.
developer: marka reviewer: explorer
This commit is contained in:
parent
fcecba0341
commit
c86eed4bde
2
CHANGES
2
CHANGES
@ -1,3 +1,5 @@
|
||||
1410. [func] handle records that live in the parent zone, e.g. DS.
|
||||
|
||||
1409. [bug] DS should have attibute DNS_RDATATYPEATTR_DNSSEC.
|
||||
|
||||
1408. [bug] distclean was not complete. [RT #4700]
|
||||
|
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.238 2002/11/27 09:52:45 marka Exp $ */
|
||||
/* $Id: query.c,v 1.239 2003/01/14 00:28:49 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
|
||||
#define DNS_GETDB_NOEXACT 0x01U
|
||||
#define DNS_GETDB_NOLOG 0x02U
|
||||
#define DNS_GETDB_PARTIAL 0x04U
|
||||
|
||||
static void
|
||||
query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype);
|
||||
@ -544,6 +545,7 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, unsigned int options,
|
||||
unsigned int ztoptions;
|
||||
dns_zone_t *zone = NULL;
|
||||
dns_db_t *db = NULL;
|
||||
isc_boolean_t partial = ISC_FALSE;
|
||||
|
||||
REQUIRE(zonep != NULL && *zonep == NULL);
|
||||
REQUIRE(dbp != NULL && *dbp == NULL);
|
||||
@ -556,6 +558,8 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, unsigned int options,
|
||||
|
||||
result = dns_zt_find(client->view->zonetable, name, ztoptions, NULL,
|
||||
&zone);
|
||||
if (result == DNS_R_PARTIALMATCH)
|
||||
partial = ISC_TRUE;
|
||||
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
|
||||
result = dns_zone_getdb(zone, &db);
|
||||
|
||||
@ -687,6 +691,8 @@ query_getzonedb(ns_client_t *client, dns_name_t *name, unsigned int options,
|
||||
*dbp = db;
|
||||
*versionp = dbversion->version;
|
||||
|
||||
if (partial && (options & DNS_GETDB_PARTIAL) != 0)
|
||||
return (DNS_R_PARTIALMATCH);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
refuse:
|
||||
@ -2266,6 +2272,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
version = NULL;
|
||||
zone = NULL;
|
||||
need_wildcardproof = ISC_FALSE;
|
||||
options = 0;
|
||||
|
||||
if (event != NULL) {
|
||||
/*
|
||||
@ -2340,6 +2347,39 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
options |= DNS_GETDB_NOEXACT;
|
||||
result = query_getdb(client, client->query.qname, options, &zone, &db,
|
||||
&version, &is_zone);
|
||||
if ((result != ISC_R_SUCCESS || !is_zone) && !RECURSIONOK(client) &&
|
||||
(options & DNS_GETDB_NOEXACT) != 0 && qtype == dns_rdatatype_ds) {
|
||||
/*
|
||||
* Look to see if we are authoritative for the
|
||||
* child zone if the query type is DS.
|
||||
*/
|
||||
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,
|
||||
DNS_GETDB_PARTIAL, &tzone, &tdb,
|
||||
&tversion);
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
options &= ~DNS_GETDB_NOEXACT;
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (db != NULL)
|
||||
dns_db_detach(&db);
|
||||
if (zone != NULL)
|
||||
dns_zone_detach(&zone);
|
||||
version = tversion;
|
||||
db = tdb;
|
||||
zone = tzone;
|
||||
is_zone = ISC_TRUE;
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
if (tdb != NULL)
|
||||
dns_db_detach(&tdb);
|
||||
if (tzone != NULL)
|
||||
dns_zone_detach(&tzone);
|
||||
}
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
if (result == DNS_R_REFUSED)
|
||||
QUERY_ERROR(DNS_R_REFUSED);
|
||||
@ -2466,6 +2506,47 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
case DNS_R_DELEGATION:
|
||||
authoritative = ISC_FALSE;
|
||||
if (is_zone) {
|
||||
/*
|
||||
* Look to see if we are authoritative for the
|
||||
* child zone if the query type is DS.
|
||||
*/
|
||||
if (!RECURSIONOK(client) &&
|
||||
(options & DNS_GETDB_NOEXACT) != 0 &&
|
||||
qtype == dns_rdatatype_ds) {
|
||||
dns_db_t *tdb = NULL;
|
||||
dns_zone_t *tzone = NULL;
|
||||
dns_dbversion_t *tversion = NULL;
|
||||
result = query_getzonedb(client,
|
||||
client->query.qname,
|
||||
DNS_GETDB_PARTIAL,
|
||||
&tzone, &tdb,
|
||||
&tversion);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
options &= ~DNS_GETDB_NOEXACT;
|
||||
query_putrdataset(client, &rdataset);
|
||||
if (sigrdataset != NULL)
|
||||
query_putrdataset(client,
|
||||
&sigrdataset);
|
||||
if (fname != NULL)
|
||||
query_releasename(client,
|
||||
&fname);
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
if (db != NULL)
|
||||
dns_db_detach(&db);
|
||||
if (zone != NULL)
|
||||
dns_zone_detach(&zone);
|
||||
version = tversion;
|
||||
db = tdb;
|
||||
zone = tzone;
|
||||
authoritative = ISC_TRUE;
|
||||
goto db_find;
|
||||
}
|
||||
if (tdb != NULL)
|
||||
dns_db_detach(&tdb);
|
||||
if (tzone != NULL)
|
||||
dns_zone_detach(&tzone);
|
||||
}
|
||||
/*
|
||||
* We're authoritative for an ancestor of QNAME.
|
||||
*/
|
||||
|
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.h,v 1.94 2002/08/27 04:53:43 marka Exp $ */
|
||||
/* $Id: result.h,v 1.95 2003/01/14 00:28:50 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RESULT_H
|
||||
#define DNS_RESULT_H 1
|
||||
@ -132,8 +132,9 @@
|
||||
#define DNS_R_LAME (ISC_RESULTCLASS_DNS + 88)
|
||||
#define DNS_R_UNEXPECTEDRCODE (ISC_RESULTCLASS_DNS + 89)
|
||||
#define DNS_R_UNEXPECTEDOPCODE (ISC_RESULTCLASS_DNS + 90)
|
||||
#define DNS_R_CHASEDSSERVERS (ISC_RESULTCLASS_DNS + 91)
|
||||
|
||||
#define DNS_R_NRESULTS 91 /* Number of results */
|
||||
#define DNS_R_NRESULTS 92 /* Number of results */
|
||||
|
||||
/*
|
||||
* DNS wire format rcodes.
|
||||
|
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.c,v 1.256 2003/01/05 23:19:29 marka Exp $ */
|
||||
/* $Id: resolver.c,v 1.257 2003/01/14 00:28:49 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -199,6 +199,12 @@ struct fetchctx {
|
||||
* is used for EDNS0 black hole detection.
|
||||
*/
|
||||
unsigned int timeouts;
|
||||
/*
|
||||
* Look aside state for DS lookups.
|
||||
*/
|
||||
dns_name_t nsname;
|
||||
dns_fetch_t * nsfetch;
|
||||
dns_rdataset_t nsrrset;
|
||||
};
|
||||
|
||||
#define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
|
||||
@ -2024,6 +2030,9 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
|
||||
dns_validator_cancel(validator);
|
||||
validator = ISC_LIST_NEXT(validator, link);
|
||||
}
|
||||
|
||||
if (fctx->nsfetch != NULL)
|
||||
dns_resolver_cancelfetch(fctx->nsfetch);
|
||||
|
||||
/*
|
||||
* Shut down anything that is still running on behalf of this
|
||||
@ -2234,6 +2243,10 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
|
||||
fctx->timeouts = 0;
|
||||
fctx->attributes = 0;
|
||||
|
||||
dns_name_init(&fctx->nsname, NULL);
|
||||
fctx->nsfetch = NULL;
|
||||
dns_rdataset_init(&fctx->nsrrset);
|
||||
|
||||
if (domain == NULL) {
|
||||
dns_forwarders_t *forwarders = NULL;
|
||||
result = dns_fwdtable_find(fctx->res->view->fwdtable,
|
||||
@ -3710,6 +3723,15 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Trigger lookups for DNS nameservers.
|
||||
*/
|
||||
if (negative_response && message->rcode == dns_rcode_noerror &&
|
||||
fctx->type == dns_rdatatype_ds && soa_name != NULL &&
|
||||
dns_name_equal(soa_name, qname) &&
|
||||
!dns_name_equal(qname, dns_rootname))
|
||||
return (DNS_R_CHASEDSSERVERS);
|
||||
|
||||
/*
|
||||
* Did we find anything?
|
||||
*/
|
||||
@ -4211,6 +4233,98 @@ answer_response(fetchctx_t *fctx) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
resume_dslookup(isc_task_t *task, isc_event_t *event) {
|
||||
dns_fetchevent_t *fevent;
|
||||
dns_resolver_t *res;
|
||||
fetchctx_t *fctx;
|
||||
isc_result_t result;
|
||||
isc_boolean_t bucket_empty = ISC_FALSE;
|
||||
isc_boolean_t locked = ISC_FALSE;
|
||||
|
||||
REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
|
||||
fevent = (dns_fetchevent_t *)event;
|
||||
fctx = event->ev_arg;
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
res = fctx->res;
|
||||
|
||||
UNUSED(task);
|
||||
FCTXTRACE("resume_dslookup");
|
||||
|
||||
if (fevent->node != NULL)
|
||||
dns_db_detachnode(fevent->db, &fevent->node);
|
||||
if (fevent->db != NULL)
|
||||
dns_db_detach(&fevent->db);
|
||||
|
||||
dns_resolver_destroyfetch(&fctx->nsfetch);
|
||||
|
||||
if (fevent->result == ISC_R_CANCELED)
|
||||
fctx_done(fctx, ISC_R_CANCELED);
|
||||
else if (fevent->result == ISC_R_SUCCESS) {
|
||||
|
||||
FCTXTRACE("resuming DS lookup");
|
||||
|
||||
if (dns_rdataset_isassociated(&fctx->nameservers))
|
||||
dns_rdataset_disassociate(&fctx->nameservers);
|
||||
dns_rdataset_clone(fevent->rdataset, &fctx->nameservers);
|
||||
dns_name_free(&fctx->domain, fctx->res->mctx);
|
||||
dns_name_init(&fctx->domain, NULL);
|
||||
result = dns_name_dup(&fctx->nsname, fctx->res->mctx,
|
||||
&fctx->domain);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
/*
|
||||
* Try again.
|
||||
*/
|
||||
fctx_try(fctx);
|
||||
} else {
|
||||
unsigned int n;
|
||||
|
||||
n = dns_name_countlabels(&fctx->nsname);
|
||||
dns_name_getlabelsequence(&fctx->nsname, 1, n - 1,
|
||||
&fctx->nsname);
|
||||
|
||||
if (dns_name_equal(&fctx->nsname, &fctx->domain)) {
|
||||
fctx_done(fctx, DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
if (dns_rdataset_isassociated(fevent->rdataset))
|
||||
dns_rdataset_disassociate(fevent->rdataset);
|
||||
FCTXTRACE("continuing to look for parent's NS records");
|
||||
result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
|
||||
dns_rdatatype_ns,
|
||||
&fctx->domain,
|
||||
&fctx->nameservers, NULL,
|
||||
0, task,
|
||||
resume_dslookup, fctx,
|
||||
&fctx->nsrrset, NULL,
|
||||
&fctx->nsfetch);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
else {
|
||||
LOCK(&res->buckets[fctx->bucketnum].lock);
|
||||
locked = ISC_TRUE;
|
||||
fctx->references++;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (dns_rdataset_isassociated(fevent->rdataset))
|
||||
dns_rdataset_disassociate(fevent->rdataset);
|
||||
INSIST(fevent->sigrdataset == NULL);
|
||||
isc_event_free(&event);
|
||||
if (!locked)
|
||||
LOCK(&res->buckets[fctx->bucketnum].lock);
|
||||
fctx->references--;
|
||||
if (fctx->references == 0)
|
||||
bucket_empty = fctx_destroy(fctx);
|
||||
UNLOCK(&res->buckets[fctx->bucketnum].lock);
|
||||
if (bucket_empty)
|
||||
empty_bucket(res);
|
||||
}
|
||||
|
||||
static void
|
||||
resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
@ -4235,7 +4349,6 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
REQUIRE(event->ev_type == DNS_EVENT_DISPATCH);
|
||||
|
||||
UNUSED(task);
|
||||
QTRACE("response");
|
||||
|
||||
(void)isc_timer_touch(fctx->timer);
|
||||
@ -4569,7 +4682,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
* NXDOMAIN, NXRDATASET, or referral.
|
||||
*/
|
||||
result = noanswer_response(fctx, NULL, ISC_FALSE);
|
||||
if (result == DNS_R_DELEGATION) {
|
||||
if (result == DNS_R_CHASEDSSERVERS) {
|
||||
} else if (result == DNS_R_DELEGATION) {
|
||||
force_referral:
|
||||
/*
|
||||
* We don't have the answer, but we know a better
|
||||
@ -4728,6 +4842,34 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
result = fctx_stopidletimer(fctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
} else if (result == DNS_R_CHASEDSSERVERS) {
|
||||
unsigned int n;
|
||||
add_bad(fctx, &addrinfo->sockaddr, result);
|
||||
fctx_cancelqueries(fctx, ISC_TRUE);
|
||||
fctx_cleanupfinds(fctx);
|
||||
fctx_cleanupforwaddrs(fctx);
|
||||
|
||||
n = dns_name_countlabels(&fctx->name);
|
||||
dns_name_getlabelsequence(&fctx->name, 1, n - 1, &fctx->nsname);
|
||||
|
||||
FCTXTRACE("suspending DS lookup to find parent's NS records");
|
||||
|
||||
result = dns_resolver_createfetch(fctx->res, &fctx->nsname,
|
||||
dns_rdatatype_ns,
|
||||
&fctx->domain,
|
||||
&fctx->nameservers, NULL,
|
||||
0, task,
|
||||
resume_dslookup, fctx,
|
||||
&fctx->nsrrset, NULL,
|
||||
&fctx->nsfetch);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
fctx->references++;
|
||||
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
result = fctx_stopidletimer(fctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
} else {
|
||||
/*
|
||||
* We're done.
|
||||
|
@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: result.c,v 1.104 2002/08/27 04:53:43 marka Exp $ */
|
||||
/* $Id: result.c,v 1.105 2003/01/14 00:28:49 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -137,7 +137,9 @@ static const char *text[DNS_R_NRESULTS] = {
|
||||
"truncated TCP response", /* 87 DNS_R_TRUNCATEDTCP */
|
||||
"lame server detected", /* 88 DNS_R_LAME */
|
||||
"unexpected RCODE", /* 89 DNS_R_UNEXPECTEDRCODE */
|
||||
"unexpected OPCODE" /* 90 DNS_R_UNEXPECTEDOPCODE */
|
||||
|
||||
"unexpected OPCODE", /* 90 DNS_R_UNEXPECTEDOPCODE */
|
||||
"chase DS servers" /* 91 DNS_R_CHASEDSSERVERS */
|
||||
};
|
||||
|
||||
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user