Code

First version of `network.c' running..
authorocto <octo>
Sun, 29 Jan 2006 14:53:57 +0000 (14:53 +0000)
committerocto <octo>
Sun, 29 Jan 2006 14:53:57 +0000 (14:53 +0000)
src/Makefile.am
src/collectd.c
src/configfile.c
src/network.c
src/network.h
src/plugin.c

index 2c0e3484570a1c5176c9885e4967ca0c5a921117..b6ae7588f2babe2849e5ecf0918bdf56c2a67580 100644 (file)
@@ -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
index c2c6dc0eb64d16d0a8ac3c422a453eaf7b1440e6..7f2f6e8c4bceee0a06cd0a727caa423ed2d8e698 100644 (file)
@@ -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;
index be90dd37437da693dbac11588ab66a67b246cd17..2569b4a9b3bb558eaa31f1a5c5de465799a1a1ba 100644 (file)
 
 #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;
index 546f5e2d142ad46d03548a5410d5c139ba361018..b86d5a255b1f9f5897ab20d4c9d660d846a58392 100644 (file)
 #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)
index e2448ab123a9e2cb6cc1d7f8b64699f7ee78bccb..374448cc7a3c53b2eb50a640f753fa048ff3f100 100644 (file)
 #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);
index 98add242ce7ec84478b35e82507d8afd718792db..fc79668db24d017b24dca717615568192d73fd24 100644 (file)
@@ -25,7 +25,7 @@
 #include <ltdl.h>
 
 #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
 }