From 7e9a722fa5d169d5efd1afcdfff5676fd3bcfcc0 Mon Sep 17 00:00:00 2001 From: octo Date: Sun, 29 Jan 2006 14:53:57 +0000 Subject: [PATCH] First version of `network.c' running.. --- src/Makefile.am | 1 - src/collectd.c | 5 ++-- src/configfile.c | 50 ++++++++++++++++++++++++++++++++++++ src/network.c | 66 ++++++++++++++++++++++++++++++++++++------------ src/network.h | 32 +++++++++++++++++++++++ src/plugin.c | 8 +++--- 6 files changed, 139 insertions(+), 23 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 2c0e3484..b6ae7588 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,6 @@ collectd_SOURCES = collectd.c collectd.h \ utils_debug.c utils_debug.h \ utils_mount.c utils_mount.h \ common.c common.h \ - multicast.c multicast.h \ network.c network.h \ plugin.c plugin.h \ configfile.c configfile.h diff --git a/src/collectd.c b/src/collectd.c index c2c6dc0e..7f2f6e8c 100644 --- a/src/collectd.c +++ b/src/collectd.c @@ -25,7 +25,7 @@ #include "common.h" #include "utils_debug.h" -#include "multicast.h" +#include "network.h" #include "plugin.h" #include "configfile.h" @@ -192,6 +192,7 @@ static int start_client (void) #if HAVE_LIBRRD static int start_server (void) { + /* FIXME use stack here! */ char *host; char *type; char *instance; @@ -199,7 +200,7 @@ static int start_server (void) while (loop == 0) { - if (multicast_receive (&host, &type, &instance, &values) == 0) + if (network_receive (&host, &type, &instance, &values) == 0) plugin_write (host, type, instance, values); if (host != NULL) free (host); host = NULL; diff --git a/src/configfile.c b/src/configfile.c index be90dd37..2569b4a9 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -27,8 +27,10 @@ #include "libconfig/libconfig.h" +#include "common.h" #include "plugin.h" #include "configfile.h" +#include "network.h" #include "utils_debug.h" #define SHORTOPT_NONE 0 @@ -376,6 +378,49 @@ int cf_callback_mode_switch (const char *shortvar, const char *var, return (LC_CBRET_OKAY); } +int cf_callback_socket (const char *shortvar, const char *var, + const char *arguments, const char *value, lc_flags_t flags, + void *extra) +{ + char *buffer; + + char *fields[3]; + int numfields; + + char *node; + char *service = NET_DEFAULT_PORT; + + DBG ("shortvar = %s, var = %s, arguments = %s, value = %s, ...", + shortvar, var, arguments, value); + + buffer = strdup (value); + if (buffer == NULL) + return (LC_CBRET_ERROR); + + numfields = strsplit (buffer, fields, 3); + + if ((numfields != 1) && (numfields != 2)) + { + syslog (LOG_ERR, "Invalid number of arguments to `%s'", + shortvar); + free (buffer); + return (LC_CBRET_ERROR); + } + + node = fields[0]; + if (numfields == 2) + service = fields[1]; + + /* Still return `LC_CBRET_OKAY' because this is not an syntax error */ + if (network_create_socket (node, service) < 1) + syslog (LOG_ERR, "network_create_socket (%s, %s) failed", + node, service); + + free (buffer); + + return (LC_CBRET_OKAY); +} + /* * `cf_callback_plugin' * Start/end section `plugin' @@ -484,6 +529,11 @@ void cf_init (void) lc_register_callback ("LoadPlugin", SHORTOPT_NONE, LC_VAR_STRING, cf_callback_mode_loadmodule, NULL); + lc_register_callback ("Listen", SHORTOPT_NONE, + LC_VAR_STRING, cf_callback_socket, NULL); + lc_register_callback ("Server", SHORTOPT_NONE, + LC_VAR_STRING, cf_callback_socket, NULL); + for (i = 0; i < cf_mode_num; i++) { cf_mode_item_t *item; diff --git a/src/network.c b/src/network.c index 546f5e2d..b86d5a25 100644 --- a/src/network.c +++ b/src/network.c @@ -36,21 +36,6 @@ #include "common.h" #include "utils_debug.h" -/* - * From RFC2365: - * - * The IPv4 Organization Local Scope -- 239.192.0.0/14 - * - * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is - * the space from which an organization should allocate sub-ranges when - * defining scopes for private use. - * - * Port 25826 is not assigned as of 2005-09-12 - */ - -#define IPV4_MCAST_GROUP "239.192.74.66" -#define UDP_PORT 25826 - /* 1500 - 40 - 8 = Ethernet packet - IPv6 header - UDP header */ /* #define BUFF_SIZE 1452 */ @@ -65,6 +50,7 @@ static int operating_mode = MODE_CLIENT; typedef struct sockent { int fd; + int mode; struct sockaddr_storage *addr; socklen_t addrlen; struct sockent *next; @@ -76,6 +62,8 @@ static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai) { int loop = 1; + DBG ("fd = %i; calling `bind'", se->fd); + if (bind (se->fd, ai->ai_addr, ai->ai_addrlen) == -1) { syslog (LOG_ERR, "bind: %s", strerror (errno)); @@ -89,6 +77,8 @@ static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai) { struct ip_mreq mreq; + DBG ("fd = %i; IPv4 multicast address found", se->fd); + mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr; mreq.imr_interface.s_addr = htonl (INADDR_ANY); @@ -115,6 +105,8 @@ static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai) { struct ipv6_mreq mreq; + DBG ("fd = %i; IPv6 multicast address found", se->fd); + memcpy (&mreq.ipv6mr_multiaddr, &addr->sin6_addr, sizeof (addr->sin6_addr)); @@ -205,6 +197,7 @@ int network_create_socket (const char *node, const char *service) memcpy (se->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen); se->addrlen = ai_ptr->ai_addrlen; + se->mode = operating_mode; se->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); se->next = NULL; @@ -226,7 +219,8 @@ int network_create_socket (const char *node, const char *service) if (socklist_tail == NULL) { - socklist_head = socklist_tail = se; + socklist_head = se; + socklist_tail = se; } else { @@ -246,6 +240,29 @@ int network_create_socket (const char *node, const char *service) return (num_added); } +static int network_connect_default (void) +{ + int ret; + + if (socklist_head != NULL) + return (0); + + DBG ("socklist_head is NULL"); + + ret = 0; + + if (network_create_socket (NET_DEFAULT_V4_ADDR, NET_DEFAULT_PORT) > 0) + ret++; + + if (network_create_socket (NET_DEFAULT_V6_ADDR, NET_DEFAULT_PORT) > 0) + ret++; + + if (ret == 0) + ret = -1; + + return (ret); +} + static int network_get_listen_socket (void) { int fd; @@ -255,12 +272,18 @@ static int network_get_listen_socket (void) fd_set readfds; sockent_t *se; + if (socklist_head == NULL) + network_connect_default (); + while (1) { FD_ZERO (&readfds); max_fd = -1; for (se = socklist_head; se != NULL; se = se->next) { + if (se->mode != operating_mode) + continue; + FD_SET (se->fd, &readfds); if (se->fd >= max_fd) max_fd = se->fd + 1; @@ -287,11 +310,16 @@ static int network_get_listen_socket (void) fd = -1; for (se = socklist_head; se != NULL; se = se->next) + { + if (se->mode != operating_mode) + continue; + if (FD_ISSET (se->fd, &readfds)) { fd = se->fd; break; } + } if (fd == -1) syslog (LOG_WARNING, "No socket ready..?"); @@ -403,9 +431,15 @@ int network_send (char *type, char *inst, char *value) buf[buflen] = '\0'; buflen++; + if (socklist_head == NULL) + network_connect_default (); + ret = 0; for (se = socklist_head; se != NULL; se = se->next) { + if (se->mode != operating_mode) + continue; + DBG ("fd = %i", se->fd); while (1) diff --git a/src/network.h b/src/network.h index e2448ab1..374448cc 100644 --- a/src/network.h +++ b/src/network.h @@ -23,6 +23,38 @@ #ifndef NETWORK_H #define NETWORK_H +/* + * From RFC2365: Administratively Scoped IP Multicast + * + * The IPv4 Organization Local Scope -- 239.192.0.0/14 + * + * 239.192.0.0/14 is defined to be the IPv4 Organization Local Scope, and is + * the space from which an organization should allocate sub-ranges when + * defining scopes for private use. + * + * Port 25826 is not assigned as of 2005-09-12 + */ + +/* + * From RFC2373: IP Version 6 Addressing Architecture + * + * 2.7 Multicast Addresses + * + * | 8 | 4 | 4 | 80 bits | 32 bits | + * +--------+----+----+---------------------------+-----------------+ + * |11111111|flgs|scop| reserved must be zero | group ID | + * +--------+----+----+---------------------------+-----------------+ + * + * flgs = 1 => non-permanently-assigned ("transient") multicast address. + * scop = 8 => organization-local scope + * + * group = efc0:4a42 = 239.192.74.66 + */ + +#define NET_DEFAULT_V4_ADDR "239.192.74.66" +#define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" +#define NET_DEFAULT_PORT "25826" + int network_create_socket (const char *node, const char *service); int network_receive (char **host, char **type, char **instance, char **value); int network_send (char *type, char *instance, char *value); diff --git a/src/plugin.c b/src/plugin.c index 98add242..fc79668d 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -25,7 +25,7 @@ #include #include "plugin.h" -#include "multicast.h" +#include "network.h" typedef struct plugin { @@ -333,7 +333,7 @@ void plugin_write (char *host, char *type, char *inst, char *val) /* * Receive data from the plugin/module and get it somehow to ``plugin_write'': - * Either using ``multicast_send'' (when in network/client mode) or call it + * Either using ``network_send'' (when in network/client mode) or call it * directly (in local mode). */ void plugin_submit (char *type, char *inst, char *val) @@ -342,10 +342,10 @@ void plugin_submit (char *type, char *inst, char *val) if (operating_mode == MODE_LOCAL) plugin_write (NULL, type, inst, val); else if (operating_mode == MODE_CLIENT) - multicast_send (type, inst, val); + network_send (type, inst, val); else /* operating_mode == MODE_SERVER */ syslog (LOG_ERR, "WTF is the server doing in ``plugin_submit''?!?\n"); #else - multicast_send (type, inst, val); + network_send (type, inst, val); #endif } -- 2.30.2