Fixed the TTL option. Changed it's name to `TimeToLive' and made it apply to unicast...
authorocto <octo>
Mon, 30 Jan 2006 21:23:11 +0000 (21:23 +0000)
committerocto <octo>
Mon, 30 Jan 2006 21:23:11 +0000 (21:23 +0000)
ChangeLog
TODO
src/collectd.conf.pod
src/configfile.c
src/network.c
src/network.h

index eecef0f..7d6ea11 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,8 +10,8 @@
          address and/or port than localhost.
        * The `df' plugin now prefers `statvfs' over `statfs'.
        * The network code has been rewritten. collectd now supports unicast
-         and multicast, and IPv4 and IPv6. Also, the TTL of multicast packets
-         can be set in the configfile.
+         and multicast, and IPv4 and IPv6. Also, the TTL of sent packages can
+         be set in the configfile.
 
 2006-01-24, Version 3.6.2
        * Due to a bug in the configfile handling collectd wouldn't start in
diff --git a/TODO b/TODO
index ae003f0..1fe76c8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,9 +1,4 @@
-For version 3.6:
-* Fix RPM package
-
 For version 3.*:
 * Port nfs module to solaris
 * Port tape module to Linux
 * Maybe look into porting the serial module
-* Ping bug (disabled)
-* Write battery status, using /proc/pmu/battery_%i
index dfbe1ea..3e4b958 100644 (file)
@@ -90,9 +90,12 @@ The optional I<Port> argument sets the port to use. It can either be given
 using a numeric port number or a service name. If the argument is omited the
 default port B<25826> is assumed.
 
-=item B<MulticastTTL> I<1-255>
+=item B<TimeToLive> I<1-255>
 
-Set the time-to-live of multicast packets. The default is a TTL of C<1>.
+Set the time-to-live of sent packets. This applies to all, unicast and
+multicast, and IPv4 and IPv6 packets. The default is to not change this value.
+That means that multicast packets will be sent with a TTL of C<1> (one) on most
+operating systems.
 
 =back
 
index 41439ee..252bd31 100644 (file)
@@ -66,7 +66,7 @@ typedef struct cf_mode_item
  */
 static cf_mode_item_t cf_mode_list[] =
 {
-       {"MulticastTTL",NULL, MODE_CLIENT                           },
+       {"TimeToLive",  NULL, MODE_CLIENT                           },
        {"PIDFile",     NULL, MODE_CLIENT | MODE_SERVER | MODE_LOCAL},
        {"DataDir",     NULL, MODE_CLIENT | MODE_SERVER | MODE_LOCAL},
        {"LogFile",     NULL, MODE_CLIENT | MODE_SERVER | MODE_LOCAL}
index cecf0ba..5f9aa74 100644 (file)
@@ -58,19 +58,66 @@ typedef struct sockent
 
 static sockent_t *socklist_head = NULL;
 
-static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai)
+static int network_set_ttl (const sockent_t *se, const struct addrinfo *ai)
 {
-       int loop = 1;
-
        char *ttl_str;
        int   ttl_int;
 
-       ttl_str = cf_get_option ("MulticastTTL", NULL);
-       ttl_int = 0;
-       if (ttl_str != NULL)
-               ttl_int = atoi (ttl_str);
+       ttl_str = cf_get_option ("TimeToLive", NULL);
+       if (ttl_str == NULL)
+               return (-1);
+
+       ttl_int = atoi (ttl_str);
        if ((ttl_int < 1) || (ttl_int > 255))
-               ttl_int = NET_DEFAULT_MC_TTL;
+       {
+               syslog (LOG_WARNING, "A TTL value of %i is invalid.", ttl_int);
+               return (-1);
+       }
+
+       DBG ("ttl = %i", ttl_int);
+
+       if (ai->ai_family == AF_INET)
+       {
+               struct sockaddr_in *addr = (struct sockaddr_in *) ai->ai_addr;
+               int optname;
+
+               if (IN_MULTICAST (ntohl (addr->sin_addr.s_addr)))
+                       optname = IP_MULTICAST_TTL;
+               else
+                       optname = IP_TTL;
+
+               if (setsockopt (se->fd, IPPROTO_IP, optname,
+                                       &ttl_int, sizeof (ttl_int)) == -1)
+               {
+                       syslog (LOG_ERR, "setsockopt: %s", strerror (errno));
+                       return (-1);
+               }
+       }
+       else if (ai->ai_family == AF_INET6)
+       {
+               /* Useful example: http://gsyc.escet.urjc.es/~eva/IPv6-web/examples/mcast.html */
+               struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai->ai_addr;
+               int optname;
+
+               if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr))
+                       optname = IPV6_MULTICAST_HOPS;
+               else
+                       optname = IPV6_UNICAST_HOPS;
+
+               if (setsockopt (se->fd, IPPROTO_IPV6, optname,
+                                       &ttl_int, sizeof (ttl_int)) == -1)
+               {
+                       syslog (LOG_ERR, "setsockopt: %s", strerror (errno));
+                       return (-1);
+               }
+       }
+
+       return (0);
+}
+
+static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai)
+{
+       int loop = 1;
 
        DBG ("fd = %i; calling `bind'", se->fd);
 
@@ -99,14 +146,6 @@ static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai)
                                return (-1);
                        }
 
-                       /* IP_MULTICAST_TTL */
-                       if (setsockopt (se->fd, IPPROTO_IP, IP_MULTICAST_TTL,
-                                               &ttl_int, sizeof (ttl_int)) == -1)
-                       {
-                               syslog (LOG_ERR, "setsockopt: %s", strerror (errno));
-                               return (-1);
-                       }
-
                        if (setsockopt (se->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                                                &mreq, sizeof (mreq)) == -1)
                        {
@@ -147,13 +186,6 @@ static int network_bind_socket (const sockent_t *se, const struct addrinfo *ai)
                                return (-1);
                        }
 
-                       if (setsockopt (se->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
-                                               &ttl_int, sizeof (ttl_int)) == -1)
-                       {
-                               syslog (LOG_ERR, "setsockopt: %s", strerror (errno));
-                               return (-1);
-                       }
-
                        if (setsockopt (se->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
                                                &mreq, sizeof (mreq)) == -1)
                        {
@@ -235,12 +267,18 @@ int network_create_socket (const char *node, const char *service)
                }
 
                if (operating_mode == MODE_SERVER)
+               {
                        if (network_bind_socket (se, ai_ptr) != 0)
                        {
                                free (se->addr);
                                free (se);
                                continue;
                        }
+               }
+               else if (operating_mode == MODE_CLIENT)
+               {
+                       network_set_ttl (se, ai_ptr);
+               }
 
                if (socklist_tail == NULL)
                {
index aa3d3fc..374448c 100644 (file)
@@ -54,7 +54,6 @@
 #define NET_DEFAULT_V4_ADDR "239.192.74.66"
 #define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42"
 #define NET_DEFAULT_PORT    "25826"
-#define NET_DEFAULT_MC_TTL  1
 
 int network_create_socket (const char *node, const char *service);
 int network_receive (char **host, char **type, char **instance, char **value);