summaryrefslogtreecommitdiff
path: root/resolv/res_query.c
diff options
context:
space:
mode:
Diffstat (limited to 'resolv/res_query.c')
-rw-r--r--resolv/res_query.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 85bad97d2d..4371af5b05 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -120,10 +120,13 @@ __libc_res_nquery(res_state statp,
u_char *buf;
HEADER *hp = (HEADER *) answer;
int n, use_malloc = 0;
+ u_int oflags = statp->_flags;
- hp->rcode = NOERROR; /* default */
+ size_t bufsize = QUERYSIZE;
+ buf = alloca (bufsize);
- buf = alloca (QUERYSIZE);
+ again:
+ hp->rcode = NOERROR; /* default */
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -131,18 +134,30 @@ __libc_res_nquery(res_state statp,
#endif
n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
- buf, QUERYSIZE);
- if (__builtin_expect (n <= 0, 0)) {
+ buf, bufsize);
+ if (n > 0
+ && (oflags & RES_F_EDNS0ERR) == 0
+ && (statp->options & RES_USE_EDNS0) != 0)
+ n = __res_nopt(statp, n, buf, bufsize, anslen);
+ if (__builtin_expect (n <= 0, 0) && !use_malloc) {
/* Retry just in case res_nmkquery failed because of too
short buffer. Shouldn't happen. */
- buf = malloc (MAXPACKET);
+ bufsize = MAXPACKET;
+ buf = malloc (bufsize);
if (buf != NULL) {
use_malloc = 1;
- n = res_nmkquery(statp, QUERY, name, class, type, NULL,
- 0, NULL, buf, MAXPACKET);
+ goto again;
}
}
if (__builtin_expect (n <= 0, 0)) {
+ /* If the query choked with EDNS0, retry without EDNS0. */
+ if ((statp->options & RES_USE_EDNS0) != 0
+ && ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
+ statp->_flags |= RES_F_EDNS0ERR;
+ if (statp->options & RES_DEBUG)
+ printf(";; res_nquery: retry without EDNS0\n");
+ goto again;
+ }
#ifdef DEBUG
if (statp->options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");