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:
parent
07bf7b758c
commit
4296c5480d
3
CHANGES
3
CHANGES
@ -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]
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
271
lib/dns/rootns.c
271
lib/dns/rootns.c
@ -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, ¤t);
|
||||||
|
if (dns_rdata_compare(rdata, ¤t) == 0)
|
||||||
|
return (ISC_TRUE);
|
||||||
|
dns_rdata_reset(¤t);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user