summaryrefslogtreecommitdiffstats
path: root/main/libc0.9.32/uClibc-0.9.33-avahi.patch
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2012-05-25 19:14:48 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2012-05-25 19:15:30 +0000
commit472f22263f5613910e7c8808d0accd1481a66f57 (patch)
treeaa38dbfe22e4691f866ead1510a6653551c1ef8d /main/libc0.9.32/uClibc-0.9.33-avahi.patch
parent49832f5ede2114d640ba939136243b18b8249a47 (diff)
downloadaports-472f22263f5613910e7c8808d0accd1481a66f57.tar.bz2
aports-472f22263f5613910e7c8808d0accd1481a66f57.tar.xz
main/libc0.9.32: add mDNS support via avahi-daemon
Diffstat (limited to 'main/libc0.9.32/uClibc-0.9.33-avahi.patch')
-rw-r--r--main/libc0.9.32/uClibc-0.9.33-avahi.patch418
1 files changed, 418 insertions, 0 deletions
diff --git a/main/libc0.9.32/uClibc-0.9.33-avahi.patch b/main/libc0.9.32/uClibc-0.9.33-avahi.patch
new file mode 100644
index 000000000..017ac5fef
--- /dev/null
+++ b/main/libc0.9.32/uClibc-0.9.33-avahi.patch
@@ -0,0 +1,418 @@
+From 5654318b39dae5e5a32e290849ec590cb85ee0b3 Mon Sep 17 00:00:00 2001
+Message-Id: <5654318b39dae5e5a32e290849ec590cb85ee0b3.1322557154.git.n.voss@weinmann.de>
+In-Reply-To: <cover.1322557154.git.n.voss@weinmann.de>
+References: <cover.1322557154.git.n.voss@weinmann.de>
+From: Nikolaus Voss <n.voss@weinmann.de>
+Date: Mon, 28 Nov 2011 16:18:30 +0100
+Subject: [PATCH 1/2] gethostbyaddr_r: add space for alias pointers
+To: uclibc@uclibc.org
+
+addr_list and alias where on the same buffer offset. This led
+to corrupt addr_list which was overwritten by the resolved name.
+
+Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
+---
+ libc/inet/resolv.c | 2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
+index 021d5bf..bc596b0 100644
+--- a/libc/inet/resolv.c
++++ b/libc/inet/resolv.c
+@@ -2402,6 +2402,8 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
+ */
+ #define in6 ((struct in6_addr *)in)
+ alias = (char **)buf;
++ buf += sizeof(alias) * 2;
++ buflen -= sizeof(alias) * 2;
+ addr_list = (struct in_addr**)buf;
+ buf += sizeof(*addr_list) * 2;
+ buflen -= sizeof(*addr_list) * 2;
+--
+1.7.5.4
+
+From 5388e302e40b12fb6682899dd4206f3e3d7a84fa Mon Sep 17 00:00:00 2001
+Message-Id: <5388e302e40b12fb6682899dd4206f3e3d7a84fa.1322557154.git.n.voss@weinmann.de>
+In-Reply-To: <cover.1322557154.git.n.voss@weinmann.de>
+References: <cover.1322557154.git.n.voss@weinmann.de>
+From: Nikolaus Voss <n.voss@weinmann.de>
+Date: Mon, 28 Nov 2011 16:22:42 +0100
+Subject: [PATCH 2/2] Make link-local addresses resolvable via running
+ avahi-daemon
+To: uclibc@uclibc.org
+
+nss-mdns is an extension to glibc to support resolution of link-local
+(.local) addresses via GNU Name Service Switch (NSS) which redirects
+the queries to a running avahi-daemon, which in turn does the resolution
+via multicast DNS (mdns).
+
+However, this does not work for uClibc, as it does not support NSS.
+
+This patch integrates the nss-mdns approach into uClibc's resolver,
+so getaddrinfo() and getnameinfo() calls get redirected to a running
+avahi-daemon before trying to resolve via unicast DNS.
+
+This increases the size of the library by 50 bytes on ARM.
+
+Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
+---
+ extra/Configs/Config.in | 19 +++
+ libc/inet/Makefile.in | 1 +
+ libc/inet/avahi.c | 183 ++++++++++++++++++++++
+ libc/inet/avahi.h | 33 ++++
+ libc/inet/resolv.c | 23 +++-
+ libc/sysdeps/linux/common/bits/kernel-features.h | 7 +-
+ 6 files changed, 259 insertions(+), 7 deletions(-)
+ create mode 100644 libc/inet/avahi.c
+ create mode 100644 libc/inet/avahi.h
+
+diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
+index e41adc4..6053a55 100644
+--- a/extra/Configs/Config.in
++++ b/extra/Configs/Config.in
+@@ -1268,6 +1268,25 @@ config UCLIBC_HAS_EXTRA_COMPAT_RES_STATE
+ Answer Y if selecting UCLIBC_HAS_COMPAT_RES_STATE is not enough.
+ As far as I can say, this should never be needed.
+
++config UCLIBC_HAS_AVAHI_RES
++ bool "Try to resolve link-local IP addresses via avahi-daemon"
++ default n
++ depends on UCLIBC_HAS_IPV4 || UCLIBC_HAS_IPV6
++ help
++ Answer Y if you want to resolve .local addresses via multicast-dns.
++ The queries are forwarded to a running avahi-daemon via a domain
++ socket interface.
++ Note that this might interfere with a .local domain on your DNS.
++ Answering N saves around 50 bytes.
++
++config UCLIBC_AVAHI_SOCKET_PATH
++ string "Path to avahi unix domain socket"
++ default "/var/run/avahi-daemon/socket"
++ depends on UCLIBC_HAS_AVAHI_RES
++ help
++ A running avahi-daemon creates a socket to listen for queries.
++ Enter the path you configured your avahi-daemon to.
++
+ config UCLIBC_HAS_LIBRESOLV_STUB
+ bool "Provide libresolv stub"
+ default n
+diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in
+index d588220..7f436c9 100644
+--- a/libc/inet/Makefile.in
++++ b/libc/inet/Makefile.in
+@@ -33,6 +33,7 @@ CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \
+ dnslookup.c opennameservers.c closenameservers.c \
+ getnameinfo.c \
+ gethostent.c gethostent_r.c
++CSRC-$(UCLIBC_HAS_AVAHI_RES) += avahi.c
+ CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \
+ get_hosts_byaddr_r.c get_hosts_byname_r.c \
+ gethostbyaddr_r.c gethostbyname_r.c gethostbyname2_r.c \
+diff --git a/libc/inet/avahi.c b/libc/inet/avahi.c
+new file mode 100644
+index 0000000..11ce055
+--- /dev/null
++++ b/libc/inet/avahi.c
+@@ -0,0 +1,183 @@
++/*
++ *
++ * (C) 2011 Weinmann GmbH, Hamburg, Germany
++ *
++ * Author: Nikolaus Voss <n.voss@weinmann.de>
++ *
++ * Derived from avahi.c / nss-mdns by Lennart Poettering.
++ * Copyright 2004-2007 Lennart Poettering <mzaffzqaf (at) 0pointer (dot) de>
++ *
++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
++ *
++ */
++
++#include <arpa/inet.h>
++#include <fcntl.h>
++#include <not-cancel.h>
++#include <stdio.h>
++#include <string.h>
++#include <sys/socket.h>
++#include <sys/types.h>
++#include <sys/un.h>
++#include <unistd.h>
++
++#include "avahi.h"
++
++#define WHITESPACE " \t"
++
++static FILE *avahi_open_socket(void)
++{
++ int fd;
++ struct sockaddr_un sa;
++ FILE *f;
++
++ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
++
++ if (fd < 0)
++ return NULL;
++
++#ifndef __ASSUME_SOCK_CLOEXEC
++ fcntl_not_cancel(fd, F_SETFD, FD_CLOEXEC);
++#endif
++
++ memset(&sa, 0, sizeof(sa));
++ sa.sun_family = AF_UNIX;
++ strncpy(sa.sun_path, __UCLIBC_AVAHI_SOCKET_PATH__,
++ sizeof(sa.sun_path) - 1);
++ sa.sun_path[sizeof(sa.sun_path) - 1] = 0;
++
++ if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0)
++ goto fail;
++
++ f = fdopen(fd, "r+");
++ if (!f)
++ goto fail;
++
++ return f;
++
++fail:
++ close(fd);
++
++ return NULL;
++}
++
++static int avahi_ends_with(const char *name, const char* suffix)
++{
++ size_t ln, ls;
++
++ if (!name || !suffix)
++ return 0;
++
++ if ((ls = strlen(suffix)) > (ln = strlen(name)))
++ return 0;
++
++ return strcasecmp(name + ln - ls, suffix) == 0;
++}
++
++int __avahi_resolve_name(int af, const char* name, void* data)
++{
++ FILE *f;
++ char *p;
++ int ret = -1;
++ char ln[256];
++
++ if (af != AF_INET && af != AF_INET6)
++ return ret;
++
++ if (!avahi_ends_with(name, ".local") &&
++ !avahi_ends_with(name, ".local."))
++ return ret;
++
++ f = avahi_open_socket();
++ if (!f)
++ return ret;
++
++ fprintf(f, "RESOLVE-HOSTNAME-IPV%d %s\n", af == AF_INET ? 4 : 6, name);
++ fflush(f);
++
++ if (!fgets(ln, sizeof(ln), f))
++ goto finish;
++
++ if (ln[0] != '+') {
++ ret = 1;
++ goto finish;
++ }
++
++ p = ln + 1;
++ p += strspn(p, WHITESPACE);
++
++ /* Skip interface */
++ p += strcspn(p, WHITESPACE);
++ p += strspn(p, WHITESPACE);
++
++ /* Skip protocol */
++ p += strcspn(p, WHITESPACE);
++ p += strspn(p, WHITESPACE);
++
++ /* Skip host name */
++ p += strcspn(p, WHITESPACE);
++ p += strspn(p, WHITESPACE);
++
++ /* Cut off end of line */
++ p[strcspn(p, "\n\r\t ")] = 0;
++
++ if (inet_pton(af, p, data) <= 0)
++ goto finish;
++
++ ret = 0;
++
++finish:
++ fclose(f);
++
++ return ret;
++}
++
++int __avahi_resolve_address(int af, const void *data, char* name,
++ size_t name_len)
++{
++ FILE *f;
++ char *p;
++ int ret = -1;
++ char a[256], ln[256];
++
++ if (af != AF_INET && af != AF_INET6)
++ return ret;
++
++ f = avahi_open_socket();
++ if (!f)
++ return ret;
++
++ fprintf(f, "RESOLVE-ADDRESS %s\n", inet_ntop(af, data, a, sizeof(a)));
++
++ if (!fgets(ln, sizeof(ln), f))
++ goto finish;
++
++ if (ln[0] != '+') {
++ ret = 1;
++ goto finish;
++ }
++
++ p = ln + 1;
++ p += strspn(p, WHITESPACE);
++
++ /* Skip interface */
++ p += strcspn(p, WHITESPACE);
++ p += strspn(p, WHITESPACE);
++
++ /* Skip protocol */
++ p += strcspn(p, WHITESPACE);
++ p += strspn(p, WHITESPACE);
++
++ /* Cut off end of line */
++ p[strcspn(p, "\n\r\t ")] = 0;
++
++ strncpy(name, p, name_len - 1);
++ name[name_len - 1] = 0;
++
++ ret = 0;
++
++finish:
++ fclose(f);
++
++ return ret;
++}
+diff --git a/libc/inet/avahi.h b/libc/inet/avahi.h
+new file mode 100644
+index 0000000..85df5f6
+--- /dev/null
++++ b/libc/inet/avahi.h
+@@ -0,0 +1,33 @@
++/*
++ *
++ * (C) 2011 Weinmann GmbH, Hamburg, Germany
++ *
++ * Author: Nikolaus Voss <n.voss@weinmann.de>
++ *
++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
++ *
++ */
++
++#ifndef _UCLIBC_AVAHI_H_
++#define _UCLIBC_AVAHI_H_
++
++#ifdef __UCLIBC_HAS_AVAHI_RES__
++int __avahi_resolve_name(int af, const char* name, void* data) attribute_hidden;
++
++int __avahi_resolve_address(int af, const void *data, char* name,
++ size_t name_len) attribute_hidden;
++#else
++static inline int __avahi_resolve_name(int af, const char* name, void* data)
++ attribute_hidden
++{
++ return 1;
++}
++
++static inline int __avahi_resolve_address(int af, const void *data, char* name,
++ size_t name_len) attribute_hidden
++{
++ return 1;
++}
++#endif
++
++#endif
+diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
+index bc596b0..2527b50 100644
+--- a/libc/inet/resolv.c
++++ b/libc/inet/resolv.c
+@@ -318,6 +318,7 @@ Domain name in a message can be represented as either:
+ #include <sys/stat.h>
+ #include <bits/uClibc_mutex.h>
+ #include "internal/parse_config.h"
++#include "avahi.h"
+
+ /* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is
+ * not available, we assume an old Linux kernel is in use and we will
+@@ -2073,10 +2074,11 @@ int gethostbyname_r(const char *name,
+ alias[0] = alias0;
+ alias[1] = NULL;
+
+- /* maybe it is already an address? */
++ /* maybe it is resolvable via avahi or already an address? */
+ {
+ struct in_addr *in = (struct in_addr *)(buf + sizeof(addr_list[0]) * 2);
+- if (inet_aton(name, in)) {
++ if (!__avahi_resolve_name(AF_INET, name, in) ||
++ inet_aton(name, in)) {
+ addr_list[0] = in;
+ addr_list[1] = NULL;
+ result_buf->h_name = alias0;
+@@ -2263,8 +2265,9 @@ int gethostbyname2_r(const char *name,
+ strncpy(buf, name, buflen);
+ buf[buflen] = '\0';
+
+- /* maybe it is already an address? */
+- if (inet_pton(AF_INET6, name, in)) {
++ /* maybe it is resolvable via avahi or already an address? */
++ if (!__avahi_resolve_name(AF_INET6, name, in) ||
++ inet_pton(AF_INET6, name, in)) {
+ result_buf->h_name = buf;
+ result_buf->h_addrtype = AF_INET6;
+ result_buf->h_length = sizeof(*in);
+@@ -2427,6 +2430,18 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
+ addr_list[1] = NULL;
+ memcpy(in, addr, addrlen);
+
++ /* is this a .local address? */
++ if (!__avahi_resolve_address(type, in, buf, buflen)) {
++ result_buf->h_name = buf;
++ result_buf->h_addrtype = type;
++ result_buf->h_length = addrlen;
++ result_buf->h_addr_list = (char **) addr_list;
++ result_buf->h_aliases = alias;
++ *result = result_buf;
++ *h_errnop = NETDB_SUCCESS;
++ return NETDB_SUCCESS;
++ }
++
+ if (0) /* nothing */;
+ #ifdef __UCLIBC_HAS_IPV4__
+ else IF_HAS_BOTH(if (type == AF_INET)) {
+diff --git a/libc/sysdeps/linux/common/bits/kernel-features.h b/libc/sysdeps/linux/common/bits/kernel-features.h
+index 6bf5544..a322334 100644
+--- a/libc/sysdeps/linux/common/bits/kernel-features.h
++++ b/libc/sysdeps/linux/common/bits/kernel-features.h
+@@ -310,11 +310,12 @@
+ #endif
+
+ /* Support for various CLOEXEC and NONBLOCK flags was added for x86,
+- * x86-64, PPC, IA-64, and SPARC in 2.6.27. */
++ * x86-64, PPC, IA-64, ARM and SPARC in 2.6.27. */
+ #if __LINUX_KERNEL_VERSION >= 0x02061b \
+ && (defined __i386__ || defined __x86_64__ || defined __powerpc__ \
+- || defined __ia64__ || defined __sparc__ || defined __s390__)
+-/* # define __ASSUME_SOCK_CLOEXEC 1 */
++ || defined __ia64__ || defined __sparc__ || defined __s390__ \
++ || defined __arm__)
++# define __ASSUME_SOCK_CLOEXEC 1
+ /* # define __ASSUME_IN_NONBLOCK 1 */
+ # define __ASSUME_PIPE2 1
+ /* # define __ASSUME_EVENTFD2 1 */
+--
+1.7.5.4
+