From: Peter A. Bigot Date: Mon, 19 May 2014 19:47:44 +0000 (-0500) Subject: rrdcached: support wildcard listen specifications X-Git-Tag: v1.5.0-rc1~83^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9d06bd95eef393530e89e838cec15a3553682254;p=thirdparty%2Frrdtool-1.x.git rrdcached: support wildcard listen specifications The documentation suggested that the syntax "-l :42217" would cause the daemon to listen on all available interfaces. The implementation didn't follow through, until now. Signed-off-by: Peter A. Bigot --- diff --git a/doc/rrdcached.pod b/doc/rrdcached.pod index 04b075e8..58c34f71 100644 --- a/doc/rrdcached.pod +++ b/doc/rrdcached.pod @@ -43,7 +43,7 @@ section below. =item B<-l> I
-Tells the daemon to bind to I
and accept incoming connections on that +Tells the daemon to bind to I
and accept incoming TCP connections on that socket. If I
begins with C, everything following that prefix is interpreted as the path to a UNIX domain socket. Otherwise the address or node name are resolved using C. @@ -52,7 +52,7 @@ For network sockets, a port may be specified by using the form CI
B<]:>I>. If the address is an IPv4 address or a fully qualified domain name (i.Ee. the address contains at least one dot (C<.>)), the square brackets can be omitted, resulting in the (simpler) -CB<:>I> pattern. The default port is B<42217/tcp>. If you +CB<:>I> pattern. The default port is B<42217>. If you specify a network socket, it is mandatory to read the L section. @@ -65,8 +65,12 @@ domain socket B start with a slash in the second case! []: : -If the B<-l> option is not specified the default address, +Given a port without a host (e.g. C<-l :42217>) the daemon will listen +on that port on all network interfaces. + +If no B<-l> option is not specified the default address, C, will be used. +Multiple B<-l> options may be provided. =item B<-s> I|I diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 2e8e0489..742d258f 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -92,6 +92,7 @@ #include #include #include +#include #include #include #include @@ -2951,6 +2952,7 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ char addr_copy[NI_MAXHOST]; char *addr; char *port; + int addr_is_wildcard = 0; int status; strncpy (addr_copy, sock->addr, sizeof(addr_copy)-1); @@ -2999,8 +3001,14 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ port++; } } + /* Empty string for address should be treated as wildcard (open on + * all interfaces) */ + addr_is_wildcard = (0 == *addr); + if (addr_is_wildcard) + ai_hints.ai_flags |= AI_PASSIVE; + ai_res = NULL; - status = getaddrinfo (addr, + status = getaddrinfo (addr_is_wildcard ? NULL : addr, port == NULL ? RRDCACHED_DEFAULT_PORT : port, &ai_hints, &ai_res); if (status != 0) @@ -3036,6 +3044,12 @@ static int open_listen_socket_network(const listen_socket_t *sock) /* {{{ */ } setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); +#ifdef IPV6_V6ONLY + /* Prevent EADDRINUSE bind errors on dual-stack configurations + * with IPv4-mapped-on-IPv6 enabled */ + if (AF_INET6 == ai_ptr->ai_family) + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)); +#endif /* IPV6_V6ONLY */ status = bind (fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); if (status != 0)