X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fnetwork.c;h=3f0c6fa1a08858def27ffd167362475faf0fcbc8;hb=cc0bb2b472628ccede974a02c822d1f9189f0d21;hp=9cb8c38e071344a24fde6aa3909b99f619fe0cc9;hpb=b6d95bf9f5713c62286851c1782ac95b2eb2fa21;p=collectd.git diff --git a/src/network.c b/src/network.c index 9cb8c38e..3f0c6fa1 100644 --- a/src/network.c +++ b/src/network.c @@ -1,6 +1,6 @@ /** * collectd - src/network.c - * Copyright (C) 2005-2009 Florian octo Forster + * Copyright (C) 2005-2010 Florian octo Forster * Copyright (C) 2009 Aman Gupta * * This program is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "utils_fbhash.h" #include "utils_avltree.h" #include "utils_cache.h" +#include "utils_complain.h" #include "network.h" @@ -57,7 +58,24 @@ #endif #if HAVE_LIBGCRYPT +# include +# if defined __APPLE__ +/* default xcode compiler throws warnings even when deprecated functionality + * is not used. -Werror breaks the build because of erroneous warnings. + * http://stackoverflow.com/questions/10556299/compiler-warnings-with-libgcrypt-v1-5-0/12830209#12830209 + */ +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# endif +/* FreeBSD's copy of libgcrypt extends the existing GCRYPT_NO_DEPRECATED + * to properly hide all deprecated functionality. + * http://svnweb.freebsd.org/ports/head/security/libgcrypt/files/patch-src__gcrypt.h.in + */ +# define GCRYPT_NO_DEPRECATED # include +# if defined __APPLE__ +/* Re enable deprecation warnings */ +# pragma GCC diagnostic warning "-Wdeprecated-declarations" +# endif GCRY_THREAD_OPTION_PTHREAD_IMPL; #endif @@ -258,7 +276,8 @@ typedef struct receive_list_entry_s receive_list_entry_t; * Private variables */ static int network_config_ttl = 0; -static size_t network_config_packet_size = 1024; +/* Ethernet - (IPv6 + UDP) = 1500 - (40 + 8) = 1452 */ +static size_t network_config_packet_size = 1452; static int network_config_forward = 0; static int network_config_stats = 0; @@ -295,14 +314,14 @@ static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER; * example). Only if neither is true, the stats_lock is acquired. The counters * are always read without holding a lock in the hope that writing 8 bytes to * memory is an atomic operation. */ -static uint64_t stats_octets_rx = 0; -static uint64_t stats_octets_tx = 0; -static uint64_t stats_packets_rx = 0; -static uint64_t stats_packets_tx = 0; -static uint64_t stats_values_dispatched = 0; -static uint64_t stats_values_not_dispatched = 0; -static uint64_t stats_values_sent = 0; -static uint64_t stats_values_not_sent = 0; +static derive_t stats_octets_rx = 0; +static derive_t stats_octets_tx = 0; +static derive_t stats_packets_rx = 0; +static derive_t stats_packets_tx = 0; +static derive_t stats_values_dispatched = 0; +static derive_t stats_values_not_dispatched = 0; +static derive_t stats_values_sent = 0; +static derive_t stats_values_not_sent = 0; static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; /* @@ -319,30 +338,30 @@ static _Bool check_receive_okay (const value_list_t *vl) /* {{{ */ /* 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); + return (0); - return (true); + return (1); } /* }}} _Bool check_receive_okay */ static _Bool check_send_okay (const value_list_t *vl) /* {{{ */ { - _Bool received = false; + _Bool received = 0; int status; if (network_config_forward != 0) - return (true); + return (1); if (vl->meta == NULL) - return (true); + return (1); status = meta_data_get_boolean (vl->meta, "network:received", &received); if (status == -ENOENT) - return (true); + return (1); else if (status != 0) { ERROR ("network plugin: check_send_okay: meta_data_get_boolean failed " "with status %i.", status); - return (true); + return (1); } /* By default, only *send* value lists that were not *received* by the @@ -350,7 +369,45 @@ static _Bool check_send_okay (const value_list_t *vl) /* {{{ */ return (!received); } /* }}} _Bool check_send_okay */ -static int network_dispatch_values (value_list_t *vl) /* {{{ */ +static _Bool check_notify_received (const notification_t *n) /* {{{ */ +{ + notification_meta_t *ptr; + + for (ptr = n->meta; ptr != NULL; ptr = ptr->next) + if ((strcmp ("network:received", ptr->name) == 0) + && (ptr->type == NM_TYPE_BOOLEAN)) + return ((_Bool) ptr->nm_value.nm_boolean); + + return (0); +} /* }}} _Bool check_notify_received */ + +static _Bool check_send_notify_okay (const notification_t *n) /* {{{ */ +{ + static c_complain_t complain_forwarding = C_COMPLAIN_INIT_STATIC; + _Bool received = 0; + + if (n->meta == NULL) + return (1); + + received = check_notify_received (n); + + if (network_config_forward && received) + { + c_complain_once (LOG_ERR, &complain_forwarding, + "network plugin: A notification has been received via the network " + "forwarding if enabled. Forwarding of notifications is currently " + "not supported, because there is not loop-deteciton available. " + "Please contact the collectd mailing list if you need this " + "feature."); + } + + /* By default, only *send* value lists that were not *received* by the + * network plugin. */ + return (!received); +} /* }}} _Bool check_send_notify_okay */ + +static int network_dispatch_values (value_list_t *vl, /* {{{ */ + const char *username) { int status; @@ -382,7 +439,7 @@ static int network_dispatch_values (value_list_t *vl) /* {{{ */ return (-ENOMEM); } - status = meta_data_add_boolean (vl->meta, "network:received", true); + status = meta_data_add_boolean (vl->meta, "network:received", 1); if (status != 0) { ERROR ("network plugin: meta_data_add_boolean failed."); @@ -391,7 +448,19 @@ static int network_dispatch_values (value_list_t *vl) /* {{{ */ return (status); } - plugin_dispatch_values (vl); + if (username != NULL) + { + status = meta_data_add_string (vl->meta, "network:username", username); + if (status != 0) + { + ERROR ("network plugin: meta_data_add_string failed."); + meta_data_destroy (vl->meta); + vl->meta = NULL; + return (status); + } + } + + plugin_dispatch_values_secure (vl); stats_values_dispatched++; meta_data_destroy (vl->meta); @@ -400,6 +469,29 @@ static int network_dispatch_values (value_list_t *vl) /* {{{ */ return (0); } /* }}} int network_dispatch_values */ +static int network_dispatch_notification (notification_t *n) /* {{{ */ +{ + int status; + + assert (n->meta == NULL); + + status = plugin_notification_meta_add_boolean (n, "network:received", 1); + if (status != 0) + { + ERROR ("network plugin: plugin_notification_meta_add_boolean failed."); + plugin_notification_meta_free (n->meta); + n->meta = NULL; + return (status); + } + + status = plugin_dispatch_notification (n); + + plugin_notification_meta_free (n->meta); + n->meta = NULL; + + return (status); +} /* }}} int network_dispatch_notification */ + #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) @@ -586,7 +678,7 @@ static int write_part_number (char **ret_buffer, int *ret_buffer_len, part_header_t pkg_head; uint64_t pkg_value; - + int offset; packet_len = sizeof (pkg_head) + sizeof (pkg_value); @@ -690,7 +782,7 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len, exp_size = 3 * sizeof (uint16_t) + pkg_numval * (sizeof (uint8_t) + sizeof (value_t)); - if ((buffer_len < 0) || (buffer_len < exp_size)) + if (buffer_len < exp_size) { WARNING ("network plugin: parse_part_values: " "Packet too short: " @@ -744,11 +836,11 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len, 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]); + sfree (pkg_types); + sfree (pkg_values); return (-1); } /* switch (pkg_types[i]) */ } @@ -774,9 +866,8 @@ static int parse_part_number (void **ret_buffer, size_t *ret_buffer_len, size_t exp_size = 2 * sizeof (uint16_t) + sizeof (uint64_t); uint16_t pkg_length; - uint16_t pkg_type; - if ((buffer_len < 0) || ((size_t) buffer_len < exp_size)) + if (buffer_len < exp_size) { WARNING ("network plugin: parse_part_number: " "Packet too short: " @@ -788,7 +879,7 @@ static int parse_part_number (void **ret_buffer, size_t *ret_buffer_len, memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); buffer += sizeof (tmp16); - pkg_type = ntohs (tmp16); + /* pkg_type = ntohs (tmp16); */ memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); buffer += sizeof (tmp16); @@ -814,9 +905,8 @@ static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len, size_t header_size = 2 * sizeof (uint16_t); uint16_t pkg_length; - uint16_t pkg_type; - if ((buffer_len < 0) || (buffer_len < header_size)) + if (buffer_len < header_size) { WARNING ("network plugin: parse_part_string: " "Packet too short: " @@ -828,7 +918,7 @@ static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len, memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); buffer += sizeof (tmp16); - pkg_type = ntohs (tmp16); + /* pkg_type = ntohs (tmp16); */ memcpy ((void *) &tmp16, buffer, sizeof (tmp16)); buffer += sizeof (tmp16); @@ -892,7 +982,8 @@ static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len, #define PP_SIGNED 0x01 #define PP_ENCRYPTED 0x02 static int parse_packet (sockent_t *se, - void *buffer, size_t buffer_size, int flags); + void *buffer, size_t buffer_size, int flags, + const char *username); #define BUFFER_READ(p,s) do { \ memcpy ((p), buffer + buffer_offset, (s)); \ @@ -903,6 +994,8 @@ static int parse_packet (sockent_t *se, static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ void **ret_buffer, size_t *ret_buffer_len, int flags) { + static c_complain_t complain_no_users = C_COMPLAIN_INIT_STATIC; + char *buffer; size_t buffer_len; size_t buffer_offset; @@ -924,8 +1017,9 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ if (se->data.server.userdb == NULL) { - NOTICE ("network plugin: Received signed network packet but can't verify " - "it because no user DB has been configured. Will accept it."); + c_complain (LOG_NOTICE, &complain_no_users, + "network plugin: Received signed network packet but can't verify it " + "because no user DB has been configured. Will accept it."); return (0); } @@ -987,6 +1081,8 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ { ERROR ("network plugin: gcry_md_setkey failed: %s", gcry_strerror (err)); gcry_md_close (hd); + sfree (secret); + sfree (pss.username); return (-1); } @@ -1008,9 +1104,6 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ gcry_md_close (hd); hd = NULL; - sfree (secret); - sfree (pss.username); - if (memcmp (pss.hash, hash, sizeof (pss.hash)) != 0) { WARNING ("network plugin: Verifying HMAC-SHA-256 signature failed: " @@ -1019,9 +1112,12 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ else { parse_packet (se, buffer + buffer_offset, buffer_len - buffer_offset, - flags | PP_SIGNED); + flags | PP_SIGNED, pss.username); } + sfree (secret); + sfree (pss.username); + *ret_buffer = buffer + buffer_len; *ret_buffer_len = 0; @@ -1065,7 +1161,8 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */ warning_has_been_printed = 1; } - parse_packet (se, buffer + part_len, buffer_size - part_len, flags); + parse_packet (se, buffer + part_len, buffer_size - part_len, flags, + /* username = */ NULL); *ret_buffer = buffer + buffer_size; *ret_buffer_size = 0; @@ -1144,7 +1241,10 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ cypher = network_get_aes256_cypher (se, pea.iv, sizeof (pea.iv), pea.username); if (cypher == NULL) + { + sfree (pea.username); return (-1); + } payload_len = part_size - (PART_ENCRYPTION_AES256_SIZE + username_len); assert (payload_len > 0); @@ -1156,6 +1256,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ /* in = */ NULL, /* in len = */ 0); if (err != 0) { + sfree (pea.username); ERROR ("network plugin: gcry_cipher_decrypt returned: %s", gcry_strerror (err)); return (-1); @@ -1174,17 +1275,22 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ buffer + buffer_offset, payload_len); if (memcmp (hash, pea.hash, sizeof (hash)) != 0) { + sfree (pea.username); ERROR ("network plugin: Decryption failed: Checksum mismatch."); return (-1); } parse_packet (se, buffer + buffer_offset, payload_len, - flags | PP_ENCRYPTED); + flags | PP_ENCRYPTED, pea.username); + + /* XXX: Free pea.username?!? */ /* Update return values */ *ret_buffer = buffer + part_size; *ret_buffer_len = buffer_len - part_size; + sfree (pea.username); + return (0); } /* }}} int parse_part_encr_aes256 */ /* #endif HAVE_LIBGCRYPT */ @@ -1239,7 +1345,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */ #undef BUFFER_READ static int parse_packet (sockent_t *se, /* {{{ */ - void *buffer, size_t buffer_size, int flags) + void *buffer, size_t buffer_size, int flags, + const char *username) { int status; @@ -1339,7 +1446,7 @@ static int parse_packet (sockent_t *se, /* {{{ */ if (status != 0) break; - network_dispatch_values (&vl); + network_dispatch_values (&vl, username); sfree (vl.values); } @@ -1350,8 +1457,19 @@ static int parse_packet (sockent_t *se, /* {{{ */ &tmp); if (status == 0) { - vl.time = (time_t) tmp; - n.time = (time_t) tmp; + vl.time = TIME_T_TO_CDTIME_T (tmp); + n.time = TIME_T_TO_CDTIME_T (tmp); + } + } + else if (pkg_type == TYPE_TIME_HR) + { + uint64_t tmp = 0; + status = parse_part_number (&buffer, &buffer_size, + &tmp); + if (status == 0) + { + vl.time = (cdtime_t) tmp; + n.time = (cdtime_t) tmp; } } else if (pkg_type == TYPE_INTERVAL) @@ -1360,7 +1478,15 @@ static int parse_packet (sockent_t *se, /* {{{ */ status = parse_part_number (&buffer, &buffer_size, &tmp); if (status == 0) - vl.interval = (int) tmp; + vl.interval = TIME_T_TO_CDTIME_T (tmp); + } + else if (pkg_type == TYPE_INTERVAL_HR) + { + uint64_t tmp = 0; + status = parse_part_number (&buffer, &buffer_size, + &tmp); + if (status == 0) + vl.interval = (cdtime_t) tmp; } else if (pkg_type == TYPE_HOST) { @@ -1435,7 +1561,7 @@ static int parse_packet (sockent_t *se, /* {{{ */ } else { - plugin_dispatch_notification (&n); + network_dispatch_notification (&n); } } else if (pkg_type == TYPE_SEVERITY) @@ -1553,10 +1679,10 @@ static int network_set_ttl (const sockent_t *se, const struct addrinfo *ai) if (setsockopt (se->data.client.fd, IPPROTO_IP, optname, &network_config_ttl, - sizeof (network_config_ttl)) == -1) + sizeof (network_config_ttl)) != 0) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (ipv4-ttl): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } @@ -1574,10 +1700,10 @@ static int network_set_ttl (const sockent_t *se, const struct addrinfo *ai) if (setsockopt (se->data.client.fd, IPPROTO_IPV6, optname, &network_config_ttl, - sizeof (network_config_ttl)) == -1) + sizeof (network_config_ttl)) != 0) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt(ipv6-ttl): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1621,10 +1747,10 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai #endif if (setsockopt (se->data.client.fd, IPPROTO_IP, IP_MULTICAST_IF, - &mreq, sizeof (mreq)) == -1) + &mreq, sizeof (mreq)) != 0) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (ipv4-multicast-if): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } @@ -1640,10 +1766,10 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai { if (setsockopt (se->data.client.fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &se->interface, - sizeof (se->interface)) == -1) + sizeof (se->interface)) != 0) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (ipv6-multicast-if): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1653,9 +1779,10 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai } } -#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE) + /* else: Not a multicast interface. */ if (se->interface != 0) { +#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE) char interface_name[IFNAMSIZ]; if (if_indextoname (se->interface, interface_name) == NULL) @@ -1668,26 +1795,42 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai sizeof(interface_name)) == -1 ) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (bind-if): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } +/* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */ + +#else + WARNING ("network plugin: Cannot set the interface on a unicast " + "socket because " +# if !defined(SO_BINDTODEVICE) + "the \"SO_BINDTODEVICE\" socket option " +# else + "the \"if_indextoname\" function " +# endif + "is not available on your system."); +#endif + } -#endif /* HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */ return (0); } /* }}} network_set_interface */ static int network_bind_socket (int fd, const struct addrinfo *ai, const int interface_idx) { +#if KERNEL_SOLARIS + char loop = 0; +#else int loop = 0; +#endif int yes = 1; /* allow multiple sockets to use the same PORT number */ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (reuseaddr): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } @@ -1730,7 +1873,7 @@ static int network_bind_socket (int fd, const struct addrinfo *ai, const int int &loop, sizeof (loop)) == -1) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (multicast-loop): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1740,7 +1883,7 @@ static int network_bind_socket (int fd, const struct addrinfo *ai, const int int &mreq, sizeof (mreq)) == -1) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (add-membership): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1778,7 +1921,7 @@ static int network_bind_socket (int fd, const struct addrinfo *ai, const int int &loop, sizeof (loop)) == -1) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (ipv6-multicast-loop): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1788,7 +1931,7 @@ static int network_bind_socket (int fd, const struct addrinfo *ai, const int int &mreq, sizeof (mreq)) == -1) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (ipv6-add-membership): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); @@ -1816,7 +1959,7 @@ static int network_bind_socket (int fd, const struct addrinfo *ai, const int int sizeof(interface_name)) == -1 ) { char errbuf[1024]; - ERROR ("setsockopt: %s", + ERROR ("network plugin: setsockopt (bind-if): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } @@ -2161,7 +2304,8 @@ static void *dispatch_thread (void __attribute__((unused)) *arg) /* {{{ */ continue; } - parse_packet (se, ent->data, ent->data_len, /* flags = */ 0); + parse_packet (se, ent->data, ent->data_len, /* flags = */ 0, + /* username = */ NULL); sfree (ent->data); sfree (ent); } /* while (42) */ @@ -2543,7 +2687,7 @@ static int add_to_buffer (char *buffer, int buffer_size, /* {{{ */ if (vl_def->time != vl->time) { - if (write_part_number (&buffer, &buffer_size, TYPE_TIME, + if (write_part_number (&buffer, &buffer_size, TYPE_TIME_HR, (uint64_t) vl->time)) return (-1); vl_def->time = vl->time; @@ -2551,7 +2695,7 @@ static int add_to_buffer (char *buffer, int buffer_size, /* {{{ */ if (vl_def->interval != vl->interval) { - if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL, + if (write_part_number (&buffer, &buffer_size, TYPE_INTERVAL_HR, (uint64_t) vl->interval)) return (-1); vl_def->interval = vl->interval; @@ -2590,7 +2734,7 @@ static int add_to_buffer (char *buffer, int buffer_size, /* {{{ */ return (-1); sstrncpy (vl_def->type_instance, vl->type_instance, sizeof (vl_def->type_instance)); } - + if (write_part_values (&buffer, &buffer_size, ds, vl) != 0) return (-1); @@ -3013,8 +3157,6 @@ static int network_config (oconfig_item_t *ci) /* {{{ */ network_config_set_boolean (child, &network_config_forward); else if (strcasecmp ("ReportStats", child->key) == 0) network_config_set_boolean (child, &network_config_stats); - else if (strcasecmp ("CacheFlush", child->key) == 0) - /* no op for backwards compatibility only */; else { WARNING ("network plugin: Option `%s' is not allowed here.", @@ -3026,17 +3168,19 @@ static int network_config (oconfig_item_t *ci) /* {{{ */ } /* }}} int network_config */ static int network_notification (const notification_t *n, - user_data_t __attribute__((unused)) *user_data) + user_data_t __attribute__((unused)) *user_data) { char buffer[network_config_packet_size]; char *buffer_ptr = buffer; int buffer_free = sizeof (buffer); int status; - memset (buffer, '\0', sizeof (buffer)); + if (!check_send_notify_okay (n)) + return (0); + memset (buffer, 0, sizeof (buffer)); - status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME, + status = write_part_number (&buffer_ptr, &buffer_free, TYPE_TIME_HR, (uint64_t) n->time); if (status != 0) return (-1); @@ -3049,7 +3193,7 @@ static int network_notification (const notification_t *n, if (strlen (n->host) > 0) { status = write_part_string (&buffer_ptr, &buffer_free, TYPE_HOST, - n->host, strlen (n->host)); + n->host, strlen (n->host)); if (status != 0) return (-1); } @@ -3057,7 +3201,7 @@ static int network_notification (const notification_t *n, if (strlen (n->plugin) > 0) { status = write_part_string (&buffer_ptr, &buffer_free, TYPE_PLUGIN, - n->plugin, strlen (n->plugin)); + n->plugin, strlen (n->plugin)); if (status != 0) return (-1); } @@ -3065,8 +3209,8 @@ static int network_notification (const notification_t *n, if (strlen (n->plugin_instance) > 0) { status = write_part_string (&buffer_ptr, &buffer_free, - TYPE_PLUGIN_INSTANCE, - n->plugin_instance, strlen (n->plugin_instance)); + TYPE_PLUGIN_INSTANCE, + n->plugin_instance, strlen (n->plugin_instance)); if (status != 0) return (-1); } @@ -3074,7 +3218,7 @@ static int network_notification (const notification_t *n, if (strlen (n->type) > 0) { status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE, - n->type, strlen (n->type)); + n->type, strlen (n->type)); if (status != 0) return (-1); } @@ -3082,7 +3226,7 @@ static int network_notification (const notification_t *n, if (strlen (n->type_instance) > 0) { status = write_part_string (&buffer_ptr, &buffer_free, TYPE_TYPE_INSTANCE, - n->type_instance, strlen (n->type_instance)); + n->type_instance, strlen (n->type_instance)); if (status != 0) return (-1); } @@ -3141,15 +3285,15 @@ static int network_shutdown (void) static int network_stats_read (void) /* {{{ */ { - uint64_t copy_octets_rx; - uint64_t copy_octets_tx; - uint64_t copy_packets_rx; - uint64_t copy_packets_tx; - uint64_t copy_values_dispatched; - uint64_t copy_values_not_dispatched; - uint64_t copy_values_sent; - uint64_t copy_values_not_sent; - uint64_t copy_receive_list_length; + derive_t copy_octets_rx; + derive_t copy_octets_tx; + derive_t copy_packets_rx; + derive_t copy_packets_tx; + derive_t copy_values_dispatched; + derive_t copy_values_not_dispatched; + derive_t copy_values_sent; + derive_t copy_values_not_sent; + derive_t copy_receive_list_length; value_list_t vl = VALUE_LIST_INIT; value_t values[2]; @@ -3172,16 +3316,16 @@ static int network_stats_read (void) /* {{{ */ sstrncpy (vl.plugin, "network", sizeof (vl.plugin)); /* Octets received / sent */ - vl.values[0].counter = (counter_t) copy_octets_rx; - vl.values[1].counter = (counter_t) copy_octets_tx; + vl.values[0].derive = (derive_t) copy_octets_rx; + vl.values[1].derive = (derive_t) copy_octets_tx; sstrncpy (vl.type, "if_octets", sizeof (vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); /* Packets received / send */ - vl.values[0].counter = (counter_t) copy_packets_rx; - vl.values[1].counter = (counter_t) copy_packets_tx; + vl.values[0].derive = (derive_t) copy_packets_rx; + vl.values[1].derive = (derive_t) copy_packets_tx; sstrncpy (vl.type, "if_packets", sizeof (vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); /* Values (not) dispatched and (not) send */ sstrncpy (vl.type, "total_values", sizeof (vl.type)); @@ -3190,46 +3334,54 @@ static int network_stats_read (void) /* {{{ */ vl.values[0].derive = (derive_t) copy_values_dispatched; sstrncpy (vl.type_instance, "dispatch-accepted", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); vl.values[0].derive = (derive_t) copy_values_not_dispatched; sstrncpy (vl.type_instance, "dispatch-rejected", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); vl.values[0].derive = (derive_t) copy_values_sent; sstrncpy (vl.type_instance, "send-accepted", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); vl.values[0].derive = (derive_t) copy_values_not_sent; sstrncpy (vl.type_instance, "send-rejected", sizeof (vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); /* Receive queue length */ vl.values[0].gauge = (gauge_t) copy_receive_list_length; sstrncpy (vl.type, "queue_length", sizeof (vl.type)); vl.type_instance[0] = 0; - plugin_dispatch_values (&vl); + plugin_dispatch_values_secure (&vl); return (0); } /* }}} int network_stats_read */ static int network_init (void) { - static _Bool have_init = false; + static _Bool have_init = 0; /* Check if we were already initialized. If so, just return - there's * nothing more to do (for now, that is). */ if (have_init) return (0); - have_init = true; + have_init = 1; #if HAVE_LIBGCRYPT - gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); - gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + /* http://lists.gnupg.org/pipermail/gcrypt-devel/2003-August/000458.html + * Because you can't know in a library whether another library has + * already initialized the library + */ + if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P)) + { + gcry_check_version(NULL); /* before calling any other functions */ + gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); + gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + } #endif if (network_config_stats != 0) @@ -3303,16 +3455,16 @@ static int network_init (void) return (0); } /* int network_init */ -/* +/* * The flush option of the network plugin cannot flush individual identifiers. * All the values are added to a buffer and sent when the buffer is full, the * requested value may or may not be in there, it's not worth finding out. We * just send the buffer if `flush' is called - if the requested value was in * there, good. If not, well, then there is nothing to flush.. -octo */ -static int network_flush (int timeout, - const char __attribute__((unused)) *identifier, - user_data_t __attribute__((unused)) *user_data) +static int network_flush (__attribute__((unused)) cdtime_t timeout, + __attribute__((unused)) const char *identifier, + __attribute__((unused)) user_data_t *user_data) { pthread_mutex_lock (&send_buffer_lock);