netcmd plugin: Free peers when shutting down.
[collectd.git] / src / netcmd.c
index c2a0ddb..90aef1a 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/netcmd.c
- * Copyright (C) 2007-2011  Florian octo Forster
+ * Copyright (C) 2007-2012  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -132,6 +132,34 @@ static nc_peer_t *nc_fd_to_peer (int fd) /* {{{ */
   return (NULL);
 } /* }}} nc_peer_t *nc_fd_to_peer */
 
+static void nc_free_peer (nc_peer_t *p) /* {{{ */
+{
+  size_t i;
+  if (p == NULL)
+    return;
+
+  sfree (p->node);
+  sfree (p->service);
+
+  for (i = 0; i < p->fds_num; i++)
+  {
+    if (p->fds[i] >= 0)
+      close (p->fds[i]);
+    p->fds[i] = -1;
+  }
+  p->fds_num = 0;
+  sfree (p->fds);
+
+  sfree (p->tls_cert_file);
+  sfree (p->tls_key_file);
+  sfree (p->tls_ca_file);
+  sfree (p->tls_crl_file);
+
+  gnutls_certificate_free_credentials (p->tls_credentials);
+  gnutls_dh_params_deinit (p->tls_dh_params);
+  gnutls_priority_deinit (p->tls_priority);
+} /* }}} void nc_free_peer */
+
 static int nc_register_fd (nc_peer_t *peer, int fd) /* {{{ */
 {
   struct pollfd *poll_ptr;
@@ -421,14 +449,18 @@ static int nc_connection_init (nc_connection_t *conn) /* {{{ */
   if (conn->have_tls_session)
   {
     int status;
+    intptr_t fd;
 
     conn->read_buffer = malloc (NC_READ_BUFFER_SIZE);
     if (conn->read_buffer == NULL)
       return (ENOMEM);
     memset (conn->read_buffer, 0, NC_READ_BUFFER_SIZE);
 
+    /* Make (relatively) sure that 'fd' and 'void*' have the same size to make
+     * GCC happy. */
+    fd = (intptr_t) conn->fd;
     gnutls_transport_set_ptr (conn->tls_session,
-       (gnutls_transport_ptr_t) conn->fd);
+        (gnutls_transport_ptr_t) fd);
 
     while (42)
     {
@@ -847,6 +879,7 @@ static int nc_config_peer (const oconfig_item_t *ci) /* {{{ */
 {
   nc_peer_t *p;
   int i;
+  _Bool success;
 
   p = realloc (peers, sizeof (*peers) * (peers_num + 1));
   if (p == NULL)
@@ -863,7 +896,7 @@ static int nc_config_peer (const oconfig_item_t *ci) /* {{{ */
   p->tls_key_file = NULL;
   p->tls_ca_file = NULL;
   p->tls_crl_file = NULL;
-  p->tls_verify_peer = 1;
+  p->tls_verify_peer = 0;
 
   for (i = 0; i < ci->children_num; i++)
   {
@@ -888,6 +921,26 @@ static int nc_config_peer (const oconfig_item_t *ci) /* {{{ */
           "a \"%s\" block.", child->key, ci->key);
   }
 
+  success = 1;
+
+  if (p->tls_verify_peer
+      && ((p->tls_cert_file == NULL)
+        || (p->tls_key_file == NULL)
+        || (p->tls_ca_file == NULL)))
+  {
+    ERROR ("netcmd plugin: You have requested to verify peers (using the "
+        "\"TLSVerifyPeer\" option), but the TLS setup is incomplete. "
+        "The \"TLSCertFile\", \"TLSKeyFile\" and \"TLSCAFile\" are "
+        "required for this to work. This \"Listen\" block will be disabled.");
+    success = 0;
+  }
+
+  if (!success)
+  {
+    nc_free_peer (p);
+    return (-1);
+  }
+
   DEBUG ("netcmd plugin: node = \"%s\"; service = \"%s\";", p->node, p->service);
 
   peers_num++;
@@ -895,7 +948,7 @@ static int nc_config_peer (const oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int nc_config_peer */
 
-static int nc_config (oconfig_item_t *ci)
+static int nc_config (oconfig_item_t *ci) /* {{{ */
 {
   int i;
 
@@ -911,9 +964,9 @@ static int nc_config (oconfig_item_t *ci)
   }
 
   return (0);
-} /* int nc_config */
+} /* }}} int nc_config */
 
-static int nc_init (void)
+static int nc_init (void) /* {{{ */
 {
   static int have_init = 0;
 
@@ -941,16 +994,18 @@ static int nc_init (void)
 
   listen_thread_running = 1;
   return (0);
-} /* int nc_init */
+} /* }}} int nc_init */
 
-static int nc_shutdown (void)
+static int nc_shutdown (void) /* {{{ */
 {
-  void *ret;
+  size_t i;
 
   listen_thread_loop = 0;
 
   if (listen_thread != (pthread_t) 0)
   {
+    void *ret;
+
     pthread_kill (listen_thread, SIGTERM);
     pthread_join (listen_thread, &ret);
     listen_thread = (pthread_t) 0;
@@ -959,8 +1014,13 @@ static int nc_shutdown (void)
   plugin_unregister_init ("netcmd");
   plugin_unregister_shutdown ("netcmd");
 
+  for (i = 0; i < peers_num; i++)
+    nc_free_peer (peers + i);
+  peers_num = 0;
+  sfree (peers);
+
   return (0);
-} /* int nc_shutdown */
+} /* }}} int nc_shutdown */
 
 void module_register (void)
 {