From bc86428959fc1f8cbf597bbb8e84f6b670cab7f7 Mon Sep 17 00:00:00 2001 From: octo Date: Mon, 30 Jan 2006 21:23:11 +0000 Subject: [PATCH] Fixed the TTL option. Changed it's name to `TimeToLive' and made it apply to unicast packets as well. --- ChangeLog | 4 +-- TODO | 5 --- src/collectd.conf.pod | 7 +++-- src/configfile.c | 2 +- src/network.c | 84 +++++++++++++++++++++++++++++++++++++-------------- src/network.h | 1 - 6 files changed, 69 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index eecef0fa..7d6ea115 100644 --- 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 ae003f03..1fe76c84 100644 --- 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 diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index dfbe1eab..3e4b9587 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -90,9 +90,12 @@ The optional I 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 I<1-255> +=item B 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 diff --git a/src/configfile.c b/src/configfile.c index 41439ee1..252bd31d 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -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} diff --git a/src/network.c b/src/network.c index cecf0bad..5f9aa741 100644 --- a/src/network.c +++ b/src/network.c @@ -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) { diff --git a/src/network.h b/src/network.h index aa3d3fcd..374448cc 100644 --- a/src/network.h +++ b/src/network.h @@ -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); -- 2.11.0