From 472f22263f5613910e7c8808d0accd1481a66f57 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 25 May 2012 19:14:48 +0000 Subject: main/libc0.9.32: add mDNS support via avahi-daemon --- main/libc0.9.32/APKBUILD | 11 +- main/libc0.9.32/uClibc-0.9.33-avahi.patch | 418 ++++++++++++++++++++++++++++++ main/libc0.9.32/uclibcconfig.x86 | 8 +- main/libc0.9.32/uclibcconfig.x86_64 | 8 +- 4 files changed, 434 insertions(+), 11 deletions(-) create mode 100644 main/libc0.9.32/uClibc-0.9.33-avahi.patch (limited to 'main/libc0.9.32') diff --git a/main/libc0.9.32/APKBUILD b/main/libc0.9.32/APKBUILD index 53c79e9ce..9f17732df 100644 --- a/main/libc0.9.32/APKBUILD +++ b/main/libc0.9.32/APKBUILD @@ -4,7 +4,7 @@ pkgname=libc$_abiver _gitver= pkgver=0.9.33.2 _ver=${pkgver/_/-} -pkgrel=1 +pkgrel=2 pkgdesc="C library for developing embedded Linux systems" url=http://uclibc.org license="LGPL-2" @@ -33,7 +33,7 @@ source="http://uclibc.org/downloads/uClibc-${_ver}.tar.xz 0007-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch 0008-ldso-limited-support-for-ORIGIN-in-rpath.patch eventfd.patch - +uClibc-0.9.33-avahi.patch uclibcconfig.x86 uclibcconfig.x86_64 @@ -137,9 +137,10 @@ d8e62f8016274fc8605e6f77d4def79e 0005-stdlib-fix-arc4random-return-type-to-u_in d9611de57fb72b74c0b9e243b8e9165b 0007-libc-x86-fix-stack-unwinding-and-backtrace-informati.patch 12cf5330b092ee7e00d14909737abc70 0008-ldso-limited-support-for-ORIGIN-in-rpath.patch a86eb40e8aca531a1cfee5faff3c53d4 eventfd.patch -20bfe471ee26f613834ebab0f68af28f uclibcconfig.x86 -b1207627da796c653dda93ec261a72fa uclibcconfig.x86_64 -20bfe471ee26f613834ebab0f68af28f uclibcconfig.i486 +d91fcb785ae14632a4ea8fa03ba0236f uClibc-0.9.33-avahi.patch +ce8a33a31f5a53031fbad8b1d1b66d44 uclibcconfig.x86 +e861a17baa541accf4d4d39a98d74c32 uclibcconfig.x86_64 +ce8a33a31f5a53031fbad8b1d1b66d44 uclibcconfig.i486 3f1e788cfa922c5a39d22a509bf49b60 uclibcconfig.arm 820d5176004ccfa2baa3607ba576360f uclibcconfig.powerpc f3be4f2bc54d7561d252937e10abf0d2 uclibc-utils.trigger" 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: +References: +From: Nikolaus Voss +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 +--- + 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: +References: +From: Nikolaus Voss +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 +--- + 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 ++ * ++ * Derived from avahi.c / nss-mdns by Lennart Poettering. ++ * Copyright 2004-2007 Lennart Poettering ++ * ++ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ * ++ * 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 + #include + #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 + diff --git a/main/libc0.9.32/uclibcconfig.x86 b/main/libc0.9.32/uclibcconfig.x86 index 6f3a1b58e..84323ff7a 100644 --- a/main/libc0.9.32/uclibcconfig.x86 +++ b/main/libc0.9.32/uclibcconfig.x86 @@ -1,12 +1,13 @@ # # Automatically generated make config: don't edit -# Version: 0.9.33 -# Mon Feb 6 07:27:05 2012 +# Version: 0.9.33.2 +# Fri May 25 19:11:31 2012 # # TARGET_alpha is not set # TARGET_arm is not set # TARGET_avr32 is not set # TARGET_bfin is not set +# TARGET_c6x is not set # TARGET_cris is not set # TARGET_e1 is not set # TARGET_frv is not set @@ -28,7 +29,6 @@ TARGET_i386=y # TARGET_vax is not set # TARGET_x86_64 is not set # TARGET_xtensa is not set -# TARGET_c6x is not set # # Target Architecture Features and Options @@ -169,6 +169,8 @@ UCLIBC_HAS_BSD_RES_CLOSE=y UCLIBC_HAS_COMPAT_RES_STATE=y # UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set UCLIBC_HAS_RESOLVER_SUPPORT=y +UCLIBC_HAS_AVAHI_RES=y +UCLIBC_AVAHI_SOCKET_PATH="/var/run/avahi-daemon/socket" UCLIBC_HAS_LIBRESOLV_STUB=y # UCLIBC_HAS_LIBNSL_STUB is not set diff --git a/main/libc0.9.32/uclibcconfig.x86_64 b/main/libc0.9.32/uclibcconfig.x86_64 index d2930ffe3..b03ad9902 100644 --- a/main/libc0.9.32/uclibcconfig.x86_64 +++ b/main/libc0.9.32/uclibcconfig.x86_64 @@ -1,12 +1,13 @@ # # Automatically generated make config: don't edit -# Version: 0.9.33 -# Mon Feb 6 07:27:05 2012 +# Version: 0.9.33.2 +# Fri May 25 19:11:31 2012 # # TARGET_alpha is not set # TARGET_arm is not set # TARGET_avr32 is not set # TARGET_bfin is not set +# TARGET_c6x is not set # TARGET_cris is not set # TARGET_e1 is not set # TARGET_frv is not set @@ -28,7 +29,6 @@ # TARGET_vax is not set TARGET_x86_64=y # TARGET_xtensa is not set -# TARGET_c6x is not set # # Target Architecture Features and Options @@ -152,6 +152,8 @@ UCLIBC_HAS_BSD_RES_CLOSE=y UCLIBC_HAS_COMPAT_RES_STATE=y # UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set UCLIBC_HAS_RESOLVER_SUPPORT=y +UCLIBC_HAS_AVAHI_RES=y +UCLIBC_AVAHI_SOCKET_PATH="/var/run/avahi-daemon/socket" UCLIBC_HAS_LIBRESOLV_STUB=y # UCLIBC_HAS_LIBNSL_STUB is not set -- cgit v1.2.3