aboutsummaryrefslogtreecommitdiff
path: root/resolv/res_query.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-02-09 23:46:29 +0000
committerUlrich Drepper <drepper@redhat.com>2007-02-09 23:46:29 +0000
commit2bbb7d5b3c517956e95e5827037a76cbc39a20c8 (patch)
treee5d2f14edf74a9e9992ebe907e5feffd9dca7c7e /resolv/res_query.c
parent00458b5bee15b31f90bca83c79f29e168f04ecc8 (diff)
downloadglibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.tar
glibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.tar.gz
glibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.tar.bz2
glibc-2bbb7d5b3c517956e95e5827037a76cbc39a20c8.zip
* resolv/res_init.c (res_setoptions): Recognize edns0 option.
* resolv/res_mkquery.c: Define __res_nopt. * resolv/res_query.c (__libc_res_nquery): If RES_USE_EDNS0 is set try adding EDNS0 record. * resolv/res_send.c (send_dg): If request failed with FORMERR and EDNS0 record was send make sure we don't try it again. * resolv/resolv.h: Define RES_F_EDNS0ERR and RES_USE_EDNS0. * include/resolv.h: Declare __res_nopt.
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");