static void set_reuseaddr P((int));
static isc_boolean_t socket_broadcast_enable P((struct interface *, SOCKET, struct sockaddr_storage *));
static isc_boolean_t socket_broadcast_disable P((struct interface *, int, struct sockaddr_storage *));
+/*
+ * Multicast functions
+ */
static isc_boolean_t addr_ismulticast P((struct sockaddr_storage *));
/*
* Not all platforms support multicast
return (ISC_FALSE);
}
}
+/*
+ * Multicast servers need to set the appropriate Multicast interface
+ * socket option in order for it to know which interface to use for
+ * send the multicast packet.
+ */
+void
+enable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr)
+{
+ switch (maddr->ss_family)
+ {
+ case AF_INET:
+ if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,
+ (char *)&(((struct sockaddr_in*)&iface->sin)->sin_addr.s_addr),
+ sizeof(struct sockaddr_in*)) == -1) {
+ netsyslog(LOG_ERR,
+ "setsockopt IP_MULTICAST_IF failure: %m on socket %d, addr %s for multicast address %s",
+ iface->fd, stoa(&iface->sin), stoa(maddr));
+ return;
+ }
+#ifdef DEBUG
+ if (debug > 0) {
+ printf(
+ "Added IPv4 multicast interface on socket %d, addr %s for multicast address %s\n",
+ iface->fd, stoa(&iface->sin),
+ stoa(maddr));
+ }
+#endif
+ break;
+ case AF_INET6:
+#ifdef INCLUDE_IPV6_MULTICAST_SUPPORT
+ if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ &iface->scopeid, sizeof(iface->scopeid)) == -1) {
+ netsyslog(LOG_ERR,
+ "setsockopt IPV6_MULTICAST_IF failure: %m on socket %d, addr %s, scope %d for multicast address %s",
+ iface->fd, stoa(&iface->sin), iface->scopeid,
+ stoa(maddr));
+ return;
+ }
+#ifdef DEBUG
+ if (debug > 0) {
+ printf(
+ "Added IPv6 multicast interface on socket %d, addr %s, scope %d for multicast address %s\n",
+ iface->fd, stoa(&iface->sin), iface->scopeid,
+ stoa(maddr));
+ }
+#endif
+ break;
+#else
+ return;
+#endif /* INCLUDE_IPV6_MULTICAST_SUPPORT */
+ }
+ return;
+}
/*
* NOTE: Not all platforms support multicast
*/
{
if (select_count == 0) /* We really had nothing to do */
{
+#ifdef DEBUG
if (debug)
netsyslog(LOG_DEBUG, "input_handler: select() returned 0");
+#endif
--handler_count;
return;
}
* it.
*/
L_SUB(&ts_e, &ts);
+#ifdef DEBUG
if (debug > 3)
netsyslog(LOG_INFO, "input_handler: Processed a gob of fd's in %s msec", lfptoms(&ts_e, 6));
-
+#endif
/* just bail. */
--handler_count;
return;
if (inter_list[i].sin.ss_family == AF_INET6 &&
(IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6*)&inter_list[i].sin)->sin6_addr)))
{
- continue;
+/* continue; */
}
#endif
/*
else if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
peer->dstadr = findbcastinter(srcadr);
#ifdef DEBUG
- if (debug > 1)
- printf("Found broadcast interface address %s, for address %s\n",
- stoa(&(peer->dstadr)->sin), stoa(srcadr));
+ if (debug > 1) {
+ if (peer->dstadr != NULL)
+ printf("Found broadcast interface address %s, for address %s\n",
+ stoa(&(peer->dstadr)->sin), stoa(srcadr));
+ else
+ printf("No broadcast local address found for address %s\n",
+ stoa(srcadr));
+ }
#endif
/*
* If it was a multicast packet, findbcastinter() may not
if (cast_flags & MDF_BCAST) {
enable_broadcast(peer->dstadr, srcadr);
}
+ /*
+ * Multicast needs the socket interface enabled for multicast
+ */
+ if (cast_flags & MDF_MCAST) {
+ enable_multicast_if(peer->dstadr, srcadr);
+ }
#ifdef DEBUG
if (debug>2)
printf("newpeer: using fd %d and our addr %s\n",