madwifi plugin: Plugin for detailed information from the MadWifi driver.
[collectd.git] / src / network.c
index 91cfa4c..0e416bd 100644 (file)
  *   Florian octo Forster <octo at verplant.org>
  **/
 
+#define _BSD_SOURCE /* For struct ip_mreq */
+
 #include "collectd.h"
 #include "plugin.h"
 #include "common.h"
 #include "configfile.h"
 #include "utils_fbhash.h"
 #include "utils_avltree.h"
+#include "utils_cache.h"
 
 #include "network.h"
 
@@ -47,7 +50,7 @@
 # include <poll.h>
 #endif
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 # include <gcrypt.h>
 #endif
 
 /*
  * Maximum size required for encryption / signing:
  *
- *    44 bytes for the encryption header
+ *    42 bytes for the encryption header
  * +  64 bytes for the username
  * -----------
- * = 108 bytes
+ * = 106 bytes
  */
-#define BUFF_SIG_SIZE 108
+#define BUFF_SIG_SIZE 106
 
 /*
  * Private data types
  */
 #define SECURITY_LEVEL_NONE     0
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 # define SECURITY_LEVEL_SIGN    1
 # define SECURITY_LEVEL_ENCRYPT 2
 #endif
@@ -88,7 +91,7 @@ struct sockent_client
        int fd;
        struct sockaddr_storage *addr;
        socklen_t                addrlen;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int security_level;
        char *username;
        char *password;
@@ -101,7 +104,7 @@ struct sockent_server
 {
        int *fd;
        size_t fd_num;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int security_level;
        char *auth_file;
        fbhash_t *userdb;
@@ -226,7 +229,7 @@ typedef struct part_signature_sha256_s part_signature_sha256_t;
  * +---------------------------------------------------------------+
  */
 /* Minimum size */
-#define PART_ENCRYPTION_AES256_SIZE 44
+#define PART_ENCRYPTION_AES256_SIZE 42
 struct part_encryption_aes256_s
 {
   part_header_t head;
@@ -281,129 +284,100 @@ static int              send_buffer_fill;
 static value_list_t     send_buffer_vl = VALUE_LIST_STATIC;
 static pthread_mutex_t  send_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
 
-/* In this cache we store all the values we received, so we can send out only
- * those values which were *not* received via the network plugin, too. This is
- * used for the `Forward false' option. */
-static c_avl_tree_t    *cache_tree = NULL;
-static pthread_mutex_t  cache_lock = PTHREAD_MUTEX_INITIALIZER;
-static time_t           cache_flush_last = 0;
-static int              cache_flush_interval = 1800;
-
 /*
  * Private functions
  */
-static int cache_flush (void)
+static _Bool check_receive_okay (const value_list_t *vl) /* {{{ */
 {
-       char **keys = NULL;
-       int    keys_num = 0;
+  uint64_t time_sent = 0;
+  int status;
 
-       char **tmp;
-       int    i;
+  status = uc_meta_data_get_unsigned_int (vl,
+      "network:time_sent", &time_sent);
 
-       char   *key;
-       time_t *value;
-       c_avl_iterator_t *iter;
+  /* This is a value we already sent. Don't allow it to be received again in
+   * order to avoid looping. */
+  if ((status == 0) && (time_sent >= ((uint64_t) vl->time)))
+    return (false);
 
-       time_t curtime = time (NULL);
+  return (true);
+} /* }}} _Bool check_receive_okay */
 
-       iter = c_avl_get_iterator (cache_tree);
-       while (c_avl_iterator_next (iter, (void *) &key, (void *) &value) == 0)
-       {
-               if ((curtime - *value) <= cache_flush_interval)
-                       continue;
-               tmp = (char **) realloc (keys,
-                               (keys_num + 1) * sizeof (char *));
-               if (tmp == NULL)
-               {
-                       sfree (keys);
-                       c_avl_iterator_destroy (iter);
-                       ERROR ("network plugin: cache_flush: realloc"
-                                       " failed.");
-                       return (-1);
-               }
-               keys = tmp;
-               keys[keys_num] = key;
-               keys_num++;
-       } /* while (c_avl_iterator_next) */
-       c_avl_iterator_destroy (iter);
+static _Bool check_send_okay (const value_list_t *vl) /* {{{ */
+{
+  _Bool received = false;
+  int status;
 
-       for (i = 0; i < keys_num; i++)
-       {
-               if (c_avl_remove (cache_tree, keys[i], (void *) &key,
-                                       (void *) &value) != 0)
-               {
-                       WARNING ("network plugin: cache_flush: c_avl_remove"
-                                       " (%s) failed.", keys[i]);
-                       continue;
-               }
+  if (network_config_forward != 0)
+    return (true);
 
-               sfree (key);
-               sfree (value);
-       }
+  if (vl->meta == NULL)
+    return (true);
 
-       sfree (keys);
+  status = meta_data_get_boolean (vl->meta, "network:received", &received);
+  if (status == -ENOENT)
+    return (true);
+  else if (status != 0)
+  {
+    ERROR ("network plugin: check_send_okay: meta_data_get_boolean failed "
+       "with status %i.", status);
+    return (true);
+  }
 
-       DEBUG ("network plugin: cache_flush: Removed %i %s",
-                       keys_num, (keys_num == 1) ? "entry" : "entries");
-       cache_flush_last = curtime;
-       return (0);
-} /* int cache_flush */
+  /* By default, only *send* value lists that were not *received* by the
+   * network plugin. */
+  return (!received);
+} /* }}} _Bool check_send_okay */
 
-static int cache_check (const value_list_t *vl)
+static int network_dispatch_values (value_list_t *vl) /* {{{ */
 {
-       char key[1024];
-       time_t *value = NULL;
-       int retval = -1;
+  int status;
 
-       if (cache_tree == NULL)
-               return (-1);
+  if ((vl->time <= 0)
+      || (strlen (vl->host) <= 0)
+      || (strlen (vl->plugin) <= 0)
+      || (strlen (vl->type) <= 0))
+    return (-EINVAL);
 
-       if (format_name (key, sizeof (key), vl->host, vl->plugin,
-                               vl->plugin_instance, vl->type, vl->type_instance))
-               return (-1);
+  if (!check_receive_okay (vl))
+  {
+#if COLLECT_DEBUG
+         char name[6*DATA_MAX_NAME_LEN];
+         FORMAT_VL (name, sizeof (name), vl);
+         name[sizeof (name) - 1] = 0;
+         DEBUG ("network plugin: network_dispatch_values: "
+             "NOT dispatching %s.", name);
+#endif
+    return (0);
+  }
 
-       pthread_mutex_lock (&cache_lock);
+  assert (vl->meta == NULL);
 
-       if (c_avl_get (cache_tree, key, (void *) &value) == 0)
-       {
-               if (*value < vl->time)
-               {
-                       *value = vl->time;
-                       retval = 0;
-               }
-               else
-               {
-                       DEBUG ("network plugin: cache_check: *value = %i >= vl->time = %i",
-                                       (int) *value, (int) vl->time);
-                       retval = 1;
-               }
-       }
-       else
-       {
-               char *key_copy = strdup (key);
-               value = malloc (sizeof (time_t));
-               if ((key_copy != NULL) && (value != NULL))
-               {
-                       *value = vl->time;
-                       c_avl_insert (cache_tree, key_copy, value);
-                       retval = 0;
-               }
-               else
-               {
-                       sfree (key_copy);
-                       sfree (value);
-               }
-       }
+  vl->meta = meta_data_create ();
+  if (vl->meta == NULL)
+  {
+    ERROR ("network plugin: meta_data_create failed.");
+    return (-ENOMEM);
+  }
 
-       if ((time (NULL) - cache_flush_last) > cache_flush_interval)
-               cache_flush ();
+  status = meta_data_add_boolean (vl->meta, "network:received", true);
+  if (status != 0)
+  {
+    ERROR ("network plugin: meta_data_add_boolean failed.");
+    meta_data_destroy (vl->meta);
+    vl->meta = NULL;
+    return (status);
+  }
 
-       pthread_mutex_unlock (&cache_lock);
+  plugin_dispatch_values (vl);
 
-       return (retval);
-} /* int cache_check */
+  meta_data_destroy (vl->meta);
+  vl->meta = NULL;
 
-#if HAVE_GCRYPT_H
+  return (0);
+} /* }}} int network_dispatch_values */
+
+#if HAVE_LIBGCRYPT
 static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
     const void *iv, size_t iv_size, const char *username)
 {
@@ -478,7 +452,7 @@ static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
 
   return (*cyper_ptr);
 } /* }}} int network_get_aes256_cypher */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static int write_part_values (char **ret_buffer, int *ret_buffer_len,
                const data_set_t *ds, const value_list_t *vl)
@@ -525,17 +499,34 @@ static int write_part_values (char **ret_buffer, int *ret_buffer_len,
 
        for (i = 0; i < num_values; i++)
        {
-               if (ds->ds[i].type == DS_TYPE_COUNTER)
-               {
-                       pkg_values_types[i] = DS_TYPE_COUNTER;
-                       pkg_values[i].counter = htonll (vl->values[i].counter);
-               }
-               else
+               pkg_values_types[i] = (uint8_t) ds->ds[i].type;
+               switch (ds->ds[i].type)
                {
-                       pkg_values_types[i] = DS_TYPE_GAUGE;
-                       pkg_values[i].gauge = htond (vl->values[i].gauge);
-               }
-       }
+                       case DS_TYPE_COUNTER:
+                               pkg_values[i].counter = htonll (vl->values[i].counter);
+                               break;
+
+                       case DS_TYPE_GAUGE:
+                               pkg_values[i].gauge = htond (vl->values[i].gauge);
+                               break;
+
+                       case DS_TYPE_DERIVE:
+                               pkg_values[i].derive = htonll (vl->values[i].derive);
+                               break;
+
+                       case DS_TYPE_ABSOLUTE:
+                               pkg_values[i].absolute = htonll (vl->values[i].absolute);
+                               break;
+
+                       default:
+                               free (pkg_values_types);
+                               free (pkg_values);
+                               ERROR ("network plugin: write_part_values: "
+                                               "Unknown data source type: %i",
+                                               ds->ds[i].type);
+                               return (-1);
+               } /* switch (ds->ds[i].type) */
+       } /* for (num_values) */
 
        /*
         * Use `memcpy' to write everything to the buffer, because the pointer
@@ -711,10 +702,32 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
 
        for (i = 0; i < pkg_numval; i++)
        {
-               if (pkg_types[i] == DS_TYPE_COUNTER)
-                       pkg_values[i].counter = ntohll (pkg_values[i].counter);
-               else if (pkg_types[i] == DS_TYPE_GAUGE)
-                       pkg_values[i].gauge = ntohd (pkg_values[i].gauge);
+               switch (pkg_types[i])
+               {
+                 case DS_TYPE_COUNTER:
+                   pkg_values[i].counter = (counter_t) ntohll (pkg_values[i].counter);
+                   break;
+
+                 case DS_TYPE_GAUGE:
+                   pkg_values[i].gauge = (gauge_t) ntohd (pkg_values[i].gauge);
+                   break;
+
+                 case DS_TYPE_DERIVE:
+                   pkg_values[i].derive = (derive_t) ntohll (pkg_values[i].derive);
+                   break;
+
+                 case DS_TYPE_ABSOLUTE:
+                   pkg_values[i].absolute = (absolute_t) ntohll (pkg_values[i].absolute);
+                   break;
+
+                 default:
+                   sfree (pkg_types);
+                   sfree (pkg_values);
+                   NOTICE ("network plugin: parse_part_values: "
+                       "Don't know how to handle data source type %"PRIu8,
+                       pkg_types[i]);
+                   return (-1);
+               } /* switch (pkg_types[i]) */
        }
 
        *ret_buffer     = buffer;
@@ -863,7 +876,7 @@ static int parse_packet (sockent_t *se,
   buffer_offset += (s); \
 } while (0)
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_len, int flags)
 {
@@ -991,9 +1004,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-/* #endif HAVE_GCRYPT_H */
+/* #endif HAVE_LIBGCRYPT */
 
-#else /* if !HAVE_GCRYPT_H */
+#else /* if !HAVE_LIBGCRYPT */
 static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_size, int flags)
 {
@@ -1036,9 +1049,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_sign_sha256 */
-#endif /* !HAVE_GCRYPT_H */
+#endif /* !HAVE_LIBGCRYPT */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
                void **ret_buffer, size_t *ret_buffer_len,
                int flags)
@@ -1151,9 +1164,9 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-/* #endif HAVE_GCRYPT_H */
+/* #endif HAVE_LIBGCRYPT */
 
-#else /* if !HAVE_GCRYPT_H */
+#else /* if !HAVE_LIBGCRYPT */
 static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
     void **ret_buffer, size_t *ret_buffer_size, int flags)
 {
@@ -1198,7 +1211,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
 
   return (0);
 } /* }}} int parse_part_encr_aes256 */
-#endif /* !HAVE_GCRYPT_H */
+#endif /* !HAVE_LIBGCRYPT */
 
 #undef BUFFER_READ
 
@@ -1210,11 +1223,11 @@ static int parse_packet (sockent_t *se, /* {{{ */
        value_list_t vl = VALUE_LIST_INIT;
        notification_t n;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
        int packet_was_signed = (flags & PP_SIGNED);
         int packet_was_encrypted = (flags & PP_ENCRYPTED);
        int printed_ignore_warning = 0;
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 
        memset (&vl, '\0', sizeof (vl));
@@ -1255,7 +1268,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                break;
                        }
                }
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                else if ((se->data.server.security_level == SECURITY_LEVEL_ENCRYPT)
                                && (packet_was_encrypted == 0))
                {
@@ -1268,7 +1281,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        buffer = ((char *) buffer) + pkg_length;
                        continue;
                }
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
                else if (pkg_type == TYPE_SIGN_SHA256)
                {
                        status = parse_part_sign_sha256 (se,
@@ -1281,7 +1294,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                break;
                        }
                }
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                else if ((se->data.server.security_level == SECURITY_LEVEL_SIGN)
                                && (packet_was_encrypted == 0)
                                && (packet_was_signed == 0))
@@ -1295,28 +1308,15 @@ static int parse_packet (sockent_t *se, /* {{{ */
                        buffer = ((char *) buffer) + pkg_length;
                        continue;
                }
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
                else if (pkg_type == TYPE_VALUES)
                {
                        status = parse_part_values (&buffer, &buffer_size,
                                        &vl.values, &vl.values_len);
-
                        if (status != 0)
                                break;
 
-                       if ((vl.time > 0)
-                                       && (strlen (vl.host) > 0)
-                                       && (strlen (vl.plugin) > 0)
-                                       && (strlen (vl.type) > 0)
-                                       && (cache_check (&vl) == 0))
-                       {
-                               plugin_dispatch_values (&vl);
-                       }
-                       else
-                       {
-                               DEBUG ("network plugin: parse_packet:"
-                                               " NOT dispatching values");
-                       }
+                       network_dispatch_values (&vl);
 
                        sfree (vl.values);
                }
@@ -1442,7 +1442,7 @@ static void free_sockent_client (struct sockent_client *sec) /* {{{ */
     sec->fd = -1;
   }
   sfree (sec->addr);
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
   sfree (sec->username);
   sfree (sec->password);
   if (sec->cypher != NULL)
@@ -1464,7 +1464,7 @@ static void free_sockent_server (struct sockent_server *ses) /* {{{ */
   }
 
   sfree (ses->fd);
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
   sfree (ses->auth_file);
   fbh_destroy (ses->userdb);
   if (ses->cypher != NULL)
@@ -1685,7 +1685,7 @@ static int sockent_init (sockent_t *se, int type) /* {{{ */
        {
                se->type = SOCKENT_TYPE_SERVER;
                se->data.server.fd = NULL;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                se->data.server.security_level = SECURITY_LEVEL_NONE;
                se->data.server.auth_file = NULL;
                se->data.server.userdb = NULL;
@@ -1696,7 +1696,7 @@ static int sockent_init (sockent_t *se, int type) /* {{{ */
        {
                se->data.client.fd = -1;
                se->data.client.addr = NULL;
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
                se->data.client.security_level = SECURITY_LEVEL_NONE;
                se->data.client.username = NULL;
                se->data.client.password = NULL;
@@ -1721,7 +1721,7 @@ static int sockent_open (sockent_t *se) /* {{{ */
                return (-1);
 
        /* Set up the security structures. */
-#if HAVE_GCRYPT_H /* {{{ */
+#if HAVE_LIBGCRYPT /* {{{ */
        if (se->type == SOCKENT_TYPE_CLIENT)
        {
                if (se->data.client.security_level > SECURITY_LEVEL_NONE)
@@ -1765,7 +1765,7 @@ static int sockent_open (sockent_t *se) /* {{{ */
                        }
                }
        }
-#endif /* }}} HAVE_GCRYPT_H */
+#endif /* }}} HAVE_LIBGCRYPT */
 
         node = se->node;
         service = se->service;
@@ -2164,7 +2164,7 @@ static void networt_send_buffer_plain (const sockent_t *se, /* {{{ */
        } /* while (42) */
 } /* }}} void networt_send_buffer_plain */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 #define BUFFER_ADD(p,s) do { \
   memcpy (buffer + buffer_offset, (p), (s)); \
   buffer_offset += (s); \
@@ -2259,9 +2259,6 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
   gcry_error_t err;
   gcry_cipher_hd_t cypher;
 
-  DEBUG ("network plugin: networt_send_buffer_encrypted: "
-      "buffer_size = %zu;", buffer_size);
-
   /* Initialize the header fields */
   memset (&pea, 0, sizeof (pea));
   pea.head.type = htons (TYPE_ENCR_AES256);
@@ -2280,6 +2277,8 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
     - sizeof (pea.hash);
 
   assert (buffer_size <= sizeof (buffer));
+  DEBUG ("network plugin: networt_send_buffer_encrypted: "
+      "buffer_size = %zu;", buffer_size);
 
   pea.head.length = htons ((uint16_t) (PART_ENCRYPTION_AES256_SIZE
         + username_len + in_buffer_size));
@@ -2328,7 +2327,7 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
   networt_send_buffer_plain (se, buffer, buffer_size);
 } /* }}} void networt_send_buffer_encrypted */
 #undef BUFFER_ADD
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
 {
@@ -2338,13 +2337,13 @@ static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
 
   for (se = sending_sockets; se != NULL; se = se->next)
   {
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
       networt_send_buffer_encrypted (se, buffer, buffer_len);
     else if (se->data.client.security_level == SECURITY_LEVEL_SIGN)
       networt_send_buffer_signed (se, buffer, buffer_len);
     else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
       networt_send_buffer_plain (se, buffer, buffer_len);
   } /* for (sending_sockets) */
 } /* }}} void network_send_buffer */
@@ -2433,13 +2432,20 @@ static int network_write (const data_set_t *ds, const value_list_t *vl,
 {
        int status;
 
-       /* If the value is already in the cache, we have received it via the
-        * network. We write it again if forwarding is activated. It's then in
-        * the cache and should we receive it again we will ignore it. */
-       status = cache_check (vl);
-       if ((network_config_forward == 0)
-                       && (status != 0))
-               return (0);
+       if (!check_send_okay (vl))
+       {
+#if COLLECT_DEBUG
+         char name[6*DATA_MAX_NAME_LEN];
+         FORMAT_VL (name, sizeof (name), vl);
+         name[sizeof (name) - 1] = 0;
+         DEBUG ("network plugin: network_write: "
+             "NOT sending %s.", name);
+#endif
+         return (0);
+       }
+
+       uc_meta_data_add_unsigned_int (vl,
+           "network:time_sent", (uint64_t) vl->time);
 
        pthread_mutex_lock (&send_buffer_lock);
 
@@ -2545,6 +2551,7 @@ static int network_config_set_ttl (const oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int network_config_set_ttl */
 
+#if HAVE_LIBGCRYPT
 static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
     char **ret_string)
 {
@@ -2566,8 +2573,9 @@ static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
 
   return (0);
 } /* }}} int network_config_set_string */
+#endif /* HAVE_LIBGCRYPT */
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
 static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
     int *retval)
 {
@@ -2595,7 +2603,7 @@ static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
 
   return (0);
 } /* }}} int network_config_set_security_level */
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
 
 static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
 {
@@ -2628,20 +2636,21 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
   {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (strcasecmp ("AuthFile", child->key) == 0)
       network_config_set_string (child, &se->data.server.auth_file);
     else if (strcasecmp ("SecurityLevel", child->key) == 0)
       network_config_set_security_level (child,
           &se->data.server.security_level);
     else
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
     {
       WARNING ("network plugin: Option `%s' is not allowed here.",
           child->key);
     }
   }
 
+#if HAVE_LIBGCRYPT
   if ((se->data.server.security_level > SECURITY_LEVEL_NONE)
       && (se->data.server.auth_file == NULL))
   {
@@ -2651,6 +2660,7 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
     sockent_destroy (se);
     return (-1);
   }
+#endif /* HAVE_LIBGCRYPT */
 
   status = sockent_open (se);
   if (status != 0)
@@ -2702,7 +2712,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
   {
     oconfig_item_t *child = ci->children + i;
 
-#if HAVE_GCRYPT_H
+#if HAVE_LIBGCRYPT
     if (strcasecmp ("Username", child->key) == 0)
       network_config_set_string (child, &se->data.client.username);
     else if (strcasecmp ("Password", child->key) == 0)
@@ -2711,13 +2721,14 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
       network_config_set_security_level (child,
           &se->data.client.security_level);
     else
-#endif /* HAVE_GCRYPT_H */
+#endif /* HAVE_LIBGCRYPT */
     {
       WARNING ("network plugin: Option `%s' is not allowed here.",
           child->key);
     }
   }
 
+#if HAVE_LIBGCRYPT
   if ((se->data.client.security_level > SECURITY_LEVEL_NONE)
       && ((se->data.client.username == NULL)
         || (se->data.client.password == NULL)))
@@ -2728,6 +2739,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
     sockent_destroy (se);
     return (-1);
   }
+#endif /* HAVE_LIBGCRYPT */
 
   status = sockent_open (se);
   if (status != 0)
@@ -2748,24 +2760,6 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int network_config_add_server */
 
-static int network_config_set_cache_flush (const oconfig_item_t *ci) /* {{{ */
-{
-  int tmp;
-  if ((ci->values_num != 1)
-      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
-  {
-    WARNING ("network plugin: The `CacheFlush' config option needs exactly "
-        "one numeric argument.");
-    return (-1);
-  }
-
-  tmp = (int) ci->values[0].value.number;
-  if (tmp > 0)
-    network_config_ttl = tmp;
-
-  return (0);
-} /* }}} int network_config_set_cache_flush */
-
 static int network_config (oconfig_item_t *ci) /* {{{ */
 {
   int i;
@@ -2783,7 +2777,7 @@ static int network_config (oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp ("Forward", child->key) == 0)
       network_config_set_boolean (child, &network_config_forward);
     else if (strcasecmp ("CacheFlush", child->key) == 0)
-      network_config_set_cache_flush (child);
+      /* no op for backwards compatibility only */;
     else
     {
       WARNING ("network plugin: Option `%s' is not allowed here.",
@@ -2896,20 +2890,6 @@ static int network_shutdown (void)
        if (send_buffer_fill > 0)
                flush_buffer ();
 
-       if (cache_tree != NULL)
-       {
-               void *key;
-               void *value;
-
-               while (c_avl_pick (cache_tree, &key, &value) == 0)
-               {
-                       sfree (key);
-                       sfree (value);
-               }
-               c_avl_destroy (cache_tree);
-               cache_tree = NULL;
-       }
-
        /* TODO: Close `sending_sockets' */
 
        plugin_unregister_config ("network");
@@ -2917,26 +2897,23 @@ static int network_shutdown (void)
        plugin_unregister_write ("network");
        plugin_unregister_shutdown ("network");
 
-       /* Let the init function do it's move again ;) */
-       cache_flush_last = 0;
-
        return (0);
 } /* int network_shutdown */
 
 static int network_init (void)
 {
+       static _Bool have_init = false;
+
        /* Check if we were already initialized. If so, just return - there's
         * nothing more to do (for now, that is). */
-       if (cache_flush_last != 0)
+       if (have_init)
                return (0);
+       have_init = true;
 
        plugin_register_shutdown ("network", network_shutdown);
 
        network_init_buffer ();
 
-       cache_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp);
-       cache_flush_last = time (NULL);
-
        /* setup socket(s) and so on */
        if (sending_sockets != NULL)
        {
@@ -3008,11 +2985,8 @@ static int network_flush (int timeout,
 {
        pthread_mutex_lock (&send_buffer_lock);
 
-       if (((time (NULL) - cache_flush_last) >= timeout)
-                       && (send_buffer_fill > 0))
-       {
-               flush_buffer ();
-       }
+       if (send_buffer_fill > 0)
+         flush_buffer ();
 
        pthread_mutex_unlock (&send_buffer_lock);