]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2849. [bug] Don't treat errors from the xml2 library as fatal.
authorMark Andrews <marka@isc.org>
Thu, 4 Feb 2010 01:10:32 +0000 (01:10 +0000)
committerMark Andrews <marka@isc.org>
Thu, 4 Feb 2010 01:10:32 +0000 (01:10 +0000)
                        [RT #20945]

CHANGES
bin/named/statschannel.c
lib/isc/httpd.c

diff --git a/CHANGES b/CHANGES
index 3a4d21411f682fb87d2ebf3449a8ad13f3762c11..b2bc01c54ae5bc332bba07c03d5ece4ca9a0a0f5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+2849.  [bug]           Don't treat errors from the xml2 library as fatal.
+                       [RT #20945]
+
 2846.  [bug]           EOF on unix domain sockets was not being handled
                        correctly. [RT #20731]
 
index 091a1220ae2fcf61e0105e991e002c9803b15ef6..de003bb2f21e8d702750f40f39fd88dbd8d3bf43 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: statschannel.c,v 1.14.64.9 2009/10/20 03:31:06 marka Exp $ */
+/* $Id: statschannel.c,v 1.14.64.10 2010/02/04 01:10:32 marka Exp $ */
 
 /*! \file */
 
@@ -70,6 +70,7 @@ stats_dumparg {
        int             ncounters;      /* used for general statistics */
        int             *counterindices; /* used for general statistics */
        isc_uint64_t    *countervalues;  /* used for general statistics */
+       isc_result_t    result;
 } stats_dumparg_t;
 
 static isc_once_t once = ISC_ONCE_INIT;
@@ -95,6 +96,8 @@ static const char *sockstats_xmldesc[isc_sockstatscounter_max];
 #define sockstats_xmldesc NULL
 #endif /* HAVE_LIBXML2 */
 
+#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
+
 /*%
  * Mapping arrays to represent statistics counters in the order of our
  * preference, regardless of the order of counter indices.  For example,
@@ -437,7 +440,7 @@ generalstat_dump(isc_statscounter_t counter, isc_uint64_t val, void *arg) {
        dumparg->countervalues[counter] = val;
 }
 
-static void
+static isc_result_t
 dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
              const char *category, const char **desc, int ncounters,
              int *indices, isc_uint64_t *values, int options)
@@ -448,6 +451,7 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
        FILE *fp;
 #ifdef HAVE_LIBXML2
        xmlTextWriterPtr writer;
+       int xmlrc;
 #endif
 
 #ifndef HAVE_LIBXML2
@@ -480,31 +484,41 @@ dump_counters(isc_stats_t *stats, statsformat_t type, void *arg,
                        writer = arg;
 
                        if (category != NULL) {
-                               xmlTextWriterStartElement(writer,
-                                                         ISC_XMLCHAR
-                                                         category);
-                               xmlTextWriterStartElement(writer,
-                                                         ISC_XMLCHAR "name");
-                               xmlTextWriterWriteString(writer, ISC_XMLCHAR
-                                                       desc[index]);
-                               xmlTextWriterEndElement(writer); /* name */
-
-                               xmlTextWriterStartElement(writer, ISC_XMLCHAR
-                                                         "counter");
+                               TRY0(xmlTextWriterStartElement(writer,
+                                                              ISC_XMLCHAR
+                                                              category));
+                               TRY0(xmlTextWriterStartElement(writer,
+                                                              ISC_XMLCHAR
+                                                              "name"));
+                               TRY0(xmlTextWriterWriteString(writer,
+                                                             ISC_XMLCHAR
+                                                             desc[index]));
+                               TRY0(xmlTextWriterEndElement(writer)); /* name */
+
+                               TRY0(xmlTextWriterStartElement(writer,
+                                                              ISC_XMLCHAR
+                                                              "counter"));
                        } else {
-                               xmlTextWriterStartElement(writer, ISC_XMLCHAR
-                                                         desc[index]);
+                               TRY0(xmlTextWriterStartElement(writer,
+                                                              ISC_XMLCHAR
+                                                              desc[index]));
                        }
-                       xmlTextWriterWriteFormatString(writer,
-                                                      "%" ISC_PRINT_QUADFORMAT
-                                                      "u", value);
-                       xmlTextWriterEndElement(writer); /* counter */
+                       TRY0(xmlTextWriterWriteFormatString(writer,
+                                                           "%"
+                                                           ISC_PRINT_QUADFORMAT
+                                                           "u", value));
+                       TRY0(xmlTextWriterEndElement(writer)); /* counter */
                        if (category != NULL)
-                               xmlTextWriterEndElement(writer); /* category */
+                               TRY0(xmlTextWriterEndElement(writer)); /* category */
 #endif
                        break;
                }
        }
+       return (ISC_R_SUCCESS);
+#ifdef HAVE_LIBXML2
+ error:
+       return (ISC_R_FAILURE);
+#endif
 }
 
 static void
@@ -515,6 +529,7 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
        FILE *fp;
 #ifdef HAVE_LIBXML2
        xmlTextWriterPtr writer;
+       int xmlrc;
 #endif
 
        if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE)
@@ -534,22 +549,28 @@ rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
 #ifdef HAVE_LIBXML2
                writer = dumparg->arg;
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype");
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype"));
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
-               xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr);
-               xmlTextWriterEndElement(writer); /* name */
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+               TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr));
+               TRY0(xmlTextWriterEndElement(writer)); /* name */
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
-               xmlTextWriterWriteFormatString(writer,
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+               TRY0(xmlTextWriterWriteFormatString(writer,
                                               "%" ISC_PRINT_QUADFORMAT "u",
-                                              val);
-               xmlTextWriterEndElement(writer); /* counter */
+                                              val));
+               TRY0(xmlTextWriterEndElement(writer)); /* counter */
 
-               xmlTextWriterEndElement(writer); /* rdtype */
+               TRY0(xmlTextWriterEndElement(writer)); /* rdtype */
 #endif
                break;
        }
+       return;
+#ifdef HAVE_LIBXML2
+ error:
+       dumparg->result = ISC_R_FAILURE;
+       return;
+#endif
 }
 
 static void
@@ -561,6 +582,7 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
        isc_boolean_t nxrrset = ISC_FALSE;
 #ifdef HAVE_LIBXML2
        xmlTextWriterPtr writer;
+       int xmlrc;
 #endif
 
        if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_NXDOMAIN)
@@ -589,22 +611,28 @@ rdatasetstats_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) {
 #ifdef HAVE_LIBXML2
                writer = dumparg->arg;
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset");
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
-               xmlTextWriterWriteFormatString(writer, "%s%s",
-                                              nxrrset ? "!" : "", typestr);
-               xmlTextWriterEndElement(writer); /* name */
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rrset"));
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+               TRY0(xmlTextWriterWriteFormatString(writer, "%s%s",
+                                              nxrrset ? "!" : "", typestr));
+               TRY0(xmlTextWriterEndElement(writer)); /* name */
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
-               xmlTextWriterWriteFormatString(writer,
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+               TRY0(xmlTextWriterWriteFormatString(writer,
                                               "%" ISC_PRINT_QUADFORMAT "u",
-                                              val);
-               xmlTextWriterEndElement(writer); /* counter */
+                                              val));
+               TRY0(xmlTextWriterEndElement(writer)); /* counter */
 
-               xmlTextWriterEndElement(writer); /* rrset */
+               TRY0(xmlTextWriterEndElement(writer)); /* rrset */
 #endif
                break;
        }
+       return;
+#ifdef HAVE_LIBXML2
+ error:
+       dumparg->result = ISC_R_FAILURE;
+#endif
+
 }
 
 static void
@@ -615,6 +643,7 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
        stats_dumparg_t *dumparg = arg;
 #ifdef HAVE_LIBXML2
        xmlTextWriterPtr writer;
+       int xmlrc;
 #endif
 
        isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
@@ -630,30 +659,35 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
 #ifdef HAVE_LIBXML2
                writer = dumparg->arg;
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode");
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode"));
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
-               xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf);
-               xmlTextWriterEndElement(writer); /* name */
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+               TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf));
+               TRY0(xmlTextWriterEndElement(writer)); /* name */
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter");
-               xmlTextWriterWriteFormatString(writer,
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+               TRY0(xmlTextWriterWriteFormatString(writer,
                                               "%" ISC_PRINT_QUADFORMAT "u",
-                                              val);
-               xmlTextWriterEndElement(writer); /* counter */
+                                              val));
+               TRY0(xmlTextWriterEndElement(writer)); /* counter */
 
-               xmlTextWriterEndElement(writer); /* opcode */
+               TRY0(xmlTextWriterEndElement(writer)); /* opcode */
 #endif
                break;
        }
+       return;
+
+#ifdef HAVE_LIBXML2
+ error:
+       dumparg->result = ISC_R_FAILURE;
+       return;
+#endif
 }
 
 #ifdef HAVE_LIBXML2
 
 /* XXXMLG below here sucks. */
 
-#define TRY(a) do { result = (a); INSIST(result == ISC_R_SUCCESS); } while(0);
-#define TRY0(a) do { xmlrc = (a); INSIST(xmlrc >= 0); } while(0);
 
 static isc_result_t
 zone_xmlrender(dns_zone_t *zone, void *arg) {
@@ -663,49 +697,55 @@ zone_xmlrender(dns_zone_t *zone, void *arg) {
        xmlTextWriterPtr writer = arg;
        isc_stats_t *zonestats;
        isc_uint64_t nsstat_values[dns_nsstatscounter_max];
+       int xmlrc;
+       isc_result_t result;
 
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone");
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone"));
 
        dns_zone_name(zone, buf, sizeof(buf));
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
-       xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
-       xmlTextWriterEndElement(writer);
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+       TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
+       TRY0(xmlTextWriterEndElement(writer));
 
        rdclass = dns_zone_getclass(zone);
        dns_rdataclass_format(rdclass, buf, sizeof(buf));
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass");
-       xmlTextWriterWriteString(writer, ISC_XMLCHAR buf);
-       xmlTextWriterEndElement(writer);
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass"));
+       TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf));
+       TRY0(xmlTextWriterEndElement(writer));
 
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial");
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial"));
        if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS)
-               xmlTextWriterWriteFormatString(writer, "%u", serial);
+               TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial));
        else
-               xmlTextWriterWriteString(writer, ISC_XMLCHAR "-");
-       xmlTextWriterEndElement(writer);
+               TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-"));
+       TRY0(xmlTextWriterEndElement(writer));
 
        zonestats = dns_zone_getrequeststats(zone);
        if (zonestats != NULL) {
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters");
-               dump_counters(zonestats, statsformat_xml, writer, NULL,
-                             nsstats_xmldesc, dns_nsstatscounter_max,
-                             nsstats_index, nsstat_values,
-                             ISC_STATSDUMP_VERBOSE);
-               xmlTextWriterEndElement(writer); /* counters */
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               result = dump_counters(zonestats, statsformat_xml, writer, NULL,
+                                     nsstats_xmldesc, dns_nsstatscounter_max,
+                                     nsstats_index, nsstat_values,
+                                     ISC_STATSDUMP_VERBOSE);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+               TRY0(xmlTextWriterEndElement(writer)); /* counters */
        }
 
-       xmlTextWriterEndElement(writer); /* zone */
+       TRY0(xmlTextWriterEndElement(writer)); /* zone */
 
        return (ISC_R_SUCCESS);
+ error:
+       return (ISC_R_FAILURE);
 }
 
-static void
+static isc_result_t
 generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
        char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"];
        char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"];
        isc_time_t now;
-       xmlTextWriterPtr writer;
-       xmlDocPtr doc;
+       xmlTextWriterPtr writer = NULL;
+       xmlDocPtr doc = NULL;
        int xmlrc;
        dns_view_t *view;
        stats_dumparg_t dumparg;
@@ -714,12 +754,15 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
        isc_uint64_t resstat_values[dns_resstatscounter_max];
        isc_uint64_t zonestat_values[dns_zonestatscounter_max];
        isc_uint64_t sockstat_values[isc_sockstatscounter_max];
+       isc_result_t result;
 
        isc_time_now(&now);
        isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
        isc_time_formatISO8601(&now, nowstr, sizeof nowstr);
 
        writer = xmlNewTextWriterDoc(&doc, 0);
+       if (writer == NULL)
+               goto error;
        TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL));
        TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet",
                        ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\""));
@@ -743,27 +786,36 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
        view = ISC_LIST_HEAD(server->viewlist);
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views"));
        while (view != NULL) {
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "view");
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"));
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
-               xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name);
-               xmlTextWriterEndElement(writer);
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+               TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name));
+               TRY0(xmlTextWriterEndElement(writer));
 
-               xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones");
-               dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender,
-                            writer);
-               xmlTextWriterEndElement(writer);
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones"));
+               result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender,
+                                     writer);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+               TRY0(xmlTextWriterEndElement(writer));
 
                if (view->resquerystats != NULL) {
+                       dumparg.result = ISC_R_SUCCESS;
                        dns_rdatatypestats_dump(view->resquerystats,
                                                rdtypestat_dump, &dumparg, 0);
+                       if (dumparg.result != ISC_R_SUCCESS)
+                               goto error;
                }
 
                if (view->resstats != NULL) {
-                       dump_counters(view->resstats, statsformat_xml, writer,
-                                     "resstat", resstats_xmldesc,
-                                     dns_resstatscounter_max, resstats_index,
-                                     resstat_values, ISC_STATSDUMP_VERBOSE);
+                       result = dump_counters(view->resstats, statsformat_xml,
+                                              writer, "resstat",
+                                              resstats_xmldesc,
+                                              dns_resstatscounter_max,
+                                              resstats_index, resstat_values,
+                                              ISC_STATSDUMP_VERBOSE);
+                       if (result != ISC_R_SUCCESS)
+                               goto error;
                }
 
                cachestats = dns_db_getrrsetstats(view->cachedb);
@@ -774,12 +826,15 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
                                                         ISC_XMLCHAR "name",
                                                         ISC_XMLCHAR
                                                         view->name));
+                       dumparg.result = ISC_R_SUCCESS;
                        dns_rdatasetstats_dump(cachestats, rdatasetstats_dump,
                                               &dumparg, 0);
+                       if (dumparg.result != ISC_R_SUCCESS)
+                               goto error;
                        TRY0(xmlTextWriterEndElement(writer)); /* cache */
                }
 
-               xmlTextWriterEndElement(writer); /* view */
+               TRY0(xmlTextWriterEndElement(writer)); /* view */
 
                view = ISC_LIST_NEXT(view, link);
        }
@@ -794,44 +849,63 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
        TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */
 
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server"));
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time");
-       xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime);
-       xmlTextWriterEndElement(writer);
-       xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time");
-       xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
-       xmlTextWriterEndElement(writer);
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"));
+       TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime));
+       TRY0(xmlTextWriterEndElement(writer));
+       TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"));
+       TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr));
+       TRY0(xmlTextWriterEndElement(writer));
 
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests"));
+       dumparg.result = ISC_R_SUCCESS;
        dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg,
                             0);
-       xmlTextWriterEndElement(writer); /* requests */
+       if (dumparg.result != ISC_R_SUCCESS)
+               goto error;
+       TRY0(xmlTextWriterEndElement(writer)); /* requests */
 
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in"));
+       dumparg.result = ISC_R_SUCCESS;
        dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
                                &dumparg, 0);
-       xmlTextWriterEndElement(writer); /* queries-in */
-
-       dump_counters(server->nsstats, statsformat_xml, writer,
-                     "nsstat", nsstats_xmldesc, dns_nsstatscounter_max,
-                     nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE);
-
-       dump_counters(server->zonestats, statsformat_xml, writer, "zonestat",
-                     zonestats_xmldesc, dns_zonestatscounter_max,
-                     zonestats_index, zonestat_values, ISC_STATSDUMP_VERBOSE);
+       if (dumparg.result != ISC_R_SUCCESS)
+               goto error;
+       TRY0(xmlTextWriterEndElement(writer)); /* queries-in */
+
+       result = dump_counters(server->nsstats, statsformat_xml, writer,
+                              "nsstat", nsstats_xmldesc,
+                               dns_nsstatscounter_max,
+                               nsstats_index, nsstat_values,
+                               ISC_STATSDUMP_VERBOSE);
+       if (result != ISC_R_SUCCESS)
+               goto error;
+
+       result = dump_counters(server->zonestats, statsformat_xml, writer,
+                              "zonestat", zonestats_xmldesc,
+                              dns_zonestatscounter_max, zonestats_index,
+                              zonestat_values, ISC_STATSDUMP_VERBOSE);
+       if (result != ISC_R_SUCCESS)
+               goto error;
 
        /*
         * Most of the common resolver statistics entries are 0, so we don't
         * use the verbose dump here.
         */
-       dump_counters(server->resolverstats, statsformat_xml, writer, "resstat",
-                     resstats_xmldesc, dns_resstatscounter_max, resstats_index,
-                     resstat_values, 0);
-
-       dump_counters(server->sockstats, statsformat_xml, writer, "sockstat",
-                     sockstats_xmldesc, isc_sockstatscounter_max,
-                     sockstats_index, sockstat_values, ISC_STATSDUMP_VERBOSE);
-
-       xmlTextWriterEndElement(writer); /* server */
+       result = dump_counters(server->resolverstats, statsformat_xml, writer,
+                              "resstat", resstats_xmldesc,
+                              dns_resstatscounter_max, resstats_index,
+                              resstat_values, 0);
+       if (result != ISC_R_SUCCESS)
+               goto error;
+
+       result = dump_counters(server->sockstats, statsformat_xml, writer,
+                              "sockstat", sockstats_xmldesc,
+                              isc_sockstatscounter_max, sockstats_index,
+                              sockstat_values, ISC_STATSDUMP_VERBOSE);
+       if (result != ISC_R_SUCCESS)
+               goto error;
+
+       TRY0(xmlTextWriterEndElement(writer)); /* server */
 
        TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory"));
        isc_mem_renderxml(writer);
@@ -847,6 +921,14 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
 
        xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1);
        xmlFreeDoc(doc);
+       return (ISC_R_SUCCESS);
+
+ error:
+       if (writer != NULL)
+               xmlFreeTextWriter(writer);
+       if (doc != NULL)
+               xmlFreeDoc(doc);
+       return (ISC_R_FAILURE);
 }
 
 static void
@@ -865,21 +947,24 @@ render_index(const char *url, const char *querystring, void *arg,
        unsigned char *msg;
        int msglen;
        ns_server_t *server = arg;
+       isc_result_t result;
 
        UNUSED(url);
        UNUSED(querystring);
 
-       generatexml(server, &msglen, &msg);
+       result = generatexml(server, &msglen, &msg);
 
-       *retcode = 200;
-       *retmsg = "OK";
-       *mimetype = "text/xml";
-       isc_buffer_reinit(b, msg, msglen);
-       isc_buffer_add(b, msglen);
-       *freecb = wrap_xmlfree;
-       *freecb_args = NULL;
+       if (result == ISC_R_SUCCESS) {
+               *retcode = 200;
+               *retmsg = "OK";
+               *mimetype = "text/xml";
+               isc_buffer_reinit(b, msg, msglen);
+               isc_buffer_add(b, msglen);
+               *freecb = wrap_xmlfree;
+               *freecb_args = NULL;
+       }
 
-       return (ISC_R_SUCCESS);
+       return (result);
 }
 
 #endif /* HAVE_LIBXML2 */
@@ -1280,20 +1365,20 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
        }
 
        fprintf(fp, "++ Name Server Statistics ++\n");
-       dump_counters(server->nsstats, statsformat_file, fp, NULL,
-                     nsstats_desc, dns_nsstatscounter_max, nsstats_index,
-                     nsstat_values, 0);
+       (void) dump_counters(server->nsstats, statsformat_file, fp, NULL,
+                            nsstats_desc, dns_nsstatscounter_max,
+                            nsstats_index, nsstat_values, 0);
 
        fprintf(fp, "++ Zone Maintenance Statistics ++\n");
-       dump_counters(server->zonestats, statsformat_file, fp, NULL,
-                     zonestats_desc, dns_zonestatscounter_max,
-                     zonestats_index, zonestat_values, 0);
+       (void) dump_counters(server->zonestats, statsformat_file, fp, NULL,
+                            zonestats_desc, dns_zonestatscounter_max,
+                            zonestats_index, zonestat_values, 0);
 
        fprintf(fp, "++ Resolver Statistics ++\n");
        fprintf(fp, "[Common]\n");
-       dump_counters(server->resolverstats, statsformat_file, fp, NULL,
-                     resstats_desc, dns_resstatscounter_max, resstats_index,
-                     resstat_values, 0);
+       (void) dump_counters(server->resolverstats, statsformat_file, fp, NULL,
+                            resstats_desc, dns_resstatscounter_max,
+                            resstats_index, resstat_values, 0);
        for (view = ISC_LIST_HEAD(server->viewlist);
             view != NULL;
             view = ISC_LIST_NEXT(view, link)) {
@@ -1303,9 +1388,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
                        fprintf(fp, "[View: default]\n");
                else
                        fprintf(fp, "[View: %s]\n", view->name);
-               dump_counters(view->resstats, statsformat_file, fp, NULL,
-                             resstats_desc, dns_resstatscounter_max,
-                             resstats_index, resstat_values, 0);
+               (void) dump_counters(view->resstats, statsformat_file, fp, NULL,
+                                    resstats_desc, dns_resstatscounter_max,
+                                    resstats_index, resstat_values, 0);
        }
 
        fprintf(fp, "++ Cache DB RRsets ++\n");
@@ -1326,9 +1411,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
        }
 
        fprintf(fp, "++ Socket I/O Statistics ++\n");
-       dump_counters(server->sockstats, statsformat_file, fp, NULL,
-                     sockstats_desc, isc_sockstatscounter_max, sockstats_index,
-                     sockstat_values, 0);
+       (void) dump_counters(server->sockstats, statsformat_file, fp, NULL,
+                            sockstats_desc, isc_sockstatscounter_max,
+                            sockstats_index, sockstat_values, 0);
 
        fprintf(fp, "++ Per Zone Query Statistics ++\n");
        zone = NULL;
@@ -1349,9 +1434,10 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
                                fprintf(fp, " (view: %s)", view->name);
                        fprintf(fp, "]\n");
 
-                       dump_counters(zonestats, statsformat_file, fp, NULL,
-                                     nsstats_desc, dns_nsstatscounter_max,
-                                     nsstats_index, nsstat_values, 0);
+                       (void) dump_counters(zonestats, statsformat_file, fp,
+                                            NULL, nsstats_desc,
+                                            dns_nsstatscounter_max,
+                                            nsstats_index, nsstat_values, 0);
                }
        }
 
index fa313253b3e93e4f1c48b9d84e14a9668ecc1ab8..94d38d01055a589f1a1bc5ad2e712b96a48f4d71 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: httpd.c,v 1.16 2008/08/08 05:06:49 marka Exp $ */
+/* $Id: httpd.c,v 1.16.64.1 2010/02/04 01:10:32 marka Exp $ */
 
 /*! \file */
 
@@ -151,6 +151,7 @@ struct isc_httpdmgr {
 
        ISC_LIST(isc_httpdurl_t) urls;          /*%< urls we manage */
        isc_httpdaction_t      *render_404;
+       isc_httpdaction_t      *render_500;
 };
 
 /*%
@@ -221,6 +222,11 @@ static isc_result_t render_404(const char *, const char *,
                               unsigned int *, const char **,
                               const char **, isc_buffer_t *,
                               isc_httpdfree_t **, void **);
+static isc_result_t render_500(const char *, const char *,
+                              void *,
+                              unsigned int *, const char **,
+                              const char **, isc_buffer_t *,
+                              isc_httpdfree_t **, void **);
 
 static void
 destroy_client(isc_httpd_t **httpdp)
@@ -300,6 +306,7 @@ isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
                goto cleanup;
 
        httpd->render_404 = render_404;
+       httpd->render_500 = render_500;
 
        *httpdp = httpd;
        return (ISC_R_SUCCESS);
@@ -623,6 +630,30 @@ render_404(const char *url, const char *querystring,
        return (ISC_R_SUCCESS);
 }
 
+static isc_result_t
+render_500(const char *url, const char *querystring,
+          void *arg,
+          unsigned int *retcode, const char **retmsg,
+          const char **mimetype, isc_buffer_t *b,
+          isc_httpdfree_t **freecb, void **freecb_args)
+{
+       static char msg[] = "Internal server failure.";
+
+       UNUSED(url);
+       UNUSED(querystring);
+       UNUSED(arg);
+
+       *retcode = 500;
+       *retmsg = "Internal server failure";
+       *mimetype = "text/plain";
+       isc_buffer_reinit(b, msg, strlen(msg));
+       isc_buffer_add(b, strlen(msg));
+       *freecb = NULL;
+       *freecb_args = NULL;
+
+       return (ISC_R_SUCCESS);
+}
+
 static void
 isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev)
 {
@@ -691,8 +722,14 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev)
                                     &httpd->mimetype, &httpd->bodybuffer,
                                     &httpd->freecb, &httpd->freecb_arg);
        if (result != ISC_R_SUCCESS) {
-               destroy_client(&httpd);
-               goto out;
+           result = httpd->mgr->render_500(httpd->url, httpd->querystring,
+                                           NULL,
+                                           &httpd->retcode,
+                                           &httpd->retmsg,
+                                           &httpd->mimetype,
+                                           &httpd->bodybuffer,
+                                           &httpd->freecb,
+                                           &httpd->freecb_arg);
        }
 
        isc_httpd_response(httpd);