Kaynağa Gözat

- multicast fixes backported: multicast options are set for all the sockets,
multicast ttl & loop options are properly set (they work on *BSD too)

Andrei Pelinescu-Onciul 20 yıl önce
ebeveyn
işleme
e6cb967269
2 değiştirilmiş dosya ile 45 ekleme ve 31 silme
  1. 1 1
      Makefile.defs
  2. 44 30
      udp_server.c

+ 1 - 1
Makefile.defs

@@ -58,7 +58,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 9
 SUBLEVEL = 4
-EXTRAVERSION = -rc1
+EXTRAVERSION = -rc2
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 44 - 30
udp_server.c

@@ -34,6 +34,8 @@
  *              added set multicast ttl support (andrei)
  *  2004-07-05  udp_rcv_loop: drop packets with 0 src port + error msg.
  *              cleanups (andrei)
+ *  2005-07-26  multicast fixes backported: multicast ttl & loop are set
+ *              for all the sockets; ipv4 ttl & loop expect a char* (andrei)
  */
 
 
@@ -234,21 +236,6 @@ static int setup_mcast_rcvr(int sock, union sockaddr_union* addr)
 			    strerror(errno));
 			return -1;
 		}
-		
-		if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, 
-			       &mcast_loopback, sizeof(mcast_loopback))==-1){
-			LOG(L_ERR, "ERROR: setup_mcast_rcvr: setsockopt: %s\n",
-			    strerror(errno));
-			return -1;
-		}
-		if (mcast_ttl>=0){
-			if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &mcast_ttl,
-						sizeof(mcast_ttl))==-1){
-				LOG(L_ERR, "ERROR: setup_mcast_rcvr: setosckopt (ttl):"
-						" %s\n", strerror(errno));
-				return -1;
-			}
-		}
 #ifdef USE_IPV6
 	} else if (addr->s.sa_family==AF_INET6){
 		memcpy(&mreq6.ipv6mr_multiaddr, &addr->sin6.sin6_addr, 
@@ -265,23 +252,9 @@ static int setup_mcast_rcvr(int sock, union sockaddr_union* addr)
 			return -1;
 		}
 		
-		if (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 
-			       &mcast_loopback, sizeof(mcast_loopback))==-1){
-			LOG(L_ERR, "ERROR: udp_init: setsockopt: %s\n", 
-			    strerror(errno));
-			return -1;
-		}
-		if (mcast_ttl>=0){
-			if (setsockopt(sock, IPPROTO_IP, IPV6_MULTICAST_HOPS, &mcast_ttl,
-						sizeof(mcast_ttl))==-1){
-				LOG(L_ERR, "ERROR: setup_mcast_rcvr: setosckopt (ttlv6):"
-						" %s\n", strerror(errno));
-				return -1;
-			}
-		}
 #endif /* USE_IPV6 */
 	} else {
-		LOG(L_ERR, "ERROR: udp_init: Unsupported protocol family\n");
+		LOG(L_ERR, "ERROR: setup_mcast_rcvr: Unsupported protocol family\n");
 		return -1;
 	}
 	return 0;
@@ -294,6 +267,9 @@ int udp_init(struct socket_info* sock_info)
 {
 	union sockaddr_union* addr;
 	int optval;
+#ifdef USE_MCAST
+	unsigned char m_ttl, m_loop;
+#endif
 	addr=&sock_info->su;
 /*
 	addr=(union sockaddr_union*)pkg_malloc(sizeof(union sockaddr_union));
@@ -342,6 +318,44 @@ int udp_init(struct socket_info* sock_info)
 	    && (setup_mcast_rcvr(sock_info->socket, addr)<0)){
 			goto error;
 	}
+	/* set the multicast options */
+	if (addr->s.sa_family==AF_INET){
+		m_loop=mcast_loopback;
+		if (setsockopt(sock_info->socket, IPPROTO_IP, IP_MULTICAST_LOOP, 
+						&m_loop, sizeof(m_loop))==-1){
+			LOG(L_WARN, "WARNING: udp_init: setsockopt(IP_MULTICAST_LOOP):"
+						" %s\n", strerror(errno));
+			/* it's only a warning because we might get this error if the
+			  network interface doesn't support multicasting -- andrei */
+		}
+		if (mcast_ttl>=0){
+			m_ttl=mcast_ttl;
+			if (setsockopt(sock_info->socket, IPPROTO_IP, IP_MULTICAST_TTL,
+						&m_ttl, sizeof(m_ttl))==-1){
+				LOG(L_WARN, "WARNING: udp_init: setsockopt (IP_MULTICAST_TTL):"
+						" %s\n", strerror(errno));
+			}
+		}
+#ifdef USE_IPV6
+	} else if (addr->s.sa_family==AF_INET6){
+		if (setsockopt(sock_info->socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 
+						&mcast_loopback, sizeof(mcast_loopback))==-1){
+			LOG(L_WARN, "WARNING: udp_init: setsockopt (IPV6_MULTICAST_LOOP):"
+					" %s\n", strerror(errno));
+		}
+		if (mcast_ttl>=0){
+			if (setsockopt(sock_info->socket, IPPROTO_IP, IPV6_MULTICAST_HOPS,
+							&mcast_ttl, sizeof(mcast_ttl))==-1){
+				LOG(L_WARN, "WARNING: udp_init: setssckopt "
+						"(IPV6_MULTICAST_HOPS): %s\n", strerror(errno));
+			}
+		}
+#endif /* USE_IPV6*/
+	} else {
+		LOG(L_ERR, "ERROR: udp_init: Unsupported protocol family %d\n",
+					addr->s.sa_family);
+		goto error;
+	}
 #endif /* USE_MCAST */
 
 	if ( probe_max_receive_buffer(sock_info->socket)==-1) goto error;