]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4402. [func] Collect statistics for RSSAC02v3 traffic-volume,
authorMark Andrews <marka@isc.org>
Wed, 22 Jun 2016 22:44:54 +0000 (08:44 +1000)
committerMark Andrews <marka@isc.org>
Wed, 22 Jun 2016 22:44:54 +0000 (08:44 +1000)
                        traffic-sizes and rcode-volume reporting. [RT #41475]

14 files changed:
CHANGES
bin/named/client.c
bin/named/include/named/server.h
bin/named/server.c
bin/named/statschannel.c
bin/tests/system/conf.sh.in
bin/tests/system/statschannel/server-json.pl
bin/tests/system/statschannel/tests.sh
bin/tests/system/statschannel/traffic-json.pl
bin/tests/system/statschannel/traffic-xml.pl
lib/dns/include/dns/stats.h
lib/dns/include/dns/types.h
lib/dns/stats.c
lib/dns/win32/libdns.def.in

diff --git a/CHANGES b/CHANGES
index 294e787056f121ebd4bebf9e4f49029865850649..9e995321116be380455fdda5c1d04920f4a2103d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4402.  [func]          Collect statistics for RSSAC02v3 traffic-volume,
+                       traffic-sizes and rcode-volume reporting. [RT #41475]
+
 4401.  [bug]           Fix leaks in contrib DLZ code. [RT #42707]
 
 4400.  [doc]           Description of masters with TSIG, allow-query and
index 5a74e818ed579777c05f853c3b77e7c189755991..850d31816535154765941c6d71c8a0944b443210 100644 (file)
@@ -1199,8 +1199,20 @@ client_send(ns_client_t *client) {
                }
 #endif /* HAVE_DNSTAP */
 
-               isc_stats_increment(ns_g_server->tcpoutstats,
-                                   ISC_MIN((int)respsize / 16, 256));
+               
+               switch (isc_sockaddr_pf(&client->peeraddr)) {
+               case AF_INET:
+                       isc_stats_increment(ns_g_server->tcpoutstats4,
+                                           ISC_MIN((int)respsize / 16, 256));
+                       break;
+               case AF_INET6:
+                       isc_stats_increment(ns_g_server->tcpoutstats6,
+                                           ISC_MIN((int)respsize / 16, 256));
+                       break;
+               default:
+                       INSIST(0);
+                       break;
+               }
        } else {
                respsize = isc_buffer_usedlength(&buffer);
                result = client_sendpkg(client, &buffer);
@@ -1213,13 +1225,26 @@ client_send(ns_client_t *client) {
                }
 #endif /* HAVE_DNSTAP */
 
-               isc_stats_increment(ns_g_server->udpoutstats,
-                                   ISC_MIN((int)respsize / 16, 256));
+               switch (isc_sockaddr_pf(&client->peeraddr)) {
+               case AF_INET:
+                       isc_stats_increment(ns_g_server->udpoutstats4,
+                                           ISC_MIN((int)respsize / 16, 256));
+                       break;
+               case AF_INET6:
+                       isc_stats_increment(ns_g_server->udpoutstats6,
+                                           ISC_MIN((int)respsize / 16, 256));
+                       break;
+               default:
+                       INSIST(0);
+                       break;
+               }
        }
 
        /* update statistics (XXXJT: is it okay to access message->xxxkey?) */
        isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response);
 
+       dns_rcodestats_increment(ns_g_server->rcodestats,
+                                client->message->rcode);
        if (opt_included) {
                isc_stats_increment(ns_g_server->nsstats,
                                    dns_nsstatscounter_edns0out);
@@ -2332,11 +2357,33 @@ client_request(isc_task_t *task, isc_event_t *event) {
        if (TCP_CLIENT(client)) {
                isc_stats_increment(ns_g_server->nsstats,
                                    dns_nsstatscounter_requesttcp);
-               isc_stats_increment(ns_g_server->tcpinstats,
-                                   ISC_MIN((int)reqsize / 16, 18));
+               switch (isc_sockaddr_pf(&client->peeraddr)) {
+               case AF_INET:
+                       isc_stats_increment(ns_g_server->tcpinstats4,
+                                           ISC_MIN((int)reqsize / 16, 18));
+                       break;
+               case AF_INET6:
+                       isc_stats_increment(ns_g_server->tcpinstats6,
+                                           ISC_MIN((int)reqsize / 16, 18));
+                       break;
+               default:
+                       INSIST(0);
+                       break;
+               }
        } else {
-               isc_stats_increment(ns_g_server->udpinstats,
-                                   ISC_MIN((int)reqsize / 16, 18));
+               switch (isc_sockaddr_pf(&client->peeraddr)) {
+               case AF_INET:
+                       isc_stats_increment(ns_g_server->udpinstats4,
+                                           ISC_MIN((int)reqsize / 16, 18));
+                       break;
+               case AF_INET6:
+                       isc_stats_increment(ns_g_server->udpinstats6,
+                                           ISC_MIN((int)reqsize / 16, 18));
+                       break;
+               default:
+                       INSIST(0);
+                       break;
+               }
        }
 
        /*
index 3f2943fac0402b46841777646fe42dcb4c4ac65c..8cdfe79b316dcc381ae7f037d1d2b4f07220838c 100644 (file)
@@ -101,10 +101,15 @@ struct ns_server {
        isc_stats_t *           zonestats;      /*% Zone management stats */
        isc_stats_t  *          resolverstats;  /*% Resolver stats */
        isc_stats_t *           sockstats;      /*%< Socket stats */
-       isc_stats_t *           udpinstats;     /*%< Traffic size: UDP in */
-       isc_stats_t *           udpoutstats;    /*%< Traffic size: UDP out */
-       isc_stats_t *           tcpinstats;     /*%< Traffic size: TCP in */
-       isc_stats_t *           tcpoutstats;    /*%< Traffic size: TCP out */
+       isc_stats_t *           udpinstats4;    /*%< Traffic size: UDPv4 in */
+       isc_stats_t *           udpoutstats4;   /*%< Traffic size: UDPv4 out */
+       isc_stats_t *           udpinstats6;    /*%< Traffic size: UDPv6 in */
+       isc_stats_t *           udpoutstats6;   /*%< Traffic size: UDPv6 out */
+       isc_stats_t *           tcpinstats4;    /*%< Traffic size: TCPv4 in */
+       isc_stats_t *           tcpoutstats4;   /*%< Traffic size: TCPv4 out */
+       isc_stats_t *           tcpinstats6;    /*%< Traffic size: TCPv6 in */
+       isc_stats_t *           tcpoutstats6;   /*%< Traffic size: TCPv6 out */
+       dns_stats_t *           rcodestats;     /*%< Sent Response code stats */
 
        ns_controls_t *         controls;       /*%< Control channels */
        unsigned int            dispatchgen;
index 8fc8ff6df499d521fccdbe2a344ae1d0d24a3f2f..61433dab17672dbd7ceb383aa6ce3d0b2628ebc4 100644 (file)
@@ -7834,13 +7834,18 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
        server->nsstats = NULL;
        server->rcvquerystats = NULL;
        server->opcodestats = NULL;
+       server->rcodestats = NULL;
        server->zonestats = NULL;
        server->resolverstats = NULL;
        server->sockstats = NULL;
-       server->udpinstats = NULL;
-       server->udpoutstats = NULL;
-       server->tcpinstats = NULL;
-       server->tcpoutstats = NULL;
+       server->udpinstats4 = NULL;
+       server->udpoutstats4 = NULL;
+       server->udpinstats6 = NULL;
+       server->udpoutstats6 = NULL;
+       server->tcpinstats4 = NULL;
+       server->tcpoutstats4 = NULL;
+       server->tcpinstats6 = NULL;
+       server->tcpoutstats6 = NULL;
        CHECKFATAL(isc_stats_create(server->mctx, &server->sockstats,
                                    isc_sockstatscounter_max),
                   "isc_stats_create");
@@ -7882,6 +7887,9 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
        CHECKFATAL(dns_opcodestats_create(ns_g_mctx, &server->opcodestats),
                   "dns_stats_create (opcode)");
 
+       CHECKFATAL(dns_rcodestats_create(ns_g_mctx, &server->rcodestats),
+                  "dns_stats_create (rcode)");
+
        CHECKFATAL(isc_stats_create(ns_g_mctx, &server->zonestats,
                                    dns_zonestatscounter_max),
                   "dns_stats_create (zone)");
@@ -7890,21 +7898,37 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
                                    dns_resstatscounter_max),
                   "dns_stats_create (resolver)");
 
-       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats,
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats4,
+                                   dns_sizecounter_in_max),
+                  "dns_stats_create (inbound UDP IPv4 traffic size)");
+
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats4,
+                                   dns_sizecounter_out_max),
+                  "dns_stats_create (outbound UDP IPv4 traffic size)");
+
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpinstats6,
+                                   dns_sizecounter_in_max),
+                  "dns_stats_create (inbound UDP IPv6 traffic size)");
+
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats6,
+                                   dns_sizecounter_out_max),
+                  "dns_stats_create (outbound UDP IPv6 traffic size)");
+
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats4,
                                    dns_sizecounter_in_max),
-                  "dns_stats_create (inbound UDP traffic size)");
+                  "dns_stats_create (inbound TCP IPv4 traffic size)");
 
-       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->udpoutstats,
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats4,
                                    dns_sizecounter_out_max),
-                  "dns_stats_create (outbound UDP traffic size)");
+                  "dns_stats_create (outbound TCP IPv4 traffic size)");
 
-       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats,
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpinstats6,
                                    dns_sizecounter_in_max),
-                  "dns_stats_create (inbound TCP traffic size)");
+                  "dns_stats_create (inbound TCP IPv6 traffic size)");
 
-       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats,
+       CHECKFATAL(isc_stats_create(ns_g_mctx, &server->tcpoutstats6,
                                    dns_sizecounter_out_max),
-                  "dns_stats_create (outbound TCP traffic size)");
+                  "dns_stats_create (outbound TCP IPv6 traffic size)");
 
        server->flushonshutdown = ISC_FALSE;
        server->log_queries = ISC_FALSE;
@@ -7948,13 +7972,18 @@ ns_server_destroy(ns_server_t **serverp) {
        isc_stats_detach(&server->nsstats);
        dns_stats_detach(&server->rcvquerystats);
        dns_stats_detach(&server->opcodestats);
+       dns_stats_detach(&server->rcodestats);
        isc_stats_detach(&server->zonestats);
        isc_stats_detach(&server->resolverstats);
        isc_stats_detach(&server->sockstats);
-       isc_stats_detach(&server->udpinstats);
-       isc_stats_detach(&server->udpoutstats);
-       isc_stats_detach(&server->tcpinstats);
-       isc_stats_detach(&server->tcpoutstats);
+       isc_stats_detach(&server->udpinstats4);
+       isc_stats_detach(&server->udpoutstats4);
+       isc_stats_detach(&server->udpinstats6);
+       isc_stats_detach(&server->udpoutstats6);
+       isc_stats_detach(&server->tcpinstats4);
+       isc_stats_detach(&server->tcpoutstats4);
+       isc_stats_detach(&server->tcpinstats6);
+       isc_stats_detach(&server->tcpoutstats6);
 
        isc_mem_free(server->mctx, server->statsfile);
        isc_mem_free(server->mctx, server->bindkeysfile);
index 5bc2f21967c7d7a4ae2725a0818de0718685fede..8d507761e632996fca141509c8b48d276be2e2b9 100644 (file)
 #include <dns/cache.h>
 #include <dns/db.h>
 #include <dns/opcode.h>
-#include <dns/resolver.h>
+#include <dns/rcode.h>
 #include <dns/rdataclass.h>
 #include <dns/rdatatype.h>
+#include <dns/resolver.h>
 #include <dns/stats.h>
 #include <dns/view.h>
 #include <dns/zt.h>
@@ -1279,8 +1280,8 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
                                                 ISC_XMLCHAR codebuf ));
                TRY0(xmlTextWriterWriteFormatString(writer,
-                                                      "%" ISC_PRINT_QUADFORMAT "u",
-                                                      val));
+                                               "%" ISC_PRINT_QUADFORMAT "u",
+                                               val));
                TRY0(xmlTextWriterEndElement(writer)); /* counter */
 #endif
                break;
@@ -1305,6 +1306,62 @@ opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) {
 #endif
 }
 
+static void
+rcodestat_dump(dns_rcode_t code, isc_uint64_t val, void *arg) {
+       FILE *fp;
+       isc_buffer_t b;
+       char codebuf[64];
+       stats_dumparg_t *dumparg = arg;
+#ifdef HAVE_LIBXML2
+       xmlTextWriterPtr writer;
+       int xmlrc;
+#endif
+#ifdef HAVE_JSON
+       json_object *zoneobj, *obj;
+#endif
+
+       isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1);
+       dns_rcode_totext(code, &b);
+       codebuf[isc_buffer_usedlength(&b)] = '\0';
+
+       switch (dumparg->type) {
+       case isc_statsformat_file:
+               fp = dumparg->arg;
+               fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, codebuf);
+               break;
+       case isc_statsformat_xml:
+#ifdef HAVE_LIBXML2
+               writer = dumparg->arg;
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name",
+                                                ISC_XMLCHAR codebuf ));
+               TRY0(xmlTextWriterWriteFormatString(writer,
+                                               "%" ISC_PRINT_QUADFORMAT "u",
+                                               val));
+               TRY0(xmlTextWriterEndElement(writer)); /* counter */
+#endif
+               break;
+       case isc_statsformat_json:
+#ifdef HAVE_JSON
+               zoneobj = (json_object *) dumparg->arg;
+               obj = json_object_new_int64(val);
+               if (obj == NULL)
+                       return;
+               json_object_object_add(zoneobj, codebuf, obj);
+#endif
+               break;
+       }
+       return;
+
+#ifdef HAVE_LIBXML2
+ error:
+       isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER,
+                     ISC_LOG_ERROR, "failed at rcodestat_dump()");
+       dumparg->result = ISC_R_FAILURE;
+       return;
+#endif
+}
+
 #ifdef HAVE_LIBXML2
 /*
  * Which statistics to include when rendering to XML
@@ -1480,6 +1537,17 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
 
                TRY0(xmlTextWriterEndElement(writer));
 
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+                                                ISC_XMLCHAR "rcode"));
+
+               dns_rcodestats_dump(server->rcodestats, rcodestat_dump,
+                                   &dumparg, ISC_STATSDUMP_VERBOSE);
+               if (dumparg.result != ISC_R_SUCCESS)
+                       goto error;
+
+               TRY0(xmlTextWriterEndElement(writer));
+
                TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "qtype"));
@@ -1555,12 +1623,13 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
 
        if ((flags & STATS_XML_TRAFFIC) != 0) {
                TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "traffic"));
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv4"));
                TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
                TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "request-size"));
 
-               result = dump_counters(server->udpinstats,
+               result = dump_counters(server->udpinstats4,
                                       isc_statsformat_xml, writer,
                                       NULL, udpinsizestats_xmldesc,
                                       dns_sizecounter_in_max,
@@ -1575,7 +1644,7 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "response-size"));
 
-               result = dump_counters(server->udpoutstats,
+               result = dump_counters(server->udpoutstats4,
                                       isc_statsformat_xml, writer,
                                       NULL, udpoutsizestats_xmldesc,
                                       dns_sizecounter_out_max,
@@ -1592,7 +1661,7 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "request-size"));
 
-               result = dump_counters(server->tcpinstats,
+               result = dump_counters(server->tcpinstats4,
                                       isc_statsformat_xml, writer,
                                       NULL, tcpinsizestats_xmldesc,
                                       dns_sizecounter_in_max,
@@ -1607,7 +1676,7 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
                TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
                                                 ISC_XMLCHAR "response-size"));
 
-               result = dump_counters(server->tcpoutstats,
+               result = dump_counters(server->tcpoutstats4,
                                       isc_statsformat_xml, writer,
                                       NULL, tcpoutsizestats_xmldesc,
                                       dns_sizecounter_out_max,
@@ -1618,10 +1687,76 @@ generatexml(ns_server_t *server, isc_uint32_t flags,
 
                TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
                TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
+               TRY0(xmlTextWriterEndElement(writer)); /* </ipv4> */
+
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ipv6"));
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "udp"));
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+                                                ISC_XMLCHAR "request-size"));
+
+               result = dump_counters(server->udpinstats6,
+                                      isc_statsformat_xml, writer,
+                                      NULL, udpinsizestats_xmldesc,
+                                      dns_sizecounter_in_max,
+                                      udpinsizestats_index,
+                                      udpinsizestat_values, 0);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+
+               TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
+
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+                                                ISC_XMLCHAR "response-size"));
+
+               result = dump_counters(server->udpoutstats6,
+                                      isc_statsformat_xml, writer,
+                                      NULL, udpoutsizestats_xmldesc,
+                                      dns_sizecounter_out_max,
+                                      udpoutsizestats_index,
+                                      udpoutsizestat_values, 0);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+
+               TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
+               TRY0(xmlTextWriterEndElement(writer)); /* </udp> */
+
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tcp"));
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+                                                ISC_XMLCHAR "request-size"));
+
+               result = dump_counters(server->tcpinstats6,
+                                      isc_statsformat_xml, writer,
+                                      NULL, tcpinsizestats_xmldesc,
+                                      dns_sizecounter_in_max,
+                                      tcpinsizestats_index,
+                                      tcpinsizestat_values, 0);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+
+               TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
+
+               TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
+               TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "type",
+                                                ISC_XMLCHAR "response-size"));
+
+               result = dump_counters(server->tcpoutstats6,
+                                      isc_statsformat_xml, writer,
+                                      NULL, tcpoutsizestats_xmldesc,
+                                      dns_sizecounter_out_max,
+                                      tcpoutsizestats_index,
+                                      tcpoutsizestat_values, 0);
+               if (result != ISC_R_SUCCESS)
+                       goto error;
+
+               TRY0(xmlTextWriterEndElement(writer)); /* </counters> */
+               TRY0(xmlTextWriterEndElement(writer)); /* </tcp> */
+               TRY0(xmlTextWriterEndElement(writer)); /* </ipv6> */
                TRY0(xmlTextWriterEndElement(writer)); /* </traffic> */
        }
 
-
        /*
         * Render views.  For each view we know of, call its
         * rendering function.
@@ -1928,6 +2063,12 @@ render_xml_traffic(const char *url, isc_httpdurl_t *urlinfo,
 #define STATS_JSON_TRAFFIC     0x20
 #define STATS_JSON_ALL         0xff
 
+#define CHECK(m) do { \
+       result = (m); \
+       if (result != ISC_R_SUCCESS) \
+               goto error; \
+} while (0)
+
 #define CHECKMEM(m) do { \
        if (m == NULL) { \
                result = ISC_R_NOMEMORY;\
@@ -2061,6 +2202,11 @@ generatejson(ns_server_t *server, size_t *msglen,
        dns_view_t *view;
        isc_result_t result = ISC_R_SUCCESS;
        json_object *bindstats, *viewlist, *counters, *obj;
+       json_object *traffic = NULL;
+       json_object *udpreq4 = NULL, *udpresp4 = NULL;
+       json_object *tcpreq4 = NULL, *tcpresp4 = NULL;
+       json_object *udpreq6 = NULL, *udpresp6 = NULL;
+       json_object *tcpreq6 = NULL, *tcpresp6 = NULL;
        isc_uint64_t nsstat_values[dns_nsstatscounter_max];
        isc_uint64_t resstat_values[dns_resstatscounter_max];
        isc_uint64_t adbstat_values[dns_adbstats_max];
@@ -2134,6 +2280,24 @@ generatejson(ns_server_t *server, size_t *msglen,
                else
                        json_object_put(counters);
 
+               /* OPCODE counters */
+               counters = json_object_new_object();
+
+               dumparg.type = isc_statsformat_json;
+               dumparg.arg = counters;
+
+               dns_rcodestats_dump(server->rcodestats, rcodestat_dump,
+                                   &dumparg, ISC_STATSDUMP_VERBOSE);
+               if (dumparg.result != ISC_R_SUCCESS) {
+                       json_object_put(counters);
+                       goto error;
+               }
+
+               if (json_object_get_object(counters)->count != 0)
+                       json_object_object_add(bindstats, "rcodes", counters);
+               else
+                       json_object_put(counters);
+
                /* QTYPE counters */
                counters = json_object_new_object();
 
@@ -2419,76 +2583,124 @@ generatejson(ns_server_t *server, size_t *msglen,
        }
 
        if ((flags & STATS_JSON_TRAFFIC) != 0) {
-               json_object *traffic, *udpreq, *udpresp, *tcpreq, *tcpresp;
 
                traffic = json_object_new_object();
                CHECKMEM(traffic);
 
-               udpreq = json_object_new_object();
-               CHECKMEM(udpreq);
-
-               udpresp = json_object_new_object();
-               CHECKMEM(udpresp);
-
-               tcpreq = json_object_new_object();
-               CHECKMEM(tcpreq);
-
-               tcpresp = json_object_new_object();
-               CHECKMEM(tcpresp);
-
-               result = dump_counters(server->udpinstats,
-                                      isc_statsformat_json, udpreq, NULL,
-                                      udpinsizestats_xmldesc,
-                                      dns_sizecounter_in_max,
-                                      udpinsizestats_index,
-                                      udpinsizestat_values, 0);
-               if (result != ISC_R_SUCCESS) {
-                       json_object_put(traffic);
-                       goto error;
-               }
-
-               result = dump_counters(server->udpoutstats,
-                                      isc_statsformat_json, udpresp, NULL,
-                                      udpoutsizestats_xmldesc,
-                                      dns_sizecounter_out_max,
-                                      udpoutsizestats_index,
-                                      udpoutsizestat_values, 0);
-               if (result != ISC_R_SUCCESS) {
-                       json_object_put(traffic);
-                       goto error;
-               }
-
-               result = dump_counters(server->tcpinstats,
-                                      isc_statsformat_json, tcpreq, NULL,
-                                      tcpinsizestats_xmldesc,
-                                      dns_sizecounter_in_max,
-                                      tcpinsizestats_index,
-                                      tcpinsizestat_values, 0);
-               if (result != ISC_R_SUCCESS) {
-                       json_object_put(traffic);
-                       goto error;
-               }
-
-               result = dump_counters(server->tcpoutstats,
-                                      isc_statsformat_json, tcpresp, NULL,
-                                      tcpoutsizestats_xmldesc,
-                                      dns_sizecounter_out_max,
-                                      tcpoutsizestats_index,
-                                      tcpoutsizestat_values, 0);
-               if (result != ISC_R_SUCCESS) {
-                       json_object_put(traffic);
-                       goto error;
-               }
+               udpreq4 = json_object_new_object();
+               CHECKMEM(udpreq4);
+
+               udpresp4 = json_object_new_object();
+               CHECKMEM(udpresp4);
+
+               tcpreq4 = json_object_new_object();
+               CHECKMEM(tcpreq4);
+
+               tcpresp4 = json_object_new_object();
+               CHECKMEM(tcpresp4);
+
+               udpreq6 = json_object_new_object();
+               CHECKMEM(udpreq6);
+
+               udpresp6 = json_object_new_object();
+               CHECKMEM(udpresp6);
+
+               tcpreq6 = json_object_new_object();
+               CHECKMEM(tcpreq6);
+
+               tcpresp6 = json_object_new_object();
+               CHECKMEM(tcpresp6);
+
+               CHECK(dump_counters(server->udpinstats4,
+                                   isc_statsformat_json, udpreq4, NULL,
+                                   udpinsizestats_xmldesc,
+                                   dns_sizecounter_in_max,
+                                   udpinsizestats_index,
+                                   udpinsizestat_values, 0));
+
+               CHECK(dump_counters(server->udpoutstats4,
+                                   isc_statsformat_json, udpresp4, NULL,
+                                   udpoutsizestats_xmldesc,
+                                   dns_sizecounter_out_max,
+                                   udpoutsizestats_index,
+                                   udpoutsizestat_values, 0));
+
+               CHECK(dump_counters(server->tcpinstats4,
+                                   isc_statsformat_json, tcpreq4, NULL,
+                                   tcpinsizestats_xmldesc,
+                                   dns_sizecounter_in_max,
+                                   tcpinsizestats_index,
+                                   tcpinsizestat_values, 0));
+
+               CHECK(dump_counters(server->tcpoutstats4,
+                                   isc_statsformat_json, tcpresp4, NULL,
+                                   tcpoutsizestats_xmldesc,
+                                   dns_sizecounter_out_max,
+                                   tcpoutsizestats_index,
+                                   tcpoutsizestat_values, 0));
+
+               CHECK(dump_counters(server->udpinstats6,
+                                   isc_statsformat_json, udpreq6, NULL,
+                                   udpinsizestats_xmldesc,
+                                   dns_sizecounter_in_max,
+                                   udpinsizestats_index,
+                                   udpinsizestat_values, 0));
+
+               CHECK(dump_counters(server->udpoutstats6,
+                                   isc_statsformat_json, udpresp6, NULL,
+                                   udpoutsizestats_xmldesc,
+                                   dns_sizecounter_out_max,
+                                   udpoutsizestats_index,
+                                   udpoutsizestat_values, 0));
+
+               CHECK(dump_counters(server->tcpinstats6,
+                                   isc_statsformat_json, tcpreq6, NULL,
+                                   tcpinsizestats_xmldesc,
+                                   dns_sizecounter_in_max,
+                                   tcpinsizestats_index,
+                                   tcpinsizestat_values, 0));
+
+               CHECK(dump_counters(server->tcpoutstats6,
+                                   isc_statsformat_json, tcpresp6, NULL,
+                                   tcpoutsizestats_xmldesc,
+                                   dns_sizecounter_out_max,
+                                   tcpoutsizestats_index,
+                                   tcpoutsizestat_values, 0));
 
                json_object_object_add(traffic,
-                                      "udp-requests-received", udpreq);
+                                      "dns-udp-requests-sizes-received-ipv4",
+                                      udpreq4);
                json_object_object_add(traffic,
-                                      "udp-responses-sent", udpresp);
+                                      "dns-udp-responses-sizes-sent-ipv4",
+                                      udpresp4);
                json_object_object_add(traffic,
-                                      "tcp-requests-received", tcpreq);
+                                      "dns-tcp-requests-sizes-received-ipv4",
+                                      tcpreq4);
                json_object_object_add(traffic,
-                                      "tcp-responses-sent", tcpresp);
+                                      "dns-tcp-responses-sizes-sent-ipv4",
+                                      tcpresp4);
+               json_object_object_add(traffic,
+                                      "dns-udp-requests-sizes-received-ipv6",
+                                      udpreq6);
+               json_object_object_add(traffic,
+                                      "dns-udp-responses-sizes-sent-ipv6",
+                                      udpresp6);
+               json_object_object_add(traffic,
+                                      "dns-tcp-requests-sizes-received-ipv6",
+                                      tcpreq6);
+               json_object_object_add(traffic,
+                                      "dns-tcp-responses-sizes-sent-ipv6",
+                                      tcpresp6);
                json_object_object_add(bindstats, "traffic", traffic);
+               udpreq4 = NULL;
+               udpresp4 = NULL;
+               tcpreq4 = NULL;
+               tcpresp4 = NULL;
+               udpreq6 = NULL;
+               udpresp6 = NULL;
+               tcpreq6 = NULL;
+               tcpresp6 = NULL;
+               traffic = NULL;
        }
 
        *msg = json_object_to_json_string_ext(bindstats,
@@ -2503,6 +2715,24 @@ generatejson(ns_server_t *server, size_t *msglen,
        result = ISC_R_SUCCESS;
 
   error:
+       if (udpreq4 != NULL)
+               json_object_put(udpreq4);
+       if (udpresp4 != NULL)
+               json_object_put(udpresp4);
+       if (tcpreq4 != NULL)
+               json_object_put(tcpreq4);
+       if (tcpresp4 != NULL)
+               json_object_put(tcpresp4);
+       if (udpreq6 != NULL)
+               json_object_put(udpreq6);
+       if (udpresp6 != NULL)
+               json_object_put(udpresp6);
+       if (tcpreq6 != NULL)
+               json_object_put(tcpreq6);
+       if (tcpresp6 != NULL)
+               json_object_put(tcpresp6);
+       if (traffic != NULL)
+               json_object_put(traffic);
        if (bindstats != NULL)
                json_object_put(bindstats);
 
@@ -3122,6 +3352,9 @@ ns_stats_dump(ns_server_t *server, FILE *fp) {
        dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump,
                                &dumparg, 0);
 
+       fprintf(fp, "++ Outgoing Rcodes ++\n");
+       dns_rcodestats_dump(server->rcodestats, rcodestat_dump, &dumparg, 0);
+
        fprintf(fp, "++ Outgoing Queries ++\n");
        for (view = ISC_LIST_HEAD(server->viewlist);
             view != NULL;
index 3963447ed4e004862fc5d62509dc34b5b596443f..3d5e9c04bb41935cf3b6bb81162555169fde07b1 100644 (file)
@@ -77,7 +77,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
         pending pipelined @PKCS11_TEST@ reclimit redirect resolver rndc
         rpz rpzrecurse rrl rrchecker rrsetorder rsabigexponent
         runtime sfcache smartsign sortlist spf staticstub statistics
-        stub tcp tkey tsig tsiggss unknown upforwd verify views
+        statschannel stub tcp tkey tsig tsiggss unknown upforwd verify views
         wildcard xfer xferquota zero zonechecks"
 
 # Use the CONFIG_SHELL detected by configure for tests
index 4c81edea1a341d8cbf6119013fe593e8133dbf8b..4ffe767d8e22a0a191ed36918c39511a53572a56 100644 (file)
@@ -27,6 +27,9 @@ my $ref = decode_json($text);
 foreach $key (keys $ref->{opcodes}) {
     print "opcode " . $key . ": " . $ref->{opcodes}->{$key} . "\n";
 }
+foreach $key (keys $ref->{rcodes}) {
+    print "rcode " . $key . ": " . $ref->{rcodes}->{$key} . "\n";
+}
 foreach $key (keys $ref->{qtypes}) {
     print "qtype " . $key . ": " . $ref->{qtypes}->{$key} . "\n";
 }
index f4933f9a2526a3a2aff0c0afd629465ec2d1221a..320a0a0071456623645fdc028bc4f2942b874c61 100644 (file)
@@ -147,6 +147,7 @@ $DIGCMD +tcp example ns > dig.out.$n || ret=1
 $RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 stats 2>&1 | sed 's/^/I:ns1 /'
 query_count=`awk '/QUERY/ {print $1}' ns2/named.stats`
 txt_count=`awk '/TXT/ {print $1}' ns2/named.stats`
+noerror_count=`awk '/NOERROR/ {print $1}' ns2/named.stats`
 if [ $PERL_XML ]; then
     file=`$PERL fetch.pl xml/v3/server`
     mv $file xml.stats
@@ -157,6 +158,9 @@ if [ $PERL_XML ]; then
     xml_txt_count=`awk '/qtype TXT/ { print $NF }' xml.fmtstats`
     xml_txt_count=${xml_txt_count:-0}
     [ "$txt_count" -eq "$xml_txt_count" ] || ret=1
+    xml_noerror_count=`awk '/rcode NOERROR/ { print $NF }' xml.fmtstats`
+    xml_noerror_count=${xml_noerror_count:-0}
+    [ "$noerror_count" -eq "$xml_noerror_count" ] || ret=1
 fi
 if [ $PERL_JSON ]; then
     file=`$PERL fetch.pl json/v1/server`
@@ -168,6 +172,9 @@ if [ $PERL_JSON ]; then
     json_txt_count=`awk '/qtype TXT/ { print $NF }' json.fmtstats`
     json_txt_count=${json_txt_count:-0}
     [ "$txt_count" -eq "$json_txt_count" ] || ret=1
+    json_noerror_count=`awk '/rcode NOERROR/ { print $NF }' json.fmtstats`
+    json_noerror_count=${json_noerror_count:-0}
+    [ "$noerror_count" -eq "$json_noerror_count" ] || ret=1
 fi
 if [ $ret != 0 ]; then echo "I: failed"; fi
 status=`expr $status + $ret`
index ed155713976c23f43496abb2b1a154c202e45350..a56929e51c8705d58f5d73ae764c3c638e2309b5 100644 (file)
@@ -27,25 +27,25 @@ close(INPUT);
 
 my $ref = decode_json($text);
 
-my $tcprcvd = $ref->{traffic}->{"tcp-requests-received"};
+my $tcprcvd = $ref->{traffic}->{"dns-tcp-requests-sizes-received-ipv4"};
 my $type = "tcp request-size ";
 foreach $key (keys $tcprcvd) {
     print $type . $key . ": ". $tcprcvd->{$key} ."\n";
 }
 
-my $tcpsent = $ref->{traffic}->{"tcp-responses-sent"};
+my $tcpsent = $ref->{traffic}->{"dns-tcp-responses-sizes-sent-ipv4"};
 my $type = "tcp response-size ";
 foreach $key (keys $tcpsent) {
     print $type . $key . ": ". $tcpsent->{$key} ."\n";
 }
 
-my $udprcvd = $ref->{traffic}->{"udp-requests-received"};
+my $udprcvd = $ref->{traffic}->{"dns-udp-requests-sizes-received-ipv4"};
 my $type = "udp request-size ";
 foreach $key (keys $udprcvd) {
     print $type . $key . ": ". $udprcvd->{$key} ."\n";
 }
 
-my $udpsent = $ref->{traffic}->{"udp-responses-sent"};
+my $udpsent = $ref->{traffic}->{"dns-udp-responses-sizes-sent-ipv4"};
 my $type = "udp response-size ";
 foreach $key (keys $udpsent) {
     print $type . $key . ": ". $udpsent->{$key} ."\n";
index e86ca79391604cdbdd1277a5a40d5317f25fb15e..81281b2ed6a86bb9a2ab482f77518514649a6cb6 100644 (file)
@@ -24,7 +24,7 @@ my $file = $ARGV[0];
 
 my $ref = XMLin($file);
 
-my $udp = $ref->{traffic}->{udp}->{counters};
+my $udp = $ref->{traffic}->{ipv4}->{udp}->{counters};
 foreach $group (@$udp) {
     my $type = "udp " . $group->{type} . " ";
     if (exists $group->{counter}->{name}) {
@@ -36,7 +36,7 @@ foreach $group (@$udp) {
     }
 }
 
-my $tcp = $ref->{traffic}->{tcp}->{counters};
+my $tcp = $ref->{traffic}->{ipv4}->{tcp}->{counters};
 foreach $group (@$tcp) {
     my $type = "tcp " . $group->{type} . " ";
     if (exists $group->{counter}->{name}) {
index bba92670abc8e4ac9c7b068218ccb8aafc5e0878..eb31af77d8bec1b2857ca6c66d4796d5437e7d32 100644 (file)
@@ -199,6 +199,8 @@ typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, isc_uint64_t,
                                            void *);
 typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, isc_uint64_t, void *);
 
+typedef void (*dns_rcodestats_dumper_t)(dns_rcode_t, isc_uint64_t, void *);
+
 ISC_LANG_BEGINDECLS
 
 isc_result_t
@@ -268,6 +270,22 @@ dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
  *\li  anything else   -- failure
  */
 
+isc_result_t
+dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp);
+/*%<
+ * Create a statistics counter structure per assigned rcode.
+ *
+ * Requires:
+ *\li  'mctx' must be a valid memory context.
+ *
+ *\li  'statsp' != NULL && '*statsp' == NULL.
+ *
+ * Returns:
+ *\li  ISC_R_SUCCESS   -- all ok
+ *
+ *\li  anything else   -- failure
+ */
+
 void
 dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp);
 /*%<
@@ -340,6 +358,15 @@ dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
  *\li  'stats' is a valid dns_stats_t created by dns_opcodestats_create().
  */
 
+void
+dns_rcodestats_increment(dns_stats_t *stats, dns_opcode_t code);
+/*%<
+ * Increment the statistics counter for 'code'.
+ *
+ * Requires:
+ *\li  'stats' is a valid dns_stats_t created by dns_rcodestats_create().
+ */
+
 void
 dns_generalstats_dump(dns_stats_t *stats, dns_generalstats_dumper_t dump_fn,
                      void *arg, unsigned int options);
@@ -398,6 +425,20 @@ dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
  *\li  'stats' is a valid dns_stats_t created by dns_generalstats_create().
  */
 
+void
+dns_rcodestats_dump(dns_stats_t *stats, dns_rcodestats_dumper_t dump_fn,
+                   void *arg, unsigned int options);
+/*%<
+ * Dump the current statistics counters in a specified way.  For each counter
+ * in stats, dump_fn is called with the corresponding rcode, the current
+ * counter value and the given argument arg.  By default counters that have a
+ * value of 0 is skipped; if options has the ISC_STATSDUMP_VERBOSE flag, even
+ * such counters are dumped.
+ *
+ * Requires:
+ *\li  'stats' is a valid dns_stats_t created by dns_generalstats_create().
+ */
+
 isc_result_t
 dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
 /*%<
index c07905de5bc780968cc00e16d0d678597e8062f9..094d335d33490ada2c125cabcadfa61af66477c7 100644 (file)
@@ -261,6 +261,10 @@ enum {
 #define dns_rcode_badvers              ((dns_rcode_t)dns_rcode_badvers)
        dns_rcode_badcookie = 23
 #define dns_rcode_badcookie            ((dns_rcode_t)dns_rcode_badcookie)
+       /*
+        * Update dns_rcodestats_create() and dns_rcodestats_increment()
+        * and this comment if a rcode > dns_rcode_badcookie is assigned.
+        */
        /* Private space [3841..4095] */
 };
 
index ed1692a65482a3ad17b261ba754da59a7b9a91c3..1f2ff849ff25c0ac66f3247b2838939c080a5c19 100644 (file)
@@ -40,7 +40,8 @@ typedef enum {
        dns_statstype_general = 0,
        dns_statstype_rdtype = 1,
        dns_statstype_rdataset = 2,
-       dns_statstype_opcode = 3
+       dns_statstype_opcode = 3,
+       dns_statstype_rcode = 4
 } dns_statstype_t;
 
 /*%
@@ -88,6 +89,11 @@ typedef struct opcodedumparg {
        void                            *arg;
 } opcodedumparg_t;
 
+typedef struct rcodedumparg {
+       dns_rcodestats_dumper_t fn;
+       void                            *arg;
+} rcodedumparg_t;
+
 void
 dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
        REQUIRE(DNS_STATS_VALID(stats));
@@ -191,6 +197,14 @@ dns_opcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
        return (create_stats(mctx, dns_statstype_opcode, 16, statsp));
 }
 
+isc_result_t
+dns_rcodestats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
+       REQUIRE(statsp != NULL && *statsp == NULL);
+
+       return (create_stats(mctx, dns_statstype_rcode,
+                            dns_rcode_badcookie + 1, statsp));
+}
+
 /*%
  * Increment/Decrement methods
  */
@@ -281,6 +295,14 @@ dns_opcodestats_increment(dns_stats_t *stats, dns_opcode_t code) {
        isc_stats_increment(stats->counters, (isc_statscounter_t)code);
 }
 
+void
+dns_rcodestats_increment(dns_stats_t *stats, dns_rcode_t code) {
+       REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rcode);
+
+        if (code <= dns_rcode_badcookie) 
+               isc_stats_increment(stats->counters, (isc_statscounter_t)code);
+}
+
 /*%
  * Dump methods
  */
@@ -389,6 +411,13 @@ opcode_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
        opcodearg->fn((dns_opcode_t)counter, value, opcodearg->arg);
 }
 
+static void
+rcode_dumpcb(isc_statscounter_t counter, isc_uint64_t value, void *arg) {
+       rcodedumparg_t *rcodearg = arg;
+
+       rcodearg->fn((dns_rcode_t)counter, value, rcodearg->arg);
+}
+
 void
 dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
                     void *arg0, unsigned int options)
@@ -402,6 +431,19 @@ dns_opcodestats_dump(dns_stats_t *stats, dns_opcodestats_dumper_t dump_fn,
        isc_stats_dump(stats->counters, opcode_dumpcb, &arg, options);
 }
 
+void
+dns_rcodestats_dump(dns_stats_t *stats, dns_rcodestats_dumper_t dump_fn,
+                    void *arg0, unsigned int options)
+{
+       rcodedumparg_t arg;
+
+       REQUIRE(DNS_STATS_VALID(stats) && stats->type == dns_statstype_rcode);
+
+       arg.fn = dump_fn;
+       arg.arg = arg0;
+       isc_stats_dump(stats->counters, rcode_dumpcb, &arg, options);
+}
+
 /***
  *** Obsolete variables and functions follow:
  ***/
index f5545fff4a4e9887d1fa1b0bb2194fee522750cd..2c67bfd7eeaef6a0679f5490bfe1104f2b4e1cf2 100644 (file)
@@ -753,6 +753,9 @@ dns_rbtnodechain_prev
 dns_rbtnodechain_reset
 dns_rcode_fromtext
 dns_rcode_totext
+dns_rcodestats_create
+dns_rcodestats_dump
+dns_rcodestats_increment
 dns_rdata_additionaldata
 dns_rdata_apl_current
 dns_rdata_apl_first