- if (setsockopt (fd, IPPROTO_IP, IP_MULTICAST_LOOP,
- &loop, sizeof (loop)) == -1)
- {
- char errbuf[1024];
- ERROR ("network plugin: setsockopt (multicast-loop): %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
-
- if (setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- &mreq, sizeof (mreq)) == -1)
- {
- char errbuf[1024];
- ERROR ("network plugin: setsockopt (add-membership): %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
-
- return (0);
- }
- }
- 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;
- if (IN6_IS_ADDR_MULTICAST (&addr->sin6_addr))
- {
- struct ipv6_mreq mreq;
-
- DEBUG ("fd = %i; IPv6 multicast address found", fd);
-
- memcpy (&mreq.ipv6mr_multiaddr,
- &addr->sin6_addr,
- sizeof (addr->sin6_addr));
-
- /* http://developer.apple.com/documentation/Darwin/Reference/ManPages/man4/ip6.4.html
- * ipv6mr_interface may be set to zeroes to
- * choose the default multicast interface or to
- * the index of a particular multicast-capable
- * interface if the host is multihomed.
- * Membership is associ-associated with a
- * single interface; programs running on
- * multihomed hosts may need to join the same
- * group on more than one interface.*/
- mreq.ipv6mr_interface = interface_idx;
-
- if (setsockopt (fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
- &loop, sizeof (loop)) == -1)
- {
- char errbuf[1024];
- ERROR ("network plugin: setsockopt (ipv6-multicast-loop): %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
-
- if (setsockopt (fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
- &mreq, sizeof (mreq)) == -1)
- {
- char errbuf[1024];
- ERROR ("network plugin: setsockopt (ipv6-add-membership): %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
-
- return (0);
- }
- }
-
-#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE)
- /* if a specific interface was set, bind the socket to it. But to avoid
- * possible problems with multicast routing, only do that for non-multicast
- * addresses */
- if (interface_idx != 0)
- {
- char interface_name[IFNAMSIZ];
-
- if (if_indextoname (interface_idx, interface_name) == NULL)
- return (-1);
-
- DEBUG ("fd = %i; Binding socket to interface %s", fd, interface_name);
-
- if (setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE,
- interface_name,
- sizeof(interface_name)) == -1 )
- {
- char errbuf[1024];
- ERROR ("network plugin: setsockopt (bind-if): %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
- }
+ /* allow multiple sockets to use the same PORT number */
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (reuseaddr): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ DEBUG("fd = %i; calling `bind'", fd);
+
+ if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
+ char errbuf[1024];
+ ERROR("bind: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ if (ai->ai_family == AF_INET) {
+ struct sockaddr_in *addr = (struct sockaddr_in *)ai->ai_addr;
+ if (IN_MULTICAST(ntohl(addr->sin_addr.s_addr))) {
+#if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
+ struct ip_mreqn mreq;
+#else
+ struct ip_mreq mreq;
+#endif
+
+ DEBUG("fd = %i; IPv4 multicast address found", fd);
+
+ mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
+#if HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
+ /* Set the interface using the interface index if
+ * possible (available). Unfortunately, the struct
+ * ip_mreqn is not portable. */
+ mreq.imr_address.s_addr = ntohl(INADDR_ANY);
+ mreq.imr_ifindex = interface_idx;
+#else
+ mreq.imr_interface.s_addr = ntohl(INADDR_ANY);
+#endif
+
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) ==
+ -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (multicast-loop): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) ==
+ -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (add-membership): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ return (0);
+ }
+ } 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;
+ if (IN6_IS_ADDR_MULTICAST(&addr->sin6_addr)) {
+ struct ipv6_mreq mreq;
+
+ DEBUG("fd = %i; IPv6 multicast address found", fd);
+
+ memcpy(&mreq.ipv6mr_multiaddr, &addr->sin6_addr, sizeof(addr->sin6_addr));
+
+ /* http://developer.apple.com/documentation/Darwin/Reference/ManPages/man4/ip6.4.html
+ * ipv6mr_interface may be set to zeroes to
+ * choose the default multicast interface or to
+ * the index of a particular multicast-capable
+ * interface if the host is multihomed.
+ * Membership is associ-associated with a
+ * single interface; programs running on
+ * multihomed hosts may need to join the same
+ * group on more than one interface.*/
+ mreq.ipv6mr_interface = interface_idx;
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop,
+ sizeof(loop)) == -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (ipv6-multicast-loop): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ if (setsockopt(fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq,
+ sizeof(mreq)) == -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (ipv6-add-membership): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+
+ return (0);
+ }
+ }
+
+#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && \
+ defined(SO_BINDTODEVICE)
+ /* if a specific interface was set, bind the socket to it. But to avoid
+ * possible problems with multicast routing, only do that for non-multicast
+ * addresses */
+ if (interface_idx != 0) {
+ char interface_name[IFNAMSIZ];
+
+ if (if_indextoname(interface_idx, interface_name) == NULL)
+ return (-1);
+
+ DEBUG("fd = %i; Binding socket to interface %s", fd, interface_name);
+
+ if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name,
+ sizeof(interface_name)) == -1) {
+ char errbuf[1024];
+ ERROR("network plugin: setsockopt (bind-if): %s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ return (-1);
+ }
+ }