From 4072dfb9b865c82c24a72e734d54da51a20dfc1e Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 20 Nov 2001 05:04:41 +0000 Subject: [PATCH] 1132. [func] Improve UPDATE prerequisite failure diagnotic messages. --- CHANGES | 2 + bin/named/update.c | 92 +++++++++++++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index 2de4d6f786..9180d87f7c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +1132. [func] Improve UPDATE prerequisite failure diagnotic messages. + 1131. [bug] The match-destinations view option did not work with IPv6 destinations. [RT #2073, #2074] diff --git a/bin/named/update.c b/bin/named/update.c index 642cafc4e4..14d785d87d 100644 --- a/bin/named/update.c +++ b/bin/named/update.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.89 2001/09/19 23:08:23 gson Exp $ */ +/* $Id: update.c,v 1.90 2001/11/20 05:04:41 marka Exp $ */ #include @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,34 @@ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) +#define FAILN(code, name, msg) \ + do { \ + result = (code); \ + if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ + char _nbuf[DNS_NAME_FORMATSIZE]; \ + dns_name_format(name, _nbuf, sizeof(_nbuf)); \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "update failed: %s: %s (%s)", _nbuf, \ + msg, isc_result_totext(result)); \ + } \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) + +#define FAILNT(code, name, type, msg) \ + do { \ + result = (code); \ + if (isc_log_wouldlog(ns_g_lctx, LOGLEVEL_PROTOCOL)) { \ + char _nbuf[DNS_NAME_FORMATSIZE]; \ + char _tbuf[DNS_RDATATYPE_FORMATSIZE]; \ + dns_name_format(name, _nbuf, sizeof(_nbuf)); \ + dns_rdatatype_format(type, _tbuf, sizeof(_tbuf)); \ + update_log(client, zone, LOGLEVEL_PROTOCOL, \ + "update failed: %s/%s: %s (%s)", \ + _nbuf, _tbuf, msg, \ + isc_result_totext(result)); \ + } \ + if (result != ISC_R_SUCCESS) goto failure; \ + } while (0) /* * Fail unconditionally and log as a server error. * The test against ISC_R_SUCCESS is there to keep the Solaris compiler @@ -721,11 +750,13 @@ temp_order(const void *av, const void *bv) { * * Return ISC_R_SUCCESS if the prerequisites are satisfied, * rcode(dns_rcode_nxrrset) if not. + * + * 'temp' must be pre-sorted. */ static isc_result_t temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, - dns_dbversion_t *ver) + dns_dbversion_t *ver, dns_name_t *tmpname, dns_rdatatype_t *typep) { isc_result_t result; dns_name_t *name; @@ -733,18 +764,6 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, dns_difftuple_t *t; dns_diff_t trash; - /* Exit early if the list is empty (for efficiency only). */ - if (ISC_LIST_HEAD(temp->tuples) == NULL) - return (ISC_R_SUCCESS); - - /* - * Sort the prerequisite records by owner name, - * type, and rdata. - */ - result = dns_diff_sort(temp, temp_order); - if (result != ISC_R_SUCCESS) - return (result); - dns_diff_init(mctx, &trash); /* @@ -755,6 +774,8 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, t = ISC_LIST_HEAD(temp->tuples); while (t != NULL) { name = &t->name; + (void)dns_name_copy(name, tmpname, NULL); + *typep = t->rdata.type; /* A new unique name begins here. */ node = NULL; @@ -773,7 +794,7 @@ temp_check(isc_mem_t *mctx, dns_diff_t *temp, dns_db_t *db, dns_diff_t u_rrs; /* Update RRs with this name and type */ - type = t->rdata.type; + *typep = type = t->rdata.type; if (type == dns_rdatatype_sig) covers = dns_rdata_covers(&t->rdata); else @@ -2006,6 +2027,8 @@ update_action(isc_task_t *task, isc_event_t *event) { dns_rdataclass_t zoneclass; dns_name_t *zonename; dns_ssutable_t *ssutable = NULL; + dns_fixedname_t tmpnamefixed; + dns_name_t *tmpname = NULL; INSIST(event->ev_type == DNS_EVENT_UPDATE); @@ -2040,7 +2063,7 @@ update_action(isc_task_t *task, isc_event_t *event) { FAILC(DNS_R_FORMERR, "prerequisite TTL is not zero"); if (! dns_name_issubdomain(name, zonename)) - FAILC(DNS_R_NOTZONE, + FAILN(DNS_R_NOTZONE, name, "prerequisite name is out of zone"); if (update_class == dns_rdataclass_any) { @@ -2051,7 +2074,7 @@ update_action(isc_task_t *task, isc_event_t *event) { if (rdata.type == dns_rdatatype_any) { CHECK(name_exists(db, ver, name, &flag)); if (! flag) { - FAILC(DNS_R_NXDOMAIN, + FAILN(DNS_R_NXDOMAIN, name, "'name in use' prerequisite " "not satisfied"); } @@ -2060,7 +2083,7 @@ update_action(isc_task_t *task, isc_event_t *event) { rdata.type, covers, &flag)); if (! flag) { /* RRset does not exist. */ - FAILC(DNS_R_NXRRSET, + FAILNT(DNS_R_NXRRSET, name, rdata.type, "'rrset exists (value independent)' " "prerequisite not satisfied"); } @@ -2073,7 +2096,7 @@ update_action(isc_task_t *task, isc_event_t *event) { if (rdata.type == dns_rdatatype_any) { CHECK(name_exists(db, ver, name, &flag)); if (flag) { - FAILC(DNS_R_YXDOMAIN, + FAILN(DNS_R_YXDOMAIN, name, "'name not in use' prerequisite " "not satisfied"); } @@ -2082,9 +2105,9 @@ update_action(isc_task_t *task, isc_event_t *event) { rdata.type, covers, &flag)); if (flag) { /* RRset exists. */ - FAILC(DNS_R_YXRRSET, - "'rrset does not exist' " - "prerequisite not satisfied"); + FAILNT(DNS_R_YXRRSET, name, rdata.type, + "'rrset does not exist' " + "prerequisite not satisfied"); } } } else if (update_class == zoneclass) { @@ -2103,14 +2126,31 @@ update_action(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_NOMORE) FAIL(result); + /* * Perform the final check of the "rrset exists (value dependent)" * prerequisites. */ - result = temp_check(mctx, &temp, db, ver); - if (result != ISC_R_SUCCESS) - FAILC(result, "'RRset exists (value dependent)' " - "prerequisite not satisfied"); + if (ISC_LIST_HEAD(temp.tuples) != NULL) { + dns_rdatatype_t type; + + /* + * Sort the prerequisite records by owner name, + * type, and rdata. + */ + result = dns_diff_sort(&temp, temp_order); + if (result != ISC_R_SUCCESS) + FAILC(result, "'RRset exists (value dependent)' " + "prerequisite not satisfied"); + + dns_fixedname_init(&tmpnamefixed); + tmpname = dns_fixedname_name(&tmpnamefixed); + result = temp_check(mctx, &temp, db, ver, tmpname, &type); + if (result != ISC_R_SUCCESS) + FAILNT(result, tmpname, type, + "'RRset exists (value dependent)' " + "prerequisite not satisfied"); + } update_log(client, zone, LOGLEVEL_DEBUG, "prerequisites are OK");