summaryrefslogtreecommitdiffstats
path: root/main/libc0.9.32
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2011-07-07 18:55:50 +0300
committerTimo Teräs <timo.teras@iki.fi>2011-07-07 18:55:50 +0300
commit0f57ae191874527c2543629f2a87df2865950ade (patch)
treef6ee486a21adcc3e782da1cd11035af31a2a30e2 /main/libc0.9.32
parent8c48da01414415a08c2d06ae76d50089078c26c0 (diff)
downloadaports-0f57ae191874527c2543629f2a87df2865950ade.tar.bz2
aports-0f57ae191874527c2543629f2a87df2865950ade.tar.xz
main/libc0.9.32: fix resolver to return TRY_AGAIN on timeout
This improves error handling for certain programs. E.g. postfix.
Diffstat (limited to 'main/libc0.9.32')
-rw-r--r--main/libc0.9.32/0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch265
-rw-r--r--main/libc0.9.32/APKBUILD4
2 files changed, 268 insertions, 1 deletions
diff --git a/main/libc0.9.32/0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch b/main/libc0.9.32/0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch
new file mode 100644
index 000000000..8d6af3deb
--- /dev/null
+++ b/main/libc0.9.32/0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch
@@ -0,0 +1,265 @@
+From f32b4d27b352724f28c7409490338929fc7ba58f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
+Date: Thu, 7 Jul 2011 18:47:26 +0300
+Subject: [PATCH] resolv: fix resolver to return TRY_AGAIN on timeout
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This fixes the internal __dns_lookup to get a h_errno pointer so
+it works nicely with the _r variants. Additionally the function is
+modified to permanent error if the static buffer lengths are not
+enough. And finally it fixed to return TRY_AGAIN if the nameservers
+timeout.
+
+res_search is fixed to continue searching if we receive TRY_AGAIN.
+It could be a problem with the specific search domain's server
+and not necessarily a problem in the recursive resolver we are
+querying. For same reason, it does not make sense to differentiate
+timeout or SERVFAIL error reply.
+
+The biggest issue this fixes is that we now properly set h_errno
+to TRY_AGAIN if upstream nameserver(s) timed out. Previously we
+would have returned NETDB_INTERNAL.
+
+Signed-off-by: Timo Teräs <timo.teras@iki.fi>
+---
+ libc/inet/resolv.c | 95 +++++++++++++++++++++++++++-------------------------
+ 1 files changed, 49 insertions(+), 46 deletions(-)
+
+diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
+index dc8a752..90ba31c 100644
+--- a/libc/inet/resolv.c
++++ b/libc/inet/resolv.c
+@@ -456,7 +456,8 @@ extern int __read_etc_hosts_r(parser_t *parser,
+ extern int __dns_lookup(const char *name,
+ int type,
+ unsigned char **outpacket,
+- struct resolv_answer *a) attribute_hidden;
++ struct resolv_answer *a,
++ int *h_errnop) attribute_hidden;
+ extern int __encode_dotted(const char *dotted,
+ unsigned char *dest,
+ int maxlen) attribute_hidden;
+@@ -1233,7 +1234,8 @@ static int __decode_answer(const unsigned char *message, /* packet */
+ int attribute_hidden __dns_lookup(const char *name,
+ int type,
+ unsigned char **outpacket,
+- struct resolv_answer *a)
++ struct resolv_answer *a,
++ int *h_errnop)
+ {
+ /* Protected by __resolv_lock: */
+ static int last_ns_num = 0;
+@@ -1265,11 +1267,15 @@ int attribute_hidden __dns_lookup(const char *name,
+ fd = -1;
+ lookup = NULL;
+ name_len = strlen(name);
+- if ((unsigned)name_len >= MAXDNAME - MAXLEN_searchdomain - 2)
+- goto fail; /* paranoia */
++ if ((unsigned)name_len >= MAXDNAME - MAXLEN_searchdomain - 2) {
++ *h_errnop = NO_RECOVERY;
++ goto fail1; /* paranoia */
++ }
+ lookup = malloc(name_len + 1/*for '.'*/ + MAXLEN_searchdomain + 1);
+- if (!packet || !lookup || !name[0])
+- goto fail;
++ if (!packet || !lookup || !name[0]) {
++ *h_errnop = NO_RECOVERY;
++ goto fail1;
++ }
+ ends_with_dot = (name[name_len - 1] == '.');
+ /* no strcpy! paranoia, user might change name[] under us */
+ memcpy(lookup, name, name_len);
+@@ -1337,8 +1343,10 @@ int attribute_hidden __dns_lookup(const char *name,
+ h.rd = 1;
+ DPRINTF("encoding header\n", h.rd);
+ i = __encode_header(&h, packet, PACKETSZ);
+- if (i < 0)
+- goto fail;
++ if (i < 0) {
++ *h_errnop = NO_RECOVERY;
++ goto fail1;
++ }
+
+ /* encode question */
+ DPRINTF("lookup name: %s\n", lookup);
+@@ -1346,8 +1354,10 @@ int attribute_hidden __dns_lookup(const char *name,
+ q.qtype = type;
+ q.qclass = C_IN; /* CLASS_IN */
+ j = __encode_question(&q, packet+i, PACKETSZ-i);
+- if (j < 0)
+- goto fail;
++ if (j < 0) {
++ *h_errnop = NO_RECOVERY;
++ goto fail1;
++ }
+ packet_len = i + j;
+
+ /* send packet */
+@@ -1473,7 +1483,7 @@ int attribute_hidden __dns_lookup(const char *name,
+ /* no more search domains to try */
+ }
+ /* dont loop, this is "no such host" situation */
+- h_errno = HOST_NOT_FOUND;
++ *h_errnop = HOST_NOT_FOUND;
+ goto fail1;
+ }
+ /* Insert other non-fatal errors here, which do not warrant
+@@ -1485,7 +1495,7 @@ int attribute_hidden __dns_lookup(const char *name,
+
+ /* Code below won't work correctly with h.ancount == 0, so... */
+ if (h.ancount <= 0) {
+- h_errno = NO_DATA; /* [is this correct code to check for?] */
++ *h_errnop = NO_DATA; /* [is this correct code to check for?] */
+ goto fail1;
+ }
+ pos = HFIXEDSZ;
+@@ -1562,8 +1572,7 @@ int attribute_hidden __dns_lookup(const char *name,
+ variant = -1;
+ } while (retries_left > 0);
+
+- fail:
+- h_errno = NETDB_INTERNAL;
++ *h_errnop = TRY_AGAIN;
+ fail1:
+ if (fd != -1)
+ close(fd);
+@@ -2104,9 +2113,8 @@ int gethostbyname_r(const char *name,
+ * we'll need space of one in_addr + two addr_list[] elems */
+ a.buflen = buflen - ((sizeof(addr_list[0]) * 2 + sizeof(struct in_addr)));
+ a.add_count = 0;
+- packet_len = __dns_lookup(name, T_A, &packet, &a);
++ packet_len = __dns_lookup(name, T_A, &packet, &a, h_errnop);
+ if (packet_len < 0) {
+- *h_errnop = HOST_NOT_FOUND;
+ DPRINTF("__dns_lookup returned < 0\n");
+ return TRY_AGAIN;
+ }
+@@ -2290,9 +2298,8 @@ int gethostbyname2_r(const char *name,
+ int packet_len;
+
+ /* Hmm why we memset(a) to zeros only once? */
+- packet_len = __dns_lookup(buf, T_AAAA, &packet, &a);
++ packet_len = __dns_lookup(buf, T_AAAA, &packet, &a, h_errnop);
+ if (packet_len < 0) {
+- *h_errnop = HOST_NOT_FOUND;
+ return TRY_AGAIN;
+ }
+ strncpy(buf, a.dotted, buflen);
+@@ -2448,9 +2455,8 @@ int gethostbyaddr_r(const void *addr, socklen_t addrlen,
+ memset(&a, '\0', sizeof(a));
+ for (;;) {
+ /* Hmm why we memset(a) to zeros only once? */
+- packet_len = __dns_lookup(buf, T_PTR, &packet, &a);
++ packet_len = __dns_lookup(buf, T_PTR, &packet, &a, h_errnop);
+ if (packet_len < 0) {
+- *h_errnop = HOST_NOT_FOUND;
+ return TRY_AGAIN;
+ }
+
+@@ -3089,7 +3095,7 @@ int res_query(const char *dname, int class, int type,
+ }
+
+ memset(&a, '\0', sizeof(a));
+- i = __dns_lookup(dname, type, &packet, &a);
++ i = __dns_lookup(dname, type, &packet, &a, &h_errno);
+
+ if (i < 0) {
+ if (!h_errno) /* TODO: can this ever happen? */
+@@ -3117,14 +3123,13 @@ libc_hidden_def(res_query)
+ */
+ #define __TRAILING_DOT (1<<0)
+ #define __GOT_NODATA (1<<1)
+-#define __GOT_SERVFAIL (1<<2)
++#define __GOT_TRYAGAIN (1<<2)
+ #define __TRIED_AS_IS (1<<3)
+ int res_search(const char *name, int class, int type, u_char *answer,
+ int anslen)
+ {
+ const char *cp;
+ char **domain;
+- HEADER *hp = (HEADER *)(void *)answer;
+ unsigned dots;
+ unsigned state;
+ int ret, saved_herrno;
+@@ -3189,19 +3194,9 @@ int res_search(const char *name, int class, int type, u_char *answer,
+ if (ret > 0)
+ return ret;
+
+- /*
+- * If no server present, give up.
+- * If name isn't found in this domain,
+- * keep trying higher domains in the search list
+- * (if that's enabled).
+- * On a NO_DATA error, keep trying, otherwise
+- * a wildcard entry of another type could keep us
+- * from finding this entry higher in the domain.
+- * If we get some other error (negative answer or
+- * server failure), then stop searching up,
+- * but try the input name below in case it's
+- * fully-qualified.
+- */
++ /* our resolver refused to talk to us -
++ * no sense to retry, as the retry would likely
++ * fail too */
+ if (errno == ECONNREFUSED) {
+ h_errno = TRY_AGAIN;
+ return -1;
+@@ -3209,21 +3204,29 @@ int res_search(const char *name, int class, int type, u_char *answer,
+
+ switch (h_errno) {
+ case NO_DATA:
++ /* Keep trying, otherwise a
++ * wildcard entry of another type
++ * could keep us from finding this
++ * entry from higher in the domain
++ * search. */
+ state |= __GOT_NODATA;
+- /* FALLTHROUGH */
++ break;
+ case HOST_NOT_FOUND:
+- /* keep trying */
++ /* Not found - keep trying higher
++ * domains in the search list. */
+ break;
+ case TRY_AGAIN:
+- if (hp->rcode == SERVFAIL) {
+- /* try next search element, if any */
+- state |= __GOT_SERVFAIL;
+- break;
+- }
+- /* FALLTHROUGH */
++ /* Server error or timeout. Could
++ * be caused by a problem in servers
++ * our resolver queried. Keep trying
++ * search, but remember that there
++ * was a temporary problem. */
++ state |= __GOT_TRYAGAIN;
++ break;
+ default:
+ /* anything else implies that we're done */
+ done = 1;
++ break;
+ }
+ /*
+ * if we got here for some reason other than DNSRCH,
+@@ -3257,13 +3260,13 @@ int res_search(const char *name, int class, int type, u_char *answer,
+ h_errno = saved_herrno;
+ else if (state & __GOT_NODATA)
+ h_errno = NO_DATA;
+- else if (state & __GOT_SERVFAIL)
++ else if (state & __GOT_TRYAGAIN)
+ h_errno = TRY_AGAIN;
+ return -1;
+ }
+ #undef __TRAILING_DOT
+ #undef __GOT_NODATA
+-#undef __GOT_SERVFAIL
++#undef __GOT_TRYAGAIN
+ #undef __TRIED_AS_IS
+ /*
+ * Perform a call on res_query on the concatenation of name and domain,
+--
+1.7.1
+
diff --git a/main/libc0.9.32/APKBUILD b/main/libc0.9.32/APKBUILD
index e55ff220c..d812dddbe 100644
--- a/main/libc0.9.32/APKBUILD
+++ b/main/libc0.9.32/APKBUILD
@@ -4,7 +4,7 @@ pkgname=libc$_abiver
_gitver=
pkgver=0.9.32
_ver=${pkgver/_/-}
-pkgrel=0
+pkgrel=1
pkgdesc="C library for developing embedded Linux systems"
url=http://uclibc.org
license="LGPL-2"
@@ -22,6 +22,7 @@ _snapfile="$pkgname-$pkgver.tar.bz2"
source="http://uclibc.org/downloads/uClibc-${_ver}.tar.bz2
compat-stack-guard.patch
uclibc-resolv-cname-fix.diff
+ 0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch
0001-libm-x86_64-implement-fesetround.patch
0001-ldso-limited-support-for-ORIGIN-in-rpath.patch
0002-stdlib-fix-arc4random-return-type-to-u_int32_t.patch
@@ -129,6 +130,7 @@ libthread_db() {
md5sums="cfcb6c25d8ebe12817499d8749ee8ae1 uClibc-0.9.32.tar.bz2
a9bfb77ea7dc5fb9abf4d4b19201c614 compat-stack-guard.patch
5d6e3e382b66f59cfd7242a4fe453f98 uclibc-resolv-cname-fix.diff
+08f31006426a0fca561f262f36bcfb01 0001-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch
e0c901502602f7e9e002d910d0f32ab9 0001-libm-x86_64-implement-fesetround.patch
bc164e262c5feab55c800780704fa71c 0001-ldso-limited-support-for-ORIGIN-in-rpath.patch
b4fb68ad3d0e8331b1b40c30eb21dfdc 0002-stdlib-fix-arc4random-return-type-to-u_int32_t.patch