diff options
Diffstat (limited to 'main/libc0.9.32/0003-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch')
-rw-r--r-- | main/libc0.9.32/0003-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/main/libc0.9.32/0003-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch b/main/libc0.9.32/0003-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch deleted file mode 100644 index c1d14a8fc1..0000000000 --- a/main/libc0.9.32/0003-resolv-fix-resolver-to-return-TRY_AGAIN-on-timeout.patch +++ /dev/null @@ -1,266 +0,0 @@ -From ebe605c538137a070c0eb7294c171fd6e3658558 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 3/8] 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> -Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> ---- - 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 632bfaf..15065cf 100644 ---- a/libc/inet/resolv.c -+++ b/libc/inet/resolv.c -@@ -457,7 +457,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; -@@ -1234,7 +1235,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; -@@ -1266,11 +1268,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); -@@ -1338,8 +1344,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); -@@ -1347,8 +1355,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 */ -@@ -1474,7 +1484,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 -@@ -1486,7 +1496,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; -@@ -1565,8 +1575,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); -@@ -2107,9 +2116,8 @@ int gethostbyname_r(const char *name, - * we'll need space for 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; - } -@@ -2294,9 +2302,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); -@@ -2452,9 +2459,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; - } - -@@ -3730,7 +3736,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? */ -@@ -3756,14 +3762,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; -@@ -3828,19 +3833,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; -@@ -3848,21 +3843,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, -@@ -3896,13 +3899,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.8.4 - |