From ba8547ee3f34d8fe7bedb559530b2c0374f2089c Mon Sep 17 00:00:00 2001 From: Trent Lloyd Date: Mon, 25 Apr 2005 18:48:57 +0000 Subject: [PATCH] * Import fixes to multicast code to IP_ADD_MEMBERSHIP per interface, rather than a 'global' one, which didn't really work. -- Trent Lloyd git-svn-id: file:///home/lennart/svn/public/avahi/trunk@31 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- iface.c | 14 ++++++- socket.c | 122 +++++++++++++++++++++++++++++++++++++++---------------- socket.h | 6 +++ 3 files changed, 107 insertions(+), 35 deletions(-) diff --git a/iface.c b/iface.c index 0afdb70..c1dec19 100644 --- a/iface.c +++ b/iface.c @@ -155,6 +155,7 @@ static void new_interface(flxInterfaceMonitor *m, flxHwInterface *hw, guchar pro static void check_interface_relevant(flxInterfaceMonitor *m, flxInterface *i) { gboolean b; + g_assert(m); g_assert(i); @@ -163,13 +164,24 @@ static void check_interface_relevant(flxInterfaceMonitor *m, flxInterface *i) { if (b && !i->announcing) { g_message("New relevant interface %s.%i", i->hardware->name, i->protocol); + if (i->protocol == AF_INET) + flx_mdns_mcast_join_ipv4 (i->hardware->index, m->server->fd_ipv4); + if (i->protocol == AF_INET6) + flx_mdns_mcast_join_ipv6 (i->hardware->index, m->server->fd_ipv6); + i->announcing = TRUE; flx_announce_interface(m->server, i); } else if (!b && i->announcing) { g_message("Interface %s.%i no longer relevant", i->hardware->name, i->protocol); - i->announcing = FALSE; flx_goodbye_interface(m->server, i, FALSE); + + if (i->protocol == AF_INET) + flx_mdns_mcast_leave_ipv4 (i->hardware->index, m->server->fd_ipv4); + if (i->protocol == AF_INET6) + flx_mdns_mcast_leave_ipv6 (i->hardware->index, m->server->fd_ipv6); + + i->announcing = FALSE; } } diff --git a/socket.c b/socket.c index 54433d6..e6cf40f 100644 --- a/socket.c +++ b/socket.c @@ -26,12 +26,97 @@ static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) { inet_pton(AF_INET, "224.0.0.251", &ret_sa->sin_addr); } +static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) { + + g_assert(ret_sa); + + memset(ret_sa, 0, sizeof(struct sockaddr_in6)); + + ret_sa->sin6_family = AF_INET6; + ret_sa->sin6_port = htons(MDNS_PORT); + inet_pton(AF_INET6, "ff02::fb", &ret_sa->sin6_addr); +} + +int flx_mdns_mcast_join_ipv4 (int index, int fd) +{ + struct ip_mreqn mreq; + struct sockaddr_in sa; + + mdns_mcast_group_ipv4 (&sa); + + memset(&mreq, 0, sizeof(mreq)); + mreq.imr_multiaddr = sa.sin_addr; + mreq.imr_ifindex = index; + + if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { + g_warning("IP_ADD_MEMBERSHIP failed: %s\n", strerror(errno)); + return 0; + } else { + return -1; + } +} + +int flx_mdns_mcast_join_ipv6 (int index, int fd) +{ + struct ipv6_mreq mreq6; + struct sockaddr_in6 sa6; + + + mdns_mcast_group_ipv6 (&sa6); + + memset(&mreq6, 0, sizeof(mreq6)); + mreq6.ipv6mr_multiaddr = sa6.sin6_addr; + mreq6.ipv6mr_interface = index; + + if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { + g_warning("IPV6_ADD_MEMBERSHIP failed: %s\n", strerror(errno)); + return 0; + } else { + return -1; + } +} + +int flx_mdns_mcast_leave_ipv4 (int index, int fd) +{ + struct ip_mreqn mreq; + struct sockaddr_in sa; + + mdns_mcast_group_ipv4 (&sa); + + memset(&mreq, 0, sizeof(mreq)); + mreq.imr_multiaddr = sa.sin_addr; + mreq.imr_ifindex = index; + + if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { + g_warning("IP_DROP_MEMBERSHIP failed: %s\n", strerror(errno)); + return 0; + } else { + return -1; + } +} + +int flx_mdns_mcast_leave_ipv6 (int index, int fd) +{ + struct ipv6_mreq mreq6; + struct sockaddr_in6 sa6; + + mdns_mcast_group_ipv6 (&sa6); + + memset(&mreq6, 0, sizeof(mreq6)); + mreq6.ipv6mr_multiaddr = sa6.sin6_addr; + mreq6.ipv6mr_interface = index; + + if (setsockopt(fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { + g_warning("IPV6_DROP_MEMBERSHIP failed: %s\n", strerror(errno)); + return 0; + } else { + return -1; + } +} + gint flx_open_socket_ipv4(void) { - struct ip_mreqn mreq; struct sockaddr_in sa, local; int fd = -1, ttl, yes; - - mdns_mcast_group_ipv4(&sa); if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { g_warning("socket() failed: %s\n", strerror(errno)); @@ -72,16 +157,6 @@ gint flx_open_socket_ipv4(void) { goto fail; } - memset(&mreq, 0, sizeof(mreq)); - mreq.imr_multiaddr = sa.sin_addr; - mreq.imr_address.s_addr = htonl(INADDR_ANY); - mreq.imr_ifindex = 0; - - if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - g_warning("IP_ADD_MEMBERSHIP failed: %s\n", strerror(errno)); - goto fail; - } - yes = 1; if (setsockopt(fd, SOL_IP, IP_RECVTTL, &yes, sizeof(yes)) < 0) { g_warning("IP_RECVTTL failed: %s\n", strerror(errno)); @@ -113,19 +188,7 @@ fail: return -1; } -static void mdns_mcast_group_ipv6(struct sockaddr_in6 *ret_sa) { - g_assert(ret_sa); - - memset(ret_sa, 0, sizeof(struct sockaddr_in6)); - - ret_sa->sin6_family = AF_INET6; - ret_sa->sin6_port = htons(MDNS_PORT); - inet_pton(AF_INET6, "ff02::fb", &ret_sa->sin6_addr); -} - - gint flx_open_socket_ipv6(void) { - struct ipv6_mreq mreq; struct sockaddr_in6 sa, local; int fd = -1, ttl, yes; @@ -175,15 +238,6 @@ gint flx_open_socket_ipv6(void) { goto fail; } - memset(&mreq, 0, sizeof(mreq)); - mreq.ipv6mr_multiaddr = sa.sin6_addr; - mreq.ipv6mr_interface = 0; - - if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - g_warning("IPV6_ADD_MEMBERSHIP failed: %s\n", strerror(errno)); - goto fail; - } - yes = 1; if (setsockopt(fd, SOL_IPV6, IPV6_HOPLIMIT, &yes, sizeof(yes)) < 0) { g_warning("IPV6_HOPLIMIT failed: %s\n", strerror(errno)); diff --git a/socket.h b/socket.h index eb7013a..61d17a5 100644 --- a/socket.h +++ b/socket.h @@ -14,4 +14,10 @@ gint flx_send_dns_packet_ipv6(gint fd, gint iface, flxDnsPacket *p); flxDnsPacket *flx_recv_dns_packet_ipv4(gint fd, struct sockaddr_in*ret_sa, gint *ret_iface, guint8 *ret_ttl); flxDnsPacket *flx_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6*ret_sa, gint *ret_iface, guint8 *ret_ttl); +int flx_mdns_mcast_join_ipv4(int index, int fd); +int flx_mdns_mcast_join_ipv6(int index, int fd); + +int flx_mdns_mcast_leave_ipv4(int index, int fd); +int flx_mdns_mcast_leave_ipv6(int index, int fd); + #endif -- 2.39.5