Merge pull request #3329 from efuss/fix-3311
[collectd.git] / src / powerdns.c
index 0b08b29..9079719 100644 (file)
@@ -26,8 +26,8 @@
 
 #include "collectd.h"
 
-#include "common.h"
 #include "plugin.h"
+#include "utils/common/common.h"
 #include "utils_llist.h"
 
 #include <errno.h>
 #endif
 #define FUNC_ERROR(func)                                                       \
   do {                                                                         \
-    char errbuf[1024];                                                         \
-    ERROR("powerdns plugin: %s failed: %s", func,                              \
-          sstrerror(errno, errbuf, sizeof(errbuf)));                           \
+    ERROR("powerdns plugin: %s failed: %s", func, STRERRNO);                   \
   } while (0)
 #define SOCK_ERROR(func, sockpath)                                             \
   do {                                                                         \
-    char errbuf[1024];                                                         \
     ERROR("powerdns plugin: Socket `%s` %s failed: %s", sockpath, func,        \
-          sstrerror(errno, errbuf, sizeof(errbuf)));                           \
+          STRERRNO);                                                           \
   } while (0)
 
 #define SERVER_SOCKET LOCALSTATEDIR "/run/pdns.controlsocket"
@@ -92,48 +89,48 @@ all-outqueries        counts the number of outgoing UDP queries since starting
 answers-slow          counts the number of queries answered after 1 second
 answers0-1            counts the number of queries answered within 1 millisecond
 answers1-10           counts the number of queries answered within 10
-milliseconds
+                      milliseconds
 answers10-100         counts the number of queries answered within 100
-milliseconds
+                      milliseconds
 answers100-1000       counts the number of queries answered within 1 second
 cache-bytes           size of the cache in bytes (since 3.3.1)
 cache-entries         shows the number of entries in the cache
 cache-hits            counts the number of cache hits since starting, this does
-not include hits that got answered from the packet-cache
+                      not include hits that got answered from the packet-cache
 cache-misses          counts the number of cache misses since starting
 case-mismatches       counts the number of mismatches in character case since
-starting
+                      starting
 chain-resends         number of queries chained to existing outstanding query
 client-parse-errors   counts number of client packets that could not be parsed
 concurrent-queries    shows the number of MThreads currently running
 dlg-only-drops        number of records dropped because of delegation only
-setting
+                      setting
 dont-outqueries       number of outgoing queries dropped because of 'dont-query'
-setting (since 3.3)
+                      setting (since 3.3)
 edns-ping-matches     number of servers that sent a valid EDNS PING respons
 edns-ping-mismatches  number of servers that sent an invalid EDNS PING response
 failed-host-entries   number of servers that failed to resolve
 ipv6-outqueries       number of outgoing queries over IPv6
 ipv6-questions        counts all End-user initiated queries with the RD bit set,
-received over IPv6 UDP
+                      received over IPv6 UDP
 malloc-bytes          returns the number of bytes allocated by the process
-(broken, always returns 0)
+                      (broken, always returns 0)
 max-mthread-stack     maximum amount of thread stack ever used
 negcache-entries      shows the number of entries in the Negative answer cache
 no-packet-error       number of errorneous received packets
 noedns-outqueries     number of queries sent out without EDNS
 noerror-answers       counts the number of times it answered NOERROR since
-starting
+                      starting
 noping-outqueries     number of queries sent out without ENDS PING
 nsset-invalidations   number of times an nsset was dropped because it no longer
-worked
+                      worked
 nsspeeds-entries      shows the number of entries in the NS speeds map
 nxdomain-answers      counts the number of times it answered NXDOMAIN since
-starting
+                      starting
 outgoing-timeouts     counts the number of timeouts on outgoing UDP queries
-since starting
+                      since starting
 over-capacity-drops   questions dropped because over maximum concurrent query
-limit (since 3.2)
+                      limit (since 3.2)
 packetcache-bytes     size of the packet cache in bytes (since 3.3.1)
 packetcache-entries   size of packet cache (since 3.2)
 packetcache-hits      packet cache hits (since 3.2)
@@ -142,32 +139,32 @@ policy-drops          packets dropped because of (Lua) policy decision
 qa-latency            shows the current latency average
 questions             counts all end-user initiated queries with the RD bit set
 resource-limits       counts number of queries that could not be performed
-because of resource limits
+                      because of resource limits
 security-status       security status based on security polling
 server-parse-errors   counts number of server replied packets that could not be
-parsed
+                      parsed
 servfail-answers      counts the number of times it answered SERVFAIL since
-starting
+                      starting
 spoof-prevents        number of times PowerDNS considered itself spoofed, and
-dropped the data
+                      dropped the data
 sys-msec              number of CPU milliseconds spent in 'system' mode
 tcp-client-overflow   number of times an IP address was denied TCP access
-because it already had too many connections
+                      because it already had too many connections
 tcp-clients           counts the number of currently active TCP/IP clients
 tcp-outqueries        counts the number of outgoing TCP queries since starting
 tcp-questions         counts all incoming TCP queries (since starting)
 throttle-entries      shows the number of entries in the throttle map
 throttled-out         counts the number of throttled outgoing UDP queries since
-starting
+                      starting
 throttled-outqueries  idem to throttled-out
 unauthorized-tcp      number of TCP questions denied because of allow-from
-restrictions
+                      restrictions
 unauthorized-udp      number of UDP questions denied because of allow-from
-restrictions
+                      restrictions
 unexpected-packets    number of answers from remote servers that were unexpected
-(might point to spoofing)
+                      (might point to spoofing)
 unreachables          number of times nameservers were unreachable since
-starting
+                      starting
 uptime                number of seconds process has been running (since 3.1.5)
 user-msec             number of CPU milliseconds spent in 'user' mode
 }}} */
@@ -282,7 +279,7 @@ static statname_lookup_t lookup_table[] = /* {{{ */
         {"ipv6-questions", "dns_question", "incoming-ipv6"},
         {"malloc-bytes", "gauge", "malloc_bytes"},
         {"max-mthread-stack", "gauge", "max_mthread_stack"},
-        {"no-packet-error", "gauge", "no_packet_error"},
+        {"no-packet-error", "errors", "no_packet_error"},
         {"noedns-outqueries", "dns_question", "outgoing-noedns"},
         {"noping-outqueries", "dns_question", "outgoing-noping"},
         {"over-capacity-drops", "dns_question", "incoming-over_capacity"},
@@ -304,13 +301,14 @@ static statname_lookup_t lookup_table[] = /* {{{ */
         {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"},
         {"unauthorized-udp", "counter", "denied-unauthorized_udp"},
         {"unexpected-packets", "dns_answer", "unexpected"},
+        {"unreachables", "counter", "unreachables"},
         {"uptime", "uptime", NULL}}; /* }}} */
 static int lookup_table_length = STATIC_ARRAY_SIZE(lookup_table);
 
-static llist_t *list = NULL;
+static llist_t *list;
 
 #define PDNS_LOCAL_SOCKPATH LOCALSTATEDIR "/run/" PACKAGE_NAME "-powerdns"
-static char *local_sockpath = NULL;
+static char *local_sockpath;
 
 /* TODO: Do this before 4.4:
  * - Update the collectd.conf(5) manpage.
@@ -355,16 +353,13 @@ static void submit(const char *plugin_instance, /* {{{ */
   }
 
   if (ds->ds_num != 1) {
-    ERROR("powerdns plugin: type `%s' has %zu data sources, "
+    ERROR("powerdns plugin: type `%s' has %" PRIsz " data sources, "
           "but I can only handle one.",
           type, ds->ds_num);
     return;
   }
 
   if (0 != parse_value(value_str, &value, ds->ds[0].type)) {
-    ERROR("powerdns plugin: Cannot convert `%s' "
-          "to a number.",
-          value_str);
     return;
   }
 
@@ -379,8 +374,8 @@ static void submit(const char *plugin_instance, /* {{{ */
   plugin_dispatch_values(&vl);
 } /* }}} static void submit */
 
-static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
-                                   char **ret_buffer, size_t *ret_buffer_size) {
+static int powerdns_get_data_dgram(list_item_t *item, char **ret_buffer) {
+  /* {{{ */
   int sd;
   int status;
 
@@ -475,17 +470,14 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
   }
 
   memcpy(buffer, temp, buffer_size - 1);
-  buffer[buffer_size - 1] = 0;
+  buffer[buffer_size - 1] = '\0';
 
   *ret_buffer = buffer;
-  *ret_buffer_size = buffer_size;
-
   return 0;
 } /* }}} int powerdns_get_data_dgram */
 
-static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
-                                    char **ret_buffer,
-                                    size_t *ret_buffer_size) {
+static int powerdns_get_data_stream(list_item_t *item, char **ret_buffer) {
+  /* {{{ */
   int sd;
   int status;
 
@@ -533,13 +525,14 @@ static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
     if (status < 0) {
       SOCK_ERROR("recv", item->sockaddr.sun_path);
       break;
-    } else if (status == 0)
+    } else if (status == 0) {
       break;
+    }
 
     buffer_new = realloc(buffer, buffer_size + status + 1);
     if (buffer_new == NULL) {
       FUNC_ERROR("realloc");
-      status = -1;
+      status = ENOMEM;
       break;
     }
     buffer = buffer_new;
@@ -550,23 +543,20 @@ static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
   } /* while (42) */
   close(sd);
 
-  if (status < 0) {
+  if (status != 0) {
     sfree(buffer);
-  } else {
-    assert(status == 0);
-    *ret_buffer = buffer;
-    *ret_buffer_size = buffer_size;
+    return status;
   }
 
-  return status;
+  *ret_buffer = buffer;
+  return 0;
 } /* }}} int powerdns_get_data_stream */
 
-static int powerdns_get_data(list_item_t *item, char **ret_buffer,
-                             size_t *ret_buffer_size) {
+static int powerdns_get_data(list_item_t *item, char **ret_buffer) {
   if (item->socktype == SOCK_DGRAM)
-    return powerdns_get_data_dgram(item, ret_buffer, ret_buffer_size);
+    return powerdns_get_data_dgram(item, ret_buffer);
   else if (item->socktype == SOCK_STREAM)
-    return powerdns_get_data_stream(item, ret_buffer, ret_buffer_size);
+    return powerdns_get_data_stream(item, ret_buffer);
   else {
     ERROR("powerdns plugin: Unknown socket type: %i", (int)item->socktype);
     return -1;
@@ -575,19 +565,6 @@ static int powerdns_get_data(list_item_t *item, char **ret_buffer,
 
 static int powerdns_read_server(list_item_t *item) /* {{{ */
 {
-  char *buffer = NULL;
-  size_t buffer_size = 0;
-  int status;
-
-  char *dummy;
-  char *saveptr;
-
-  char *key;
-  char *value;
-
-  const char *const *fields;
-  int fields_num;
-
   if (item->command == NULL)
     item->command = strdup(SERVER_COMMAND);
   if (item->command == NULL) {
@@ -595,16 +572,21 @@ static int powerdns_read_server(list_item_t *item) /* {{{ */
     return -1;
   }
 
-  status = powerdns_get_data(item, &buffer, &buffer_size);
-  if (status != 0)
-    return -1;
+  char *buffer = NULL;
+  int status = powerdns_get_data(item, &buffer);
+  if (status != 0) {
+    ERROR("powerdns plugin: powerdns_get_data failed.");
+    return status;
+  }
+  if (buffer == NULL) {
+    return EINVAL;
+  }
 
+  const char *const *fields = default_server_fields;
+  int fields_num = default_server_fields_num;
   if (item->fields_num != 0) {
     fields = (const char *const *)item->fields;
     fields_num = item->fields_num;
-  } else {
-    fields = default_server_fields;
-    fields_num = default_server_fields_num;
   }
 
   assert(fields != NULL);
@@ -612,12 +594,13 @@ static int powerdns_read_server(list_item_t *item) /* {{{ */
 
   /* corrupt-packets=0,deferred-cache-inserts=0,deferred-cache-lookup=0,latency=0,packetcache-hit=0,packetcache-miss=0,packetcache-size=0,qsize-q=0,query-cache-hit=0,query-cache-miss=0,recursing-answers=0,recursing-questions=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,udp4-answers=0,udp4-queries=0,udp6-answers=0,udp6-queries=0,
    */
-  dummy = buffer;
-  saveptr = NULL;
+  char *dummy = buffer;
+  char *saveptr = NULL;
+  char *key;
   while ((key = strtok_r(dummy, ",", &saveptr)) != NULL) {
     dummy = NULL;
 
-    value = strchr(key, '=');
+    char *value = strchr(key, '=');
     if (value == NULL)
       break;
 
@@ -691,7 +674,6 @@ static int powerdns_update_recursor_command(list_item_t *li) /* {{{ */
 static int powerdns_read_recursor(list_item_t *item) /* {{{ */
 {
   char *buffer = NULL;
-  size_t buffer_size = 0;
   int status;
 
   char *dummy;
@@ -714,7 +696,7 @@ static int powerdns_read_recursor(list_item_t *item) /* {{{ */
   }
   assert(item->command != NULL);
 
-  status = powerdns_get_data(item, &buffer, &buffer_size);
+  status = powerdns_get_data(item, &buffer);
   if (status != 0) {
     ERROR("powerdns plugin: powerdns_get_data failed.");
     return -1;