2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

1801. [func] Report differences between hints and real NS rrset

and associated address records.
This commit is contained in:
Mark Andrews 2005-02-07 00:53:29 +00:00
parent 07bf7b758c
commit 4296c5480d
4 changed files with 290 additions and 6 deletions

View File

@ -15,7 +15,8 @@
1802. [placeholder] rt11280 1802. [placeholder] rt11280
1801. [placeholder] rt288 1801. [func] Report differences between hints and real NS rrset
and associated address records.
1800. [bug] Changes #1719 allowed a INSIST to be triggered. 1800. [bug] Changes #1719 allowed a INSIST to be triggered.
[RT #13428] [RT #13428]

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: rootns.h,v 1.9 2004/03/05 05:09:46 marka Exp $ */ /* $Id: rootns.h,v 1.10 2005/02/07 00:53:29 marka Exp $ */
#ifndef DNS_ROOTNS_H #ifndef DNS_ROOTNS_H
#define DNS_ROOTNS_H 1 #define DNS_ROOTNS_H 1
@ -30,6 +30,14 @@ isc_result_t
dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
const char *filename, dns_db_t **target); const char *filename, dns_db_t **target);
void
dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db);
/*
* Reports differences between hints and the real roots.
*
* Requires view, hints and (cache) db to be valid.
*/
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS
#endif /* DNS_ROOTNS_H */ #endif /* DNS_ROOTNS_H */

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: resolver.c,v 1.301 2005/01/20 00:01:46 marka Exp $ */ /* $Id: resolver.c,v 1.302 2005/02/07 00:53:28 marka Exp $ */
#include <config.h> #include <config.h>
@ -27,6 +27,7 @@
#include <dns/acl.h> #include <dns/acl.h>
#include <dns/adb.h> #include <dns/adb.h>
#include <dns/cache.h>
#include <dns/db.h> #include <dns/db.h>
#include <dns/dispatch.h> #include <dns/dispatch.h>
#include <dns/events.h> #include <dns/events.h>
@ -47,6 +48,7 @@
#include <dns/rdatatype.h> #include <dns/rdatatype.h>
#include <dns/resolver.h> #include <dns/resolver.h>
#include <dns/result.h> #include <dns/result.h>
#include <dns/rootns.h>
#include <dns/tsig.h> #include <dns/tsig.h>
#include <dns/validator.h> #include <dns/validator.h>
@ -5814,6 +5816,7 @@ prime_done(isc_task_t *task, isc_event_t *event) {
dns_resolver_t *res; dns_resolver_t *res;
dns_fetchevent_t *fevent; dns_fetchevent_t *fevent;
dns_fetch_t *fetch; dns_fetch_t *fetch;
dns_db_t *db = NULL;
REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE); REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
fevent = (dns_fetchevent_t *)event; fevent = (dns_fetchevent_t *)event;
@ -5832,6 +5835,13 @@ prime_done(isc_task_t *task, isc_event_t *event) {
UNLOCK(&res->primelock); UNLOCK(&res->primelock);
UNLOCK(&res->lock); UNLOCK(&res->lock);
if (fevent->result == ISC_R_SUCCESS &&
res->view->cache != NULL && res->view->hints != NULL) {
dns_cache_attachdb(res->view->cache, &db);
dns_root_checkhints(res->view, res->view->hints, db);
dns_db_detach(&db);
}
if (fevent->node != NULL) if (fevent->node != NULL)
dns_db_detachnode(fevent->db, &fevent->node); dns_db_detachnode(fevent->db, &fevent->node);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: rootns.c,v 1.26 2004/03/05 05:09:24 marka Exp $ */ /* $Id: rootns.c,v 1.27 2005/02/07 00:53:29 marka Exp $ */
#include <config.h> #include <config.h>
@ -26,15 +26,18 @@
#include <dns/callbacks.h> #include <dns/callbacks.h>
#include <dns/db.h> #include <dns/db.h>
#include <dns/dbiterator.h> #include <dns/dbiterator.h>
#include <dns/log.h>
#include <dns/fixedname.h> #include <dns/fixedname.h>
#include <dns/log.h>
#include <dns/master.h> #include <dns/master.h>
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/rdatasetiter.h> #include <dns/rdata.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/rdatasetiter.h>
#include <dns/rdatastruct.h> #include <dns/rdatastruct.h>
#include <dns/rdatatype.h>
#include <dns/result.h> #include <dns/result.h>
#include <dns/rootns.h> #include <dns/rootns.h>
#include <dns/view.h>
static char root_ns[] = static char root_ns[] =
";\n" ";\n"
@ -245,3 +248,265 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
return (result); return (result);
} }
static void
report(dns_view_t *view, dns_name_t *name, isc_boolean_t missing,
dns_rdata_t *rdata)
{
const char *viewname = "", *sep = "";
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
char databuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:123.123.123.123")];
isc_buffer_t buffer;
isc_result_t result;
if (strcmp(view->name, "_bind") != 0 &&
strcmp(view->name, "_default") != 0) {
viewname = view->name;
sep = ": view ";
}
dns_name_format(name, namebuf, sizeof(namebuf));
dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
isc_buffer_init(&buffer, databuf, sizeof(databuf) - 1);
result = dns_rdata_totext(rdata, NULL, &buffer);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
databuf[isc_buffer_usedlength(&buffer)] = '\0';
if (missing)
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: %s/%s (%s) missing from hints",
sep, viewname, namebuf, typebuf, databuf);
else
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: %s/%s (%s) extra record "
"in hints", sep, viewname, namebuf, typebuf,
databuf);
}
static isc_boolean_t
inrrset(dns_rdataset_t *rrset, dns_rdata_t *rdata) {
isc_result_t result;
dns_rdata_t current = DNS_RDATA_INIT;
result = dns_rdataset_first(rrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(rrset, &current);
if (dns_rdata_compare(rdata, &current) == 0)
return (ISC_TRUE);
dns_rdata_reset(&current);
result = dns_rdataset_next(rrset);
}
return (ISC_FALSE);
}
/*
* Check that the address RRsets match.
*
* Note we don't complain about missing glue records.
*/
static void
check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
dns_name_t *name, isc_stdtime_t now)
{
isc_result_t hresult, rresult, result;
dns_rdataset_t hintrrset, rootrrset;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_name_t *foundname;
dns_fixedname_t fixed;
dns_rdataset_init(&hintrrset);
dns_rdataset_init(&rootrrset);
dns_fixedname_init(&fixed);
foundname = dns_fixedname_name(&fixed);
hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0,
now, NULL, foundname, &hintrrset, NULL);
rresult = dns_db_find(db, name, NULL, dns_rdatatype_a,
DNS_DBFIND_GLUEOK, now, NULL, foundname,
&rootrrset, NULL);
if (hresult == ISC_R_SUCCESS &&
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rootrrset, &rdata);
if (!inrrset(&hintrrset, &rdata))
report(view, name, ISC_TRUE, &rdata);
result = dns_rdataset_next(&rootrrset);
}
result = dns_rdataset_first(&hintrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&hintrrset, &rdata);
if (!inrrset(&rootrrset, &rdata))
report(view, name, ISC_FALSE, &rdata);
result = dns_rdataset_next(&hintrrset);
}
}
if (hresult == ISC_R_NOTFOUND &&
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rootrrset, &rdata);
report(view, name, ISC_TRUE, &rdata);
result = dns_rdataset_next(&rootrrset);
}
}
if (dns_rdataset_isassociated(&rootrrset))
dns_rdataset_disassociate(&rootrrset);
if (dns_rdataset_isassociated(&hintrrset))
dns_rdataset_disassociate(&hintrrset);
/*
* Check AAAA records.
*/
hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0,
now, NULL, foundname, &hintrrset, NULL);
rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
DNS_DBFIND_GLUEOK, now, NULL, foundname,
&rootrrset, NULL);
if (hresult == ISC_R_SUCCESS &&
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rootrrset, &rdata);
if (!inrrset(&hintrrset, &rdata))
report(view, name, ISC_TRUE, &rdata);
dns_rdata_reset(&rdata);
result = dns_rdataset_next(&rootrrset);
}
result = dns_rdataset_first(&hintrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&hintrrset, &rdata);
if (!inrrset(&rootrrset, &rdata))
report(view, name, ISC_FALSE, &rdata);
dns_rdata_reset(&rdata);
result = dns_rdataset_next(&hintrrset);
}
}
if (hresult == ISC_R_NOTFOUND &&
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rootrrset, &rdata);
report(view, name, ISC_TRUE, &rdata);
dns_rdata_reset(&rdata);
result = dns_rdataset_next(&rootrrset);
}
}
if (dns_rdataset_isassociated(&rootrrset))
dns_rdataset_disassociate(&rootrrset);
if (dns_rdataset_isassociated(&hintrrset))
dns_rdataset_disassociate(&hintrrset);
}
void
dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) {
isc_result_t result;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_ns_t ns;
dns_rdataset_t hintns, rootns;
const char *viewname = "", *sep = "";
isc_stdtime_t now;
dns_name_t *name;
dns_fixedname_t fixed;
REQUIRE(hints != NULL);
REQUIRE(db != NULL);
REQUIRE(view != NULL);
isc_stdtime_get(&now);
if (strcmp(view->name, "_bind") != 0 &&
strcmp(view->name, "_default") != 0) {
viewname = view->name;
sep = ": view ";
}
dns_rdataset_init(&hintns);
dns_rdataset_init(&rootns);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0,
now, NULL, name, &hintns, NULL);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: unable to get root NS rrset "
"from hints: %s", sep, viewname,
dns_result_totext(result));
goto cleanup;
}
result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
now, NULL, name, &rootns, NULL);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: unable to get root NS rrset "
"from cache: %s", sep, viewname,
dns_result_totext(result));
goto cleanup;
}
/*
* Look for missing root NS names.
*/
result = dns_rdataset_first(&rootns);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rootns, &rdata);
result = dns_rdata_tostruct(&rdata, &ns, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = in_rootns(&hintns, &ns.name);
if (result != ISC_R_SUCCESS) {
char namebuf[DNS_NAME_FORMATSIZE];
/* missing from hints */
dns_name_format(&ns.name, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: unable to find root "
"NS '%s' in hints", sep, viewname,
namebuf);
} else
check_address_records(view, hints, db, &ns.name, now);
dns_rdata_reset(&rdata);
result = dns_rdataset_next(&rootns);
}
if (result != ISC_R_NOMORE) {
goto cleanup;
}
/*
* Look for extra root NS names.
*/
result = dns_rdataset_first(&hintns);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&hintns, &rdata);
result = dns_rdata_tostruct(&rdata, &ns, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = in_rootns(&rootns, &ns.name);
if (result != ISC_R_SUCCESS) {
char namebuf[DNS_NAME_FORMATSIZE];
/* extra entry in hints */
dns_name_format(&ns.name, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
"checkhints%s%s: extra NS '%s' in hints",
sep, viewname, namebuf);
}
dns_rdata_reset(&rdata);
result = dns_rdataset_next(&hintns);
}
if (result != ISC_R_NOMORE) {
goto cleanup;
}
cleanup:
if (dns_rdataset_isassociated(&rootns))
dns_rdataset_disassociate(&rootns);
if (dns_rdataset_isassociated(&hintns))
dns_rdataset_disassociate(&hintns);
}