aboutsummaryrefslogtreecommitdiff
path: root/resolv/res_send.c
diff options
context:
space:
mode:
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r--resolv/res_send.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c
index 5a10faa393..d2c97d0cd4 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -409,6 +409,7 @@ res_send(buf, buflen, ans, anssiz)
/*
* Receive length & response
*/
+read_len:
cp = ans;
len = INT16SZ;
while ((n = read(s, (char *)cp, (int)len)) > 0) {
@@ -477,6 +478,20 @@ res_send(buf, buflen, ans, anssiz)
break;
}
}
+ /*
+ * The calling applicating has bailed out of
+ * a previous call and failed to arrange to have
+ * the circuit closed or the server has got
+ * itself confused. Anyway drop the packet and
+ * wait for the correct one.
+ */
+ if (hp->id != anhp->id) {
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer (unexpected):\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto read_len;
+ }
} else {
/*
* Use datagrams.
@@ -593,6 +608,8 @@ res_send(buf, buflen, ans, anssiz)
n = select(s+1, &dsmask, (fd_set *)NULL,
(fd_set *)NULL, &timeout);
if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
Perror(stderr, "select", errno);
_res_close();
goto next_ns;
@@ -626,7 +643,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; old answer:\n"),
- ans, resplen);
+ ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
}
#if CHECK_SRVR_ADDR
@@ -640,7 +657,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; not our server:\n"),
- ans, resplen);
+ ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
}
#endif
@@ -655,7 +672,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; wrong query name:\n"),
- ans, resplen);
+ ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
}
if (anhp->rcode == SERVFAIL ||
@@ -663,7 +680,7 @@ res_send(buf, buflen, ans, anssiz)
anhp->rcode == REFUSED) {
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
- ans, resplen);
+ ans, (resplen>anssiz)?anssiz:resplen);
badns |= (1 << ns);
_res_close();
/* don't retry if called from dig */
@@ -689,7 +706,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ""),
- ans, resplen);
+ ans, (resplen>anssiz)?anssiz:resplen);
/*
* If using virtual circuits, we assume that the first server
* is preferred over the rest (i.e. it is on the local