2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +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,8 +10,9 @@
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
/proc/net/if_inet6.

View File

@@ -15,7 +15,7 @@
* 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>
@@ -1839,13 +1839,15 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
isc_buffer_t *dbuf, b;
dns_name_t *fname;
dns_rdataset_t *rdataset, *sigrdataset;
dns_fixedname_t tfixed;
dns_name_t *tname;
dns_fixedname_t wfixed;
dns_name_t *wname;
dns_dbnode_t *node;
unsigned int options;
unsigned int olabels, nlabels, i;
isc_boolean_t done;
unsigned int options, order;
unsigned int olabels, nlabels;
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec_t nsec;
isc_boolean_t have_wname;
CTRACE("query_addwildcardproof");
fname = NULL;
@@ -1853,87 +1855,107 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
sigrdataset = 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;
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) {
/*
* 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;
result = dns_db_find(db, name, NULL,
dns_rdatatype_nsec, options, 0, &node,
fname, rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
if (result == DNS_R_NXDOMAIN)
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);
}
olabels = dns_name_countlabels(dns_db_origin(db));
nlabels = dns_name_countlabels(name);
done = ISC_FALSE;
for (i = nlabels - 1; i >= olabels && !done; i--) {
/*
* 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;
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);
result = dns_db_find(db, name, NULL, dns_rdatatype_nsec, options,
0, &node, fname, rdataset, sigrdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
if (result == DNS_R_NXDOMAIN) {
if (!ispositive)
result = dns_rdataset_first(rdataset);
if (result == ISC_R_SUCCESS) {
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &nsec, NULL);
}
if (rdataset != NULL)
query_putrdataset(client, &rdataset);
if (sigrdataset != NULL)
query_putrdataset(client, &sigrdataset);
if (fname != NULL)
query_releasename(client, &fname);
if (result == ISC_R_SUCCESS) {
(void)dns_name_fullcompare(name, fname, &order,
&olabels);
(void)dns_name_fullcompare(name, &nsec.next, &order,
&nlabels);
if (olabels > nlabels)
dns_name_split(name, olabels, NULL, wname);
else
dns_name_split(name, nlabels, NULL, wname);
result = dns_name_concatenate(dns_wildcardname,
wname, wname, NULL);
if (result == ISC_R_SUCCESS)
have_wname = ISC_TRUE;
dns_rdata_freestruct(&nsec);
}
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);
if (have_wname) {
ispositive = ISC_TRUE; /* prevent loop */
if (!dns_name_equal(name, wname)) {
name = wname;
goto again;
}
}
cleanup:
if (rdataset != NULL)
query_putrdataset(client, &rdataset);