2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +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,9 +1855,53 @@ 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);
if (ispositive) { wname = dns_fixedname_name(&wfixed);
again:
have_wname = ISC_FALSE;
/* /*
* We'll need some resources... * We'll need some resources...
*/ */
@@ -1868,62 +1914,32 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
if (fname == NULL || rdataset == NULL || sigrdataset == NULL) if (fname == NULL || rdataset == NULL || sigrdataset == NULL)
goto cleanup; goto cleanup;
result = dns_db_find(db, name, NULL, result = dns_db_find(db, name, NULL, dns_rdatatype_nsec, options,
dns_rdatatype_nsec, options, 0, &node, 0, &node, fname, rdataset, sigrdataset);
fname, rdataset, sigrdataset);
if (node != NULL) if (node != NULL)
dns_db_detachnode(db, &node); dns_db_detachnode(db, &node);
if (result == DNS_R_NXDOMAIN) if (result == DNS_R_NXDOMAIN) {
query_addrrset(client, &fname, &rdataset, &sigrdataset, if (!ispositive)
dbuf, DNS_SECTION_AUTHORITY); result = dns_rdataset_first(rdataset);
if (rdataset != NULL) if (result == ISC_R_SUCCESS) {
query_putrdataset(client, &rdataset); dns_rdataset_current(rdataset, &rdata);
if (sigrdataset != NULL) result = dns_rdata_tostruct(&rdata, &nsec, NULL);
query_putrdataset(client, &sigrdataset); }
if (fname != NULL) if (result == ISC_R_SUCCESS) {
query_releasename(client, &fname); (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);
} }
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, query_addrrset(client, &fname, &rdataset, &sigrdataset,
dbuf, DNS_SECTION_AUTHORITY); dbuf, DNS_SECTION_AUTHORITY);
} }
@@ -1933,6 +1949,12 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
query_putrdataset(client, &sigrdataset); query_putrdataset(client, &sigrdataset);
if (fname != NULL) if (fname != NULL)
query_releasename(client, &fname); query_releasename(client, &fname);
if (have_wname) {
ispositive = ISC_TRUE; /* prevent loop */
if (!dns_name_equal(name, wname)) {
name = wname;
goto again;
}
} }
cleanup: cleanup:
if (rdataset != NULL) if (rdataset != NULL)