Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Oct 2007 17:03:08 GMT
From:      Fredrik Lindberg <fli@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 127249 for review
Message-ID:  <200710061703.l96H38Ng006915@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=127249

Change 127249 by fli@fli_nexus on 2007/10/06 17:02:43

	- Add missing IPV6_MULTICAST_LOOP socket option.
	- Fix broken ipv6 initialization. 
	- Use unsigned int to hold interface index.
	- Some error conditions didn't release the read-lock properly.
	- Properly loop through all ancillary data items during receive
	  instead of asuming that the item we want is the first.
	- Add a few new debugging printouts and nuke some useless code.

Affected files ...

.. //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_mdns.c#8 edit

Differences ...

==== //depot/projects/soc2007/fli-mdns_sd/mdnsd/stack_mdns.c#8 (text+ko) ====

@@ -70,7 +70,8 @@
 {
 	struct ifreq req;
 	struct ifaddrs *ifap, *ifa;
-	int error, idx, i, sock;
+	int error, i, sock;
+	unsigned int idx;
 	size_t len;
 
 	bzero(md, sizeof(struct mdns));
@@ -313,6 +314,12 @@
 		    sizeof(so));
 		if (error != 0)
 			goto out;
+		/* Ignore our own multicast packets */
+		so = 0;
+		error = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &so,
+		    sizeof(so));
+		if (error != 0)
+			goto out;
 		/* Make sure we transmit on the correct interface */
 		so = md->md_ifindex;
 		error = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &so,
@@ -330,8 +337,8 @@
 		if (error != 0)
 			goto out;
 
-		bzero(&md->md_sin6, sizeof(struct sockaddr_in));
-		inet_pton(PF_INET6, MDNS_MCAST_INET6, &sin6.sin6_addr);
+		bzero(&md->md_sin6, sizeof(struct sockaddr_in6));
+		inet_pton(PF_INET6, MDNS_MCAST_INET6, &md->md_sin6.sin6_addr);
 		md->md_sin6.sin6_family = AF_INET6;
 		md->md_sin6.sin6_port = htons(MDNS_MCAST_PORT);
 
@@ -692,9 +699,10 @@
 		goto out;
 	}
 
+	dprintf(DEBUG_STACK, "Sending packet chain pc=%p, fam=%d", pc, family);
 	error = write_pkgchain(sock, pc, sa, salen);
+out:
 	RW_UNLOCK(md, md_lock);
-out:
 	return (error);
 }
 
@@ -729,10 +737,13 @@
 		goto out;
 	}
 	
+	dprintf(DEBUG_STACK, "Sending (unicast) packet chain pc=%p, fam=%d",
+	    pc, sa->sa_family);
 	error = write_pkgchain(sock, pc, sa, salen);
 	RW_UNLOCK(md, md_lock);
 	return (error);
 out:
+	RW_UNLOCK(md, md_lock);
 	return (-1);
 }
 
@@ -748,7 +759,7 @@
 mdns_recv(struct mdns *md, struct mdns_pkgchain *pc, int family,
 	struct sockaddr *from, socklen_t *fromlen)
 {
-	int sock;
+	int sock, valid;
 	ssize_t ret;
 	struct mdns_packet *pkg;
 	struct mdns_buf *buf;
@@ -813,21 +824,34 @@
 	dprintf(DEBUG_STACK, "Buffer filled %d bytes (size %d)",
 	    MDNS_BUFLEN(buf), MDNS_BUFSZ(buf));
 
-	cmptr = CMSG_FIRSTHDR(&msg);
-	if (cmptr->cmsg_level == IPPROTO_IP) {
-		if (cmptr->cmsg_type == IP_RECVIF) {
+	valid = 0;
+	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
+	    cmptr = CMSG_NXTHDR(&msg, cmptr)) {
+		if (cmptr->cmsg_level == IPPROTO_IP &&
+		    cmptr->cmsg_type == IP_RECVIF) {
 			sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
-			if (sdl->sdl_index != md->md_ifindex)
-				goto error;
+			if (sdl->sdl_index == md->md_ifindex) {
+				valid = 1;
+				break;
+			}
+		}
+#ifdef INET6
+		else if (cmptr->cmsg_level == IPPROTO_IPV6 &&
+		    cmptr->cmsg_type == IPV6_PKTINFO) {
+			ipi6 = (struct in6_pktinfo *) CMSG_DATA(cmptr);
+			if (ipi6->ipi6_ifindex == md->md_ifindex) {
+				valid = 1;
+				break;
+			}
 		}
+#endif
 	}
-#ifdef INET6
-	else if (cmptr->cmsg_level == IPPROTO_IPV6) {
-		ipi6 = (struct in6_pktinfo *) CMSG_DATA(cmptr);
-		if (ipi6->ipi6_ifindex != (unsigned int)md->md_ifindex)
-			goto error;
+
+	if (!valid) {
+		dprintf(DEBUG_STACK,
+		    "Unable to determine incoming interface (packet ignored)");
+		goto error;
 	}
-#endif
 
 	RW_UNLOCK(md, md_lock);
 	return (pkg->p_len);
@@ -989,15 +1013,10 @@
  *   0 on success, non-zero on failure
  */
 static int
-mcast_memberctl(int sock, int ifidx, int family, int what)
+mcast_memberctl(int sock, unsigned int ifidx, int family, int what)
 {
 	int error;
 
-	if (ifidx < 0) {
-		errno = EINVAL;
-		return (-1);
-	}
-
 	switch (family) {
 	case PF_INET: {
 		struct ip_mreq mreq;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200710061703.l96H38Ng006915>