Merge branch 'collectd-5.7' into collectd-5.8
[collectd.git] / src / powerdns.c
index 5f7a542..74e671b 100644 (file)
     ERROR("powerdns plugin: %s failed: %s", func,                              \
           sstrerror(errno, errbuf, sizeof(errbuf)));                           \
   } 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)));                           \
+  } while (0)
 
 #define SERVER_SOCKET LOCALSTATEDIR "/run/pdns.controlsocket"
 #define SERVER_COMMAND "SHOW * \n"
@@ -276,7 +282,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"},
@@ -314,9 +320,9 @@ static char *local_sockpath = NULL;
 
 /* <https://doc.powerdns.com/md/recursor/stats/> */
 static void submit(const char *plugin_instance, /* {{{ */
-                   const char *pdns_type, const char *value) {
+                   const char *pdns_type, const char *value_str) {
   value_list_t vl = VALUE_LIST_INIT;
-  value_t values[1];
+  value_t value;
 
   const char *type = NULL;
   const char *type_instance = NULL;
@@ -330,7 +336,7 @@ static void submit(const char *plugin_instance, /* {{{ */
 
   if (i >= lookup_table_length) {
     INFO("powerdns plugin: submit: Not found in lookup table: %s = %s;",
-         pdns_type, value);
+         pdns_type, value_str);
     return;
   }
 
@@ -355,16 +361,15 @@ static void submit(const char *plugin_instance, /* {{{ */
     return;
   }
 
-  if (0 != parse_value(value, &values[0], ds->ds[0].type)) {
+  if (0 != parse_value(value_str, &value, ds->ds[0].type)) {
     ERROR("powerdns plugin: Cannot convert `%s' "
           "to a number.",
-          value);
+          value_str);
     return;
   }
 
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
-  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
   sstrncpy(vl.plugin, "powerdns", sizeof(vl.plugin));
   sstrncpy(vl.type, type, sizeof(vl.type));
   if (type_instance != NULL)
@@ -374,8 +379,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;
 
@@ -385,13 +390,12 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
 
   struct sockaddr_un sa_unix = {0};
 
-  struct timeval stv_timeout;
   cdtime_t cdt_timeout;
 
   sd = socket(PF_UNIX, item->socktype, 0);
   if (sd < 0) {
     FUNC_ERROR("socket");
-    return (-1);
+    return -1;
   }
 
   sa_unix.sun_family = AF_UNIX;
@@ -401,9 +405,9 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
 
   status = unlink(sa_unix.sun_path);
   if ((status != 0) && (errno != ENOENT)) {
-    FUNC_ERROR("unlink");
+    SOCK_ERROR("unlink", sa_unix.sun_path);
     close(sd);
-    return (-1);
+    return -1;
   }
 
   do /* while (0) */
@@ -412,14 +416,14 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
      * and otherwise the daemon cannot answer. */
     status = bind(sd, (struct sockaddr *)&sa_unix, sizeof(sa_unix));
     if (status != 0) {
-      FUNC_ERROR("bind");
+      SOCK_ERROR("bind", sa_unix.sun_path);
       break;
     }
 
     /* Make the socket writeable by the daemon.. */
     status = chmod(sa_unix.sun_path, 0666);
     if (status != 0) {
-      FUNC_ERROR("chmod");
+      SOCK_ERROR("chmod", sa_unix.sun_path);
       break;
     }
 
@@ -427,31 +431,30 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
     if (cdt_timeout < TIME_T_TO_CDTIME_T(2))
       cdt_timeout = TIME_T_TO_CDTIME_T(2);
 
-    CDTIME_T_TO_TIMEVAL(cdt_timeout, &stv_timeout);
-
-    status = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &stv_timeout,
-                        sizeof(stv_timeout));
+    status =
+        setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
+                   &CDTIME_T_TO_TIMEVAL(cdt_timeout), sizeof(struct timeval));
     if (status != 0) {
-      FUNC_ERROR("setsockopt");
+      SOCK_ERROR("setsockopt", sa_unix.sun_path);
       break;
     }
 
     status =
         connect(sd, (struct sockaddr *)&item->sockaddr, sizeof(item->sockaddr));
     if (status != 0) {
-      FUNC_ERROR("connect");
+      SOCK_ERROR("connect", sa_unix.sun_path);
       break;
     }
 
     status = send(sd, item->command, strlen(item->command), 0);
     if (status < 0) {
-      FUNC_ERROR("send");
+      SOCK_ERROR("send", sa_unix.sun_path);
       break;
     }
 
     status = recv(sd, temp, sizeof(temp), /* flags = */ 0);
     if (status < 0) {
-      FUNC_ERROR("recv");
+      SOCK_ERROR("recv", sa_unix.sun_path);
       break;
     }
     buffer_size = status + 1;
@@ -462,27 +465,24 @@ static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
   unlink(sa_unix.sun_path);
 
   if (status != 0)
-    return (-1);
+    return -1;
 
   assert(buffer_size > 0);
   buffer = malloc(buffer_size);
   if (buffer == NULL) {
     FUNC_ERROR("malloc");
-    return (-1);
+    return -1;
   }
 
   memcpy(buffer, temp, buffer_size - 1);
   buffer[buffer_size - 1] = 0;
 
   *ret_buffer = buffer;
-  *ret_buffer_size = buffer_size;
-
-  return (0);
+  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;
 
@@ -493,7 +493,7 @@ static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
   sd = socket(PF_UNIX, item->socktype, 0);
   if (sd < 0) {
     FUNC_ERROR("socket");
-    return (-1);
+    return -1;
   }
 
   struct timeval timeout;
@@ -503,24 +503,24 @@ static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
   if (status != 0) {
     FUNC_ERROR("setsockopt");
     close(sd);
-    return (-1);
+    return -1;
   }
 
   status =
       connect(sd, (struct sockaddr *)&item->sockaddr, sizeof(item->sockaddr));
   if (status != 0) {
-    FUNC_ERROR("connect");
+    SOCK_ERROR("connect", item->sockaddr.sun_path);
     close(sd);
-    return (-1);
+    return -1;
   }
 
   /* strlen + 1, because we need to send the terminating NULL byte, too. */
   status = send(sd, item->command, strlen(item->command) + 1,
                 /* flags = */ 0);
   if (status < 0) {
-    FUNC_ERROR("send");
+    SOCK_ERROR("send", item->sockaddr.sun_path);
     close(sd);
-    return (-1);
+    return -1;
   }
 
   while (42) {
@@ -528,15 +528,16 @@ static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
 
     status = recv(sd, temp, sizeof(temp), /* flags = */ 0);
     if (status < 0) {
-      FUNC_ERROR("recv");
+      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;
@@ -547,61 +548,50 @@ 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);
+    return -1;
   }
 } /* int powerdns_get_data */
 
 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) {
     ERROR("powerdns plugin: strdup failed.");
-    return (-1);
+    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);
@@ -609,12 +599,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;
 
@@ -637,7 +628,7 @@ static int powerdns_read_server(list_item_t *item) /* {{{ */
 
   sfree(buffer);
 
-  return (0);
+  return 0;
 } /* }}} int powerdns_read_server */
 
 /*
@@ -653,7 +644,7 @@ static int powerdns_update_recursor_command(list_item_t *li) /* {{{ */
   int status;
 
   if (li == NULL)
-    return (0);
+    return 0;
 
   if (li->fields_num < 1) {
     sstrncpy(buffer, RECURSOR_COMMAND, sizeof(buffer));
@@ -664,7 +655,7 @@ static int powerdns_update_recursor_command(list_item_t *li) /* {{{ */
                      /* seperator = */ " ");
     if (status < 0) {
       ERROR("powerdns plugin: strjoin failed.");
-      return (-1);
+      return -1;
     }
     buffer[sizeof(buffer) - 1] = 0;
     size_t len = strlen(buffer);
@@ -679,16 +670,15 @@ static int powerdns_update_recursor_command(list_item_t *li) /* {{{ */
   li->command = strdup(buffer);
   if (li->command == NULL) {
     ERROR("powerdns plugin: strdup failed.");
-    return (-1);
+    return -1;
   }
 
-  return (0);
+  return 0;
 } /* }}} int powerdns_update_recursor_command */
 
 static int powerdns_read_recursor(list_item_t *item) /* {{{ */
 {
   char *buffer = NULL;
-  size_t buffer_size = 0;
   int status;
 
   char *dummy;
@@ -703,7 +693,7 @@ static int powerdns_read_recursor(list_item_t *item) /* {{{ */
     status = powerdns_update_recursor_command(item);
     if (status != 0) {
       ERROR("powerdns plugin: powerdns_update_recursor_command failed.");
-      return (-1);
+      return -1;
     }
 
     DEBUG("powerdns plugin: powerdns_read_recursor: item->command = %s;",
@@ -711,17 +701,17 @@ 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);
+    return -1;
   }
 
   keys_list = strdup(item->command);
   if (keys_list == NULL) {
     FUNC_ERROR("strdup");
     sfree(buffer);
-    return (-1);
+    return -1;
   }
 
   key_saveptr = NULL;
@@ -744,7 +734,7 @@ static int powerdns_read_recursor(list_item_t *item) /* {{{ */
   sfree(buffer);
   sfree(keys_list);
 
-  return (0);
+  return 0;
 } /* }}} int powerdns_read_recursor */
 
 static int powerdns_config_add_collect(list_item_t *li, /* {{{ */
@@ -754,21 +744,21 @@ static int powerdns_config_add_collect(list_item_t *li, /* {{{ */
   if (ci->values_num < 1) {
     WARNING("powerdns plugin: The `Collect' option needs "
             "at least one argument.");
-    return (-1);
+    return -1;
   }
 
   for (int i = 0; i < ci->values_num; i++)
     if (ci->values[i].type != OCONFIG_TYPE_STRING) {
       WARNING("powerdns plugin: Only string arguments are allowed to "
               "the `Collect' option.");
-      return (-1);
+      return -1;
     }
 
   temp =
       realloc(li->fields, sizeof(char *) * (li->fields_num + ci->values_num));
   if (temp == NULL) {
     WARNING("powerdns plugin: realloc failed.");
-    return (-1);
+    return -1;
   }
   li->fields = temp;
 
@@ -784,7 +774,7 @@ static int powerdns_config_add_collect(list_item_t *li, /* {{{ */
   /* Invalidate a previously computed command */
   sfree(li->command);
 
-  return (0);
+  return 0;
 } /* }}} int powerdns_config_add_collect */
 
 static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
@@ -797,20 +787,20 @@ static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
     WARNING("powerdns plugin: `%s' needs exactly one string argument.",
             ci->key);
-    return (-1);
+    return -1;
   }
 
   item = calloc(1, sizeof(*item));
   if (item == NULL) {
     ERROR("powerdns plugin: calloc failed.");
-    return (-1);
+    return -1;
   }
 
   item->instance = strdup(ci->values[0].value.string);
   if (item->instance == NULL) {
     ERROR("powerdns plugin: strdup failed.");
     sfree(item);
-    return (-1);
+    return -1;
   }
 
   /*
@@ -829,7 +819,7 @@ static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
   } else {
     /* We must never get here.. */
     assert(0);
-    return (-1);
+    return -1;
   }
 
   status = 0;
@@ -876,13 +866,13 @@ static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
   if (status != 0) {
     sfree(socket_temp);
     sfree(item);
-    return (-1);
+    return -1;
   }
 
   DEBUG("powerdns plugin: Add server: instance = %s;", item->instance);
 
   sfree(socket_temp);
-  return (0);
+  return 0;
 } /* }}} int powerdns_config_add_server */
 
 static int powerdns_config(oconfig_item_t *ci) /* {{{ */
@@ -894,7 +884,7 @@ static int powerdns_config(oconfig_item_t *ci) /* {{{ */
 
     if (list == NULL) {
       ERROR("powerdns plugin: `llist_create' failed.");
-      return (-1);
+      return -1;
     }
   }
 
@@ -912,7 +902,7 @@ static int powerdns_config(oconfig_item_t *ci) /* {{{ */
       } else {
         char *temp = strdup(option->values[0].value.string);
         if (temp == NULL)
-          return (1);
+          return 1;
         sfree(local_sockpath);
         local_sockpath = temp;
       }
@@ -921,7 +911,7 @@ static int powerdns_config(oconfig_item_t *ci) /* {{{ */
     }
   } /* for (i = 0; i < ci->children_num; i++) */
 
-  return (0);
+  return 0;
 } /* }}} int powerdns_config */
 
 static int powerdns_read(void) {
@@ -930,12 +920,12 @@ static int powerdns_read(void) {
     item->func(item);
   }
 
-  return (0);
+  return 0;
 } /* static int powerdns_read */
 
 static int powerdns_shutdown(void) {
   if (list == NULL)
-    return (0);
+    return 0;
 
   for (llentry_t *e = llist_head(list); e != NULL; e = e->next) {
     list_item_t *item = (list_item_t *)e->value;
@@ -949,7 +939,7 @@ static int powerdns_shutdown(void) {
   llist_destroy(list);
   list = NULL;
 
-  return (0);
+  return 0;
 } /* static int powerdns_shutdown */
 
 void module_register(void) {
@@ -957,5 +947,3 @@ void module_register(void) {
   plugin_register_read("powerdns", powerdns_read);
   plugin_register_shutdown("powerdns", powerdns_shutdown);
 } /* void module_register */
-
-/* vim: set sw=2 sts=2 ts=8 fdm=marker : */