mdns_mcast_group_ipv4(&sa);
mreq.imr_multiaddr = sa.sin_addr;
+ /* Some network drivers have issues with dropping membership of
+ * mcast groups when the iface is down, but don't allow rejoining
+ * when it comes back up. This is an ugly workaround */
+ if (join)
+ setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
+
if (setsockopt(fd, IPPROTO_IP, join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
avahi_log_warn("%s failed: %s", join ? "IP_ADD_MEMBERSHIP" : "IP_DROP_MEMBERSHIP", strerror(errno));
return -1;
mreq6.ipv6mr_multiaddr = sa6.sin6_addr;
mreq6.ipv6mr_interface = idx;
+ if (join)
+ setsockopt(fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6));
+
if (setsockopt(fd, IPPROTO_IPV6, join ? IPV6_ADD_MEMBERSHIP : IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
avahi_log_warn("%s failed: %s", join ? "IPV6_ADD_MEMBERSHIP" : "IPV6_DROP_MEMBERSHIP", strerror(errno));
return -1;
struct iovec io;
#ifdef IP_PKTINFO
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_pktinfo))];
+ size_t cmsg_data[( CMSG_SPACE(sizeof(struct in_pktinfo)) / sizeof(size_t)) + 1];
#elif defined(IP_SENDSRCADDR)
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in_addr))];
+ size_t cmsg_data[( CMSG_SPACE(sizeof(struct in_addr)) / sizeof(size_t)) + 1];
#endif
assert(fd >= 0);
struct msghdr msg;
struct iovec io;
struct cmsghdr *cmsg;
- uint8_t cmsg_data[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+ size_t cmsg_data[(CMSG_SPACE(sizeof(struct in6_pktinfo))/sizeof(size_t)) + 1];
assert(fd >= 0);
assert(p);
AvahiDnsPacket *p= NULL;
struct msghdr msg;
struct iovec io;
- uint8_t aux[1024];
+ size_t aux[1024 / sizeof(size_t)]; /* for alignment on ia64 ! */
ssize_t l;
struct cmsghdr *cmsg;
int found_addr = 0;
AvahiDnsPacket *p = NULL;
struct msghdr msg;
struct iovec io;
- uint8_t aux[64];
+ size_t aux[1024 / sizeof(size_t)];
ssize_t l;
int ms;
struct cmsghdr *cmsg;