PERFORCE change 127249 for review
Fredrik Lindberg
fli at FreeBSD.org
Sat Oct 6 10:03:09 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=127249
Change 127249 by fli at 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;
More information about the p4-projects
mailing list