X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-core%2Fsocket.c;h=70074525004004d41f3f9f4597205f25d75aed8d;hb=fd84f9ae1c1ccaf7090e0b4f8876948bea040117;hp=b9e1b71ff3b385f4d2b1b55317ffcc191aa1e2dd;hpb=26358a4c4a8ae0ca68f08054e367aa3687681445;p=catta diff --git a/avahi-core/socket.c b/avahi-core/socket.c index b9e1b71..7007452 100644 --- a/avahi-core/socket.c +++ b/avahi-core/socket.c @@ -424,13 +424,19 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, ssize_t l; struct cmsghdr *cmsg; gboolean found_ttl = FALSE, found_iface = FALSE; + guint ms; g_assert(fd >= 0); g_assert(ret_sa); g_assert(ret_iface); g_assert(ret_ttl); - p = avahi_dns_packet_new(0); + if (ioctl(fd, FIONREAD, &ms) < 0) { + g_warning("ioctl(): %s", strerror(errno)); + goto fail; + } + + p = avahi_dns_packet_new(ms + AVAHI_DNS_PACKET_EXTRA_SIZE); io.iov_base = AVAHI_DNS_PACKET_DATA(p); io.iov_len = p->max_size; @@ -445,12 +451,16 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv4(gint fd, struct sockaddr_in *ret_sa, msg.msg_flags = 0; if ((l = recvmsg(fd, &msg, 0)) < 0) { - g_warning("recvmsg(): %s\n", strerror(errno)); + g_warning("recvmsg(): %s", strerror(errno)); goto fail; } if (ret_sa->sin_addr.s_addr == INADDR_ANY) { /* Linux 2.4 behaves very strangely sometimes! */ + + avahi_hexdump(AVAHI_DNS_PACKET_DATA(p), l); + + goto fail; } @@ -498,6 +508,8 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, struct iovec io; uint8_t aux[64]; ssize_t l; + guint ms; + struct cmsghdr *cmsg; gboolean found_ttl = FALSE, found_iface = FALSE; @@ -506,7 +518,12 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, g_assert(ret_iface); g_assert(ret_ttl); - p = avahi_dns_packet_new(0); + if (ioctl(fd, FIONREAD, &ms) < 0) { + g_warning("ioctl(): %s", strerror(errno)); + goto fail; + } + + p = avahi_dns_packet_new(ms + AVAHI_DNS_PACKET_EXTRA_SIZE); io.iov_base = AVAHI_DNS_PACKET_DATA(p); io.iov_len = p->max_size; @@ -520,8 +537,10 @@ AvahiDnsPacket* avahi_recv_dns_packet_ipv6(gint fd, struct sockaddr_in6 *ret_sa, msg.msg_controllen = sizeof(aux); msg.msg_flags = 0; - if ((l = recvmsg(fd, &msg, 0)) < 0) + if ((l = recvmsg(fd, &msg, 0)) < 0) { + g_warning("recvmsg(): %s", strerror(errno)); goto fail; + } p->size = (size_t) l; @@ -551,3 +570,98 @@ fail: return NULL; } +gint avahi_open_legacy_unicast_socket_ipv4(void) { + struct sockaddr_in local; + int fd = -1, yes; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + g_warning("socket() failed: %s\n", strerror(errno)); + goto fail; + } + + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + + if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) { + g_warning("bind() 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)); + goto fail; + } + + yes = 1; + if (setsockopt(fd, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0) { + g_warning("IP_PKTINFO failed: %s\n", strerror(errno)); + goto fail; + } + + if (avahi_set_cloexec(fd) < 0) { + g_warning("FD_CLOEXEC failed: %s\n", strerror(errno)); + goto fail; + } + + if (avahi_set_nonblock(fd) < 0) { + g_warning("O_NONBLOCK failed: %s\n", strerror(errno)); + goto fail; + } + + return fd; + +fail: + if (fd >= 0) + close(fd); + + return -1; +} + +gint avahi_open_legacy_unicast_socket_ipv6(void) { + struct sockaddr_in local; + int fd = -1, yes; + + if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + g_warning("socket() failed: %s\n", strerror(errno)); + goto fail; + } + + memset(&local, 0, sizeof(local)); + local.sin_family = AF_INET; + + if (bind(fd, (struct sockaddr*) &local, sizeof(local)) < 0) { + g_warning("bind() 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)); + goto fail; + } + + yes = 1; + if (setsockopt(fd, SOL_IPV6, IPV6_PKTINFO, &yes, sizeof(yes)) < 0) { + g_warning("IPV6_PKTINFO failed: %s\n", strerror(errno)); + goto fail; + } + + if (avahi_set_cloexec(fd) < 0) { + g_warning("FD_CLOEXEC failed: %s\n", strerror(errno)); + goto fail; + } + + if (avahi_set_nonblock(fd) < 0) { + g_warning("O_NONBLOCK failed: %s\n", strerror(errno)); + goto fail; + } + + return fd; + +fail: + if (fd >= 0) + close(fd); + + return -1; +}