aboutsummaryrefslogtreecommitdiff
path: root/contrib/bind9/bin/check/check-tool.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/bin/check/check-tool.c')
-rw-r--r--contrib/bind9/bin/check/check-tool.c252
1 files changed, 178 insertions, 74 deletions
diff --git a/contrib/bind9/bin/check/check-tool.c b/contrib/bind9/bin/check/check-tool.c
index 2136a63a7588..e0a7208f3788 100644
--- a/contrib/bind9/bin/check/check-tool.c
+++ b/contrib/bind9/bin/check/check-tool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.10.18.20 2008/10/24 01:43:17 tbox Exp $ */
+/* $Id: check-tool.c,v 1.35.36.3 2009/01/20 02:03:18 marka Exp $ */
/*! \file */
@@ -24,16 +24,17 @@
#include <stdio.h>
#include "check-tool.h"
-#include <isc/util.h>
-
#include <isc/buffer.h>
#include <isc/log.h>
-#include <isc/net.h>
+#include <isc/mem.h>
#include <isc/netdb.h>
+#include <isc/net.h>
#include <isc/region.h>
#include <isc/stdio.h>
#include <isc/string.h>
+#include <isc/symtab.h>
#include <isc/types.h>
+#include <isc/util.h>
#include <dns/fixedname.h>
#include <dns/log.h>
@@ -69,6 +70,15 @@
goto cleanup; \
} while (0)
+#define ERR_IS_CNAME 1
+#define ERR_NO_ADDRESSES 2
+#define ERR_LOOKUP_FAILURE 3
+#define ERR_EXTRA_A 4
+#define ERR_EXTRA_AAAA 5
+#define ERR_MISSING_GLUE 5
+#define ERR_IS_MXCNAME 6
+#define ERR_IS_SRVCNAME 7
+
static const char *dbtype[] = { "rbt" };
int debug = 0;
@@ -105,9 +115,62 @@ static isc_logcategory_t categories[] = {
{ "queries", 0 },
{ "unmatched", 0 },
{ "update-security", 0 },
+ { "query-errors", 0 },
{ NULL, 0 }
};
+static isc_symtab_t *symtab = NULL;
+static isc_mem_t *sym_mctx;
+
+static void
+freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
+ UNUSED(type);
+ UNUSED(value);
+ isc_mem_free(userarg, key);
+}
+
+static void
+add(char *key, int value) {
+ isc_result_t result;
+ isc_symvalue_t symvalue;
+
+ if (sym_mctx == NULL) {
+ result = isc_mem_create(0, 0, &sym_mctx);
+ if (result != ISC_R_SUCCESS)
+ return;
+ }
+
+ if (symtab == NULL) {
+ result = isc_symtab_create(sym_mctx, 100, freekey, sym_mctx,
+ ISC_FALSE, &symtab);
+ if (result != ISC_R_SUCCESS)
+ return;
+ }
+
+ key = isc_mem_strdup(sym_mctx, key);
+ if (key == NULL)
+ return;
+
+ symvalue.as_pointer = NULL;
+ result = isc_symtab_define(symtab, key, value, symvalue,
+ isc_symexists_reject);
+ if (result != ISC_R_SUCCESS)
+ isc_mem_free(sym_mctx, key);
+}
+
+static isc_boolean_t
+logged(char *key, int value) {
+ isc_result_t result;
+
+ if (symtab == NULL)
+ return (ISC_FALSE);
+
+ result = isc_symtab_lookup(symtab, key, value, NULL);
+ if (result == ISC_R_SUCCESS)
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+
static isc_boolean_t
checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
dns_rdataset_t *a, dns_rdataset_t *aaaa)
@@ -156,29 +219,39 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
cur->ai_next != NULL)
cur = cur->ai_next;
if (cur != NULL && cur->ai_canonname != NULL &&
- strcasecmp(ai->ai_canonname, namebuf) != 0) {
+ strcasecmp(cur->ai_canonname, namebuf) != 0 &&
+ !logged(namebuf, ERR_IS_CNAME)) {
dns_zone_log(zone, ISC_LOG_ERROR,
"%s/NS '%s' (out of zone) "
- "is a CNAME (illegal)",
- ownerbuf, namebuf);
+ "is a CNAME '%s' (illegal)",
+ ownerbuf, namebuf,
+ cur->ai_canonname);
/* XXX950 make fatal for 9.5.0 */
/* answer = ISC_FALSE; */
+ add(namebuf, ERR_IS_CNAME);
}
break;
case EAI_NONAME:
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
case EAI_NODATA:
#endif
- dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' (out of zone) "
- "has no addresses records (A or AAAA)",
- ownerbuf, namebuf);
+ if (!logged(namebuf, ERR_NO_ADDRESSES)) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%s/NS '%s' (out of zone) "
+ "has no addresses records (A or AAAA)",
+ ownerbuf, namebuf);
+ add(namebuf, ERR_NO_ADDRESSES);
+ }
/* XXX950 make fatal for 9.5.0 */
return (ISC_TRUE);
default:
- dns_zone_log(zone, ISC_LOG_WARNING,
- "getaddrinfo(%s) failed: %s",
- namebuf, gai_strerror(result));
+ if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "getaddrinfo(%s) failed: %s",
+ namebuf, gai_strerror(result));
+ add(namebuf, ERR_LOOKUP_FAILURE);
+ }
return (ISC_TRUE);
}
if (a == NULL || aaaa == NULL)
@@ -201,12 +274,13 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
break;
}
}
- if (!match) {
+ if (!match && !logged(namebuf, ERR_EXTRA_A)) {
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
"extra GLUE A record (%s)",
ownerbuf, namebuf,
inet_ntop(AF_INET, rdata.data,
addrbuf, sizeof(addrbuf)));
+ add(namebuf, ERR_EXTRA_A);
/* XXX950 make fatal for 9.5.0 */
/* answer = ISC_FALSE; */
}
@@ -230,12 +304,13 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
break;
}
}
- if (!match) {
+ if (!match && !logged(namebuf, ERR_EXTRA_AAAA)) {
dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
"extra GLUE AAAA record (%s)",
ownerbuf, namebuf,
inet_ntop(AF_INET6, rdata.data,
addrbuf, sizeof(addrbuf)));
+ add(namebuf, ERR_EXTRA_AAAA);
/* XXX950 make fatal for 9.5.0. */
/* answer = ISC_FALSE; */
}
@@ -247,42 +322,48 @@ checkns(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner,
/*
* Check that all addresses appear in the glue.
*/
- for (cur = ai; cur != NULL; cur = cur->ai_next) {
- switch (cur->ai_family) {
- case AF_INET:
- rdataset = a;
- ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
- type = "A";
- break;
- case AF_INET6:
- rdataset = aaaa;
- ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
- type = "AAAA";
- break;
- default:
- continue;
- }
- match = ISC_FALSE;
- if (dns_rdataset_isassociated(rdataset))
- result = dns_rdataset_first(rdataset);
- else
- result = ISC_R_FAILURE;
- while (result == ISC_R_SUCCESS && !match) {
- dns_rdataset_current(rdataset, &rdata);
- if (memcmp(ptr, rdata.data, rdata.length) == 0)
- match = ISC_TRUE;
- dns_rdata_reset(&rdata);
- result = dns_rdataset_next(rdataset);
- }
- if (!match) {
- dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
- "missing GLUE %s record (%s)",
- ownerbuf, namebuf, type,
- inet_ntop(cur->ai_family, ptr,
- addrbuf, sizeof(addrbuf)));
- /* XXX950 make fatal for 9.5.0. */
- /* answer = ISC_FALSE; */
+ if (!logged(namebuf, ERR_MISSING_GLUE)) {
+ isc_boolean_t missing_glue = ISC_FALSE;
+ for (cur = ai; cur != NULL; cur = cur->ai_next) {
+ switch (cur->ai_family) {
+ case AF_INET:
+ rdataset = a;
+ ptr = &((struct sockaddr_in *)(cur->ai_addr))->sin_addr;
+ type = "A";
+ break;
+ case AF_INET6:
+ rdataset = aaaa;
+ ptr = &((struct sockaddr_in6 *)(cur->ai_addr))->sin6_addr;
+ type = "AAAA";
+ break;
+ default:
+ continue;
+ }
+ match = ISC_FALSE;
+ if (dns_rdataset_isassociated(rdataset))
+ result = dns_rdataset_first(rdataset);
+ else
+ result = ISC_R_FAILURE;
+ while (result == ISC_R_SUCCESS && !match) {
+ dns_rdataset_current(rdataset, &rdata);
+ if (memcmp(ptr, rdata.data, rdata.length) == 0)
+ match = ISC_TRUE;
+ dns_rdata_reset(&rdata);
+ result = dns_rdataset_next(rdataset);
+ }
+ if (!match) {
+ dns_zone_log(zone, ISC_LOG_ERROR, "%s/NS '%s' "
+ "missing GLUE %s record (%s)",
+ ownerbuf, namebuf, type,
+ inet_ntop(cur->ai_family, ptr,
+ addrbuf, sizeof(addrbuf)));
+ /* XXX950 make fatal for 9.5.0. */
+ /* answer = ISC_FALSE; */
+ missing_glue = ISC_TRUE;
+ }
}
+ if (missing_glue)
+ add(namebuf, ERR_MISSING_GLUE);
}
freeaddrinfo(ai);
return (answer);
@@ -332,10 +413,15 @@ checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
if ((zone_options & DNS_ZONEOPT_WARNMXCNAME) != 0)
level = ISC_LOG_WARNING;
if ((zone_options & DNS_ZONEOPT_IGNOREMXCNAME) == 0) {
- dns_zone_log(zone, ISC_LOG_WARNING,
- "%s/MX '%s' (out of zone) "
- "is a CNAME (illegal)",
- ownerbuf, namebuf);
+ if (!logged(namebuf, ERR_IS_MXCNAME)) {
+ dns_zone_log(zone, level,
+ "%s/MX '%s' (out of zone)"
+ " is a CNAME '%s' "
+ "(illegal)",
+ ownerbuf, namebuf,
+ cur->ai_canonname);
+ add(namebuf, ERR_IS_MXCNAME);
+ }
if (level == ISC_LOG_ERROR)
answer = ISC_FALSE;
}
@@ -347,16 +433,23 @@ checkmx(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
case EAI_NODATA:
#endif
- dns_zone_log(zone, ISC_LOG_ERROR, "%s/MX '%s' (out of zone) "
- "has no addresses records (A or AAAA)",
- ownerbuf, namebuf);
+ if (!logged(namebuf, ERR_NO_ADDRESSES)) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%s/MX '%s' (out of zone) "
+ "has no addresses records (A or AAAA)",
+ ownerbuf, namebuf);
+ add(namebuf, ERR_NO_ADDRESSES);
+ }
/* XXX950 make fatal for 9.5.0. */
return (ISC_TRUE);
default:
- dns_zone_log(zone, ISC_LOG_WARNING,
+ if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
"getaddrinfo(%s) failed: %s",
namebuf, gai_strerror(result));
+ add(namebuf, ERR_LOOKUP_FAILURE);
+ }
return (ISC_TRUE);
}
#else
@@ -405,10 +498,14 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
if ((zone_options & DNS_ZONEOPT_WARNSRVCNAME) != 0)
level = ISC_LOG_WARNING;
if ((zone_options & DNS_ZONEOPT_IGNORESRVCNAME) == 0) {
- dns_zone_log(zone, level,
- "%s/SRV '%s' (out of zone) "
- "is a CNAME (illegal)",
- ownerbuf, namebuf);
+ if (!logged(namebuf, ERR_IS_SRVCNAME)) {
+ dns_zone_log(zone, level, "%s/SRV '%s'"
+ " (out of zone) is a "
+ "CNAME '%s' (illegal)",
+ ownerbuf, namebuf,
+ cur->ai_canonname);
+ add(namebuf, ERR_IS_SRVCNAME);
+ }
if (level == ISC_LOG_ERROR)
answer = ISC_FALSE;
}
@@ -420,16 +517,23 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
case EAI_NODATA:
#endif
- dns_zone_log(zone, ISC_LOG_ERROR, "%s/SRV '%s' (out of zone) "
- "has no addresses records (A or AAAA)",
- ownerbuf, namebuf);
+ if (!logged(namebuf, ERR_NO_ADDRESSES)) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "%s/SRV '%s' (out of zone) "
+ "has no addresses records (A or AAAA)",
+ ownerbuf, namebuf);
+ add(namebuf, ERR_NO_ADDRESSES);
+ }
/* XXX950 make fatal for 9.5.0. */
return (ISC_TRUE);
default:
- dns_zone_log(zone, ISC_LOG_WARNING,
- "getaddrinfo(%s) failed: %s",
- namebuf, gai_strerror(result));
+ if (!logged(namebuf, ERR_LOOKUP_FAILURE)) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "getaddrinfo(%s) failed: %s",
+ namebuf, gai_strerror(result));
+ add(namebuf, ERR_LOOKUP_FAILURE);
+ }
return (ISC_TRUE);
}
#else
@@ -438,7 +542,7 @@ checksrv(dns_zone_t *zone, dns_name_t *name, dns_name_t *owner) {
}
isc_result_t
-setup_logging(isc_mem_t *mctx, isc_log_t **logp) {
+setup_logging(isc_mem_t *mctx, FILE *errout, isc_log_t **logp) {
isc_logdestination_t destination;
isc_logconfig_t *logconfig = NULL;
isc_log_t *log = NULL;
@@ -450,7 +554,7 @@ setup_logging(isc_mem_t *mctx, isc_log_t **logp) {
dns_log_setcontext(log);
cfg_log_init(log);
- destination.file.stream = stdout;
+ destination.file.stream = errout;
destination.file.name = NULL;
destination.file.versions = ISC_LOG_ROLLNEVER;
destination.file.maximum_size = 0;
@@ -534,14 +638,14 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
FILE *output = stdout;
if (debug) {
- if (filename != NULL)
+ if (filename != NULL && strcmp(filename, "-") != 0)
fprintf(stderr, "dumping \"%s\" to \"%s\"\n",
zonename, filename);
else
fprintf(stderr, "dumping \"%s\"\n", zonename);
}
- if (filename != NULL) {
+ if (filename != NULL && strcmp(filename, "-") != 0) {
result = isc_stdio_open(filename, "w+", &output);
if (result != ISC_R_SUCCESS) {
@@ -553,7 +657,7 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
result = dns_zone_dumptostream2(zone, output, fileformat, style);
- if (filename != NULL)
+ if (output != stdout)
(void)isc_stdio_close(output);
return (result);