2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 07:35:26 +00:00

1675. [bug] named would sometimes add extra NSEC records to

the authority section.
This commit is contained in:
Mark Andrews
2004-06-29 00:51:50 +00:00
parent 8638eaef79
commit 5b4a9ac6bf
2 changed files with 108 additions and 85 deletions

View File

@@ -10,7 +10,8 @@
1676. [placeholder] rt10864 1676. [placeholder] rt10864
1675. [placeholder] rt10847 1675. [bug] named would sometimes add extra NSEC records to
the authority section.
1674. [port] linux: increase buffer size used to scan 1674. [port] linux: increase buffer size used to scan
/proc/net/if_inet6. /proc/net/if_inet6.

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: query.c,v 1.259 2004/05/14 00:10:52 marka Exp $ */ /* $Id: query.c,v 1.260 2004/06/29 00:51:50 marka Exp $ */
#include <config.h> #include <config.h>
@@ -1839,13 +1839,15 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
isc_buffer_t *dbuf, b; isc_buffer_t *dbuf, b;
dns_name_t *fname; dns_name_t *fname;
dns_rdataset_t *rdataset, *sigrdataset; dns_rdataset_t *rdataset, *sigrdataset;
dns_fixedname_t tfixed; dns_fixedname_t wfixed;
dns_name_t *tname; dns_name_t *wname;
dns_dbnode_t *node; dns_dbnode_t *node;
unsigned int options; unsigned int options, order;
unsigned int olabels, nlabels, i; unsigned int olabels, nlabels;
isc_boolean_t done;
isc_result_t result; isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec_t nsec;
isc_boolean_t have_wname;
CTRACE("query_addwildcardproof"); CTRACE("query_addwildcardproof");
fname = NULL; fname = NULL;
@@ -1853,86 +1855,106 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
sigrdataset = NULL; sigrdataset = NULL;
node = NULL; node = NULL;
/*
* Get the NOQNAME proof then if !ispositve
* get the NOWILDCARD proof.
*
* DNS_DBFIND_NOWILD finds the NSEC records that covers the
* name ignoring any wildcard. From the owner and next names
* of this record you can compute which wildcard (if it exists)
* will match by finding the longest common suffix of the
* owner name and next names with the qname and prefixing that
* with the wildcard label.
*
* e.g.
* Given:
* example SOA
* example NSEC b.example
* b.example A
* b.example NSEC a.d.example
* a.d.example A
* a.d.example NSEC g.f.example
* g.f.example A
* g.f.example NSEC z.i.example
* z.i.example A
* z.i.example NSEC example
*
* QNAME:
* a.example -> example NSEC b.example
* owner common example
* next common example
* wild *.example
* d.b.example -> b.example NSEC a.d.example
* owner common b.example
* next common example
* wild *.b.example
* a.f.example -> a.d.example NSEC g.f.example
* owner common example
* next common f.example
* wild *.f.example
* j.example -> z.i.example NSEC example
* owner common example
* next common example
* wild *.f.example
*/
options = client->query.dboptions | DNS_DBFIND_NOWILD; options = client->query.dboptions | DNS_DBFIND_NOWILD;
dns_fixedname_init(&wfixed);
wname = dns_fixedname_name(&wfixed);
again:
have_wname = ISC_FALSE;
/*
* We'll need some resources...
*/
dbuf = query_getnamebuf(client);
if (dbuf == NULL)
goto cleanup;
fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client);
sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup;
if (ispositive) { result = dns_db_find(db, name, NULL, dns_rdatatype_nsec, options,
/* 0, &node, fname, rdataset, sigrdataset);
* We'll need some resources... if (node != NULL)
*/ dns_db_detachnode(db, &node);
dbuf = query_getnamebuf(client); if (result == DNS_R_NXDOMAIN) {
if (dbuf == NULL) if (!ispositive)
goto cleanup; result = dns_rdataset_first(rdataset);
fname = query_newname(client, dbuf, &b); if (result == ISC_R_SUCCESS) {
rdataset = query_newrdataset(client); dns_rdataset_current(rdataset, &rdata);
sigrdataset = query_newrdataset(client); result = dns_rdata_tostruct(&rdata, &nsec, NULL);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) }
goto cleanup; if (result == ISC_R_SUCCESS) {
(void)dns_name_fullcompare(name, fname, &order,
result = dns_db_find(db, name, NULL, &olabels);
dns_rdatatype_nsec, options, 0, &node, (void)dns_name_fullcompare(name, &nsec.next, &order,
fname, rdataset, sigrdataset); &nlabels);
if (node != NULL) if (olabels > nlabels)
dns_db_detachnode(db, &node); dns_name_split(name, olabels, NULL, wname);
if (result == DNS_R_NXDOMAIN) else
query_addrrset(client, &fname, &rdataset, &sigrdataset, dns_name_split(name, nlabels, NULL, wname);
dbuf, DNS_SECTION_AUTHORITY); result = dns_name_concatenate(dns_wildcardname,
if (rdataset != NULL) wname, wname, NULL);
query_putrdataset(client, &rdataset); if (result == ISC_R_SUCCESS)
if (sigrdataset != NULL) have_wname = ISC_TRUE;
query_putrdataset(client, &sigrdataset); dns_rdata_freestruct(&nsec);
if (fname != NULL) }
query_releasename(client, &fname); query_addrrset(client, &fname, &rdataset, &sigrdataset,
} dbuf, DNS_SECTION_AUTHORITY);
}
olabels = dns_name_countlabels(dns_db_origin(db)); if (rdataset != NULL)
nlabels = dns_name_countlabels(name); query_putrdataset(client, &rdataset);
done = ISC_FALSE; if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
for (i = nlabels - 1; i >= olabels && !done; i--) { if (fname != NULL)
/* query_releasename(client, &fname);
* We'll need some resources... if (have_wname) {
*/ ispositive = ISC_TRUE; /* prevent loop */
dbuf = query_getnamebuf(client); if (!dns_name_equal(name, wname)) {
if (dbuf == NULL) name = wname;
goto cleanup; goto again;
fname = query_newname(client, dbuf, &b);
rdataset = query_newrdataset(client);
sigrdataset = query_newrdataset(client);
if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup;
dns_fixedname_init(&tfixed);
tname = dns_fixedname_name(&tfixed);
dns_name_split(name, i, NULL, tname);
result = dns_name_concatenate(dns_wildcardname, tname, tname,
NULL);
if (result != ISC_R_SUCCESS)
continue;
result = dns_db_find(db, tname, NULL, dns_rdatatype_nsec,
client->query.dboptions, 0, &node,
fname, rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
/*
* If this returns success, we've found the wildcard for a
* successful answer, so we're done.
*/
if (result == ISC_R_SUCCESS && ispositive)
break;
if (result == DNS_R_NXDOMAIN || result == DNS_R_EMPTYNAME) {
if (!ispositive &&
dns_name_issubdomain(name, fname))
done = ISC_TRUE;
query_addrrset(client, &fname, &rdataset, &sigrdataset,
dbuf, DNS_SECTION_AUTHORITY);
} }
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (fname != NULL)
query_releasename(client, &fname);
} }
cleanup: cleanup:
if (rdataset != NULL) if (rdataset != NULL)