mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
2004-10-23 Ulrich Drepper <drepper@redhat.com> * resolv/res_send.c (send_dg): Combine write and read to socket into one loop.
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
2004-10-23 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* resolv/res_send.c (send_dg): Combine write and read to socket
|
||||||
|
into one loop.
|
||||||
|
|
||||||
2001-10-31 Alexandre Oliva <aoliva@redhat.com>
|
2001-10-31 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
* elf/elf.h: Add R_MN10300_* relocation numbers.
|
* elf/elf.h: Add R_MN10300_* relocation numbers.
|
||||||
|
@ -73,6 +73,7 @@ static const char rcsid[] = "$BINDId: res_send.c,v 8.38 2000/03/30 20:16:51 vixi
|
|||||||
* Send query to name server and wait for reply.
|
* Send query to name server and wait for reply.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -808,7 +809,7 @@ send_dg(res_state statp,
|
|||||||
int ptimeout;
|
int ptimeout;
|
||||||
struct sockaddr_in6 from;
|
struct sockaddr_in6 from;
|
||||||
static int socket_pf = 0;
|
static int socket_pf = 0;
|
||||||
int fromlen, resplen, seconds, n, s;
|
int fromlen, resplen, seconds, n;
|
||||||
|
|
||||||
if (EXT(statp).nssocks[ns] == -1) {
|
if (EXT(statp).nssocks[ns] == -1) {
|
||||||
/* only try IPv6 if IPv6 NS and if not failed before */
|
/* only try IPv6 if IPv6 NS and if not failed before */
|
||||||
@ -854,7 +855,7 @@ send_dg(res_state statp,
|
|||||||
Dprint(statp->options & RES_DEBUG,
|
Dprint(statp->options & RES_DEBUG,
|
||||||
(stdout, ";; new DG socket\n"))
|
(stdout, ";; new DG socket\n"))
|
||||||
}
|
}
|
||||||
s = EXT(statp).nssocks[ns];
|
|
||||||
/*
|
/*
|
||||||
* Compute time for the total operation.
|
* Compute time for the total operation.
|
||||||
*/
|
*/
|
||||||
@ -867,13 +868,25 @@ send_dg(res_state statp,
|
|||||||
evConsTime(&timeout, seconds, 0);
|
evConsTime(&timeout, seconds, 0);
|
||||||
evAddTime(&finish, &now, &timeout);
|
evAddTime(&finish, &now, &timeout);
|
||||||
int need_recompute = 0;
|
int need_recompute = 0;
|
||||||
resend:
|
int nwritten = 0;
|
||||||
|
pfd[0].fd = EXT(statp).nssocks[ns];
|
||||||
|
pfd[0].events = POLLOUT;
|
||||||
|
wait:
|
||||||
|
if (need_recompute) {
|
||||||
|
evNowTime(&now);
|
||||||
|
if (evCmpTime(finish, now) <= 0) {
|
||||||
|
Perror(statp, stderr, "select", errno);
|
||||||
|
res_nclose(statp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
evSubTime(&timeout, &finish, &now);
|
||||||
|
}
|
||||||
/* Convert struct timespec in milliseconds. */
|
/* Convert struct timespec in milliseconds. */
|
||||||
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
|
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
|
||||||
|
|
||||||
pfd[0].fd = s;
|
n = 0;
|
||||||
pfd[0].events = POLLOUT;
|
if (nwritten == 0)
|
||||||
n = __poll (pfd, 1, 0);
|
n = __poll (pfd, 1, 0);
|
||||||
if (__builtin_expect (n == 0, 0)) {
|
if (__builtin_expect (n == 0, 0)) {
|
||||||
n = __poll (pfd, 1, ptimeout);
|
n = __poll (pfd, 1, ptimeout);
|
||||||
need_recompute = 1;
|
need_recompute = 1;
|
||||||
@ -890,7 +903,7 @@ send_dg(res_state statp,
|
|||||||
evNowTime(&now);
|
evNowTime(&now);
|
||||||
if (evCmpTime(finish, now) > 0) {
|
if (evCmpTime(finish, now) > 0) {
|
||||||
evSubTime(&timeout, &finish, &now);
|
evSubTime(&timeout, &finish, &now);
|
||||||
goto resend;
|
goto wait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Perror(statp, stderr, "select", errno);
|
Perror(statp, stderr, "select", errno);
|
||||||
@ -898,149 +911,126 @@ send_dg(res_state statp,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
__set_errno (0);
|
__set_errno (0);
|
||||||
if (send(s, (char*)buf, buflen, 0) != buflen) {
|
if (pfd[0].revents & POLLOUT) {
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (send(pfd[0].fd, (char*)buf, buflen, 0) != buflen) {
|
||||||
goto recompute_resend;
|
if (errno == EINTR || errno == EAGAIN)
|
||||||
Perror(statp, stderr, "send", errno);
|
goto recompute_resend;
|
||||||
res_nclose(statp);
|
Perror(statp, stderr, "send", errno);
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
wait:
|
|
||||||
if (need_recompute) {
|
|
||||||
evNowTime(&now);
|
|
||||||
if (evCmpTime(finish, now) <= 0) {
|
|
||||||
err_return:
|
|
||||||
Perror(statp, stderr, "select", errno);
|
|
||||||
res_nclose(statp);
|
res_nclose(statp);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
evSubTime(&timeout, &finish, &now);
|
pfd[0].events = POLLIN;
|
||||||
}
|
++nwritten;
|
||||||
/* Convert struct timespec in milliseconds. */
|
goto wait;
|
||||||
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
|
} else {
|
||||||
|
assert(pfd[0].revents & POLLIN);
|
||||||
|
|
||||||
pfd[0].events = POLLIN;
|
fromlen = sizeof(struct sockaddr_in6);
|
||||||
n = __poll (pfd, 1, ptimeout);
|
if (anssiz < MAXPACKET
|
||||||
if (n == 0) {
|
&& anscp
|
||||||
Dprint(statp->options & RES_DEBUG, (stdout,
|
&& (ioctl (pfd[0].fd, FIONREAD, &resplen) < 0
|
||||||
";; timeout receiving\n"));
|
|
||||||
*gotsomewhere = 1;
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (n < 0) {
|
|
||||||
if (errno == EINTR) {
|
|
||||||
need_recompute = 1;
|
|
||||||
goto wait;
|
|
||||||
}
|
|
||||||
goto err_return;
|
|
||||||
}
|
|
||||||
__set_errno (0);
|
|
||||||
fromlen = sizeof(struct sockaddr_in6);
|
|
||||||
if (anssiz < MAXPACKET
|
|
||||||
&& anscp
|
|
||||||
&& (ioctl (s, FIONREAD, &resplen) < 0
|
|
||||||
|| anssiz < resplen)) {
|
|| anssiz < resplen)) {
|
||||||
ans = malloc (MAXPACKET);
|
ans = malloc (MAXPACKET);
|
||||||
if (ans == NULL)
|
if (ans == NULL)
|
||||||
ans = *ansp;
|
ans = *ansp;
|
||||||
else {
|
else {
|
||||||
anssiz = MAXPACKET;
|
anssiz = MAXPACKET;
|
||||||
*anssizp = MAXPACKET;
|
*anssizp = MAXPACKET;
|
||||||
*ansp = ans;
|
*ansp = ans;
|
||||||
*anscp = ans;
|
*anscp = ans;
|
||||||
anhp = (HEADER *) ans;
|
anhp = (HEADER *) ans;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
resplen = recvfrom(pfd[0].fd, (char*)ans, anssiz,0,
|
||||||
resplen = recvfrom(s, (char*)ans, anssiz,0,
|
(struct sockaddr *)&from, &fromlen);
|
||||||
(struct sockaddr *)&from, &fromlen);
|
if (resplen <= 0) {
|
||||||
if (resplen <= 0) {
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
if (errno == EINTR || errno == EAGAIN) {
|
need_recompute = 1;
|
||||||
need_recompute = 1;
|
goto wait;
|
||||||
|
}
|
||||||
|
Perror(statp, stderr, "recvfrom", errno);
|
||||||
|
res_nclose(statp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
*gotsomewhere = 1;
|
||||||
|
if (resplen < HFIXEDSZ) {
|
||||||
|
/*
|
||||||
|
* Undersized message.
|
||||||
|
*/
|
||||||
|
Dprint(statp->options & RES_DEBUG,
|
||||||
|
(stdout, ";; undersized: %d\n",
|
||||||
|
resplen));
|
||||||
|
*terrno = EMSGSIZE;
|
||||||
|
res_nclose(statp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (hp->id != anhp->id) {
|
||||||
|
/*
|
||||||
|
* response from old query, ignore it.
|
||||||
|
* XXX - potential security hazard could
|
||||||
|
* be detected here.
|
||||||
|
*/
|
||||||
|
DprintQ((statp->options & RES_DEBUG) ||
|
||||||
|
(statp->pfcode & RES_PRF_REPLY),
|
||||||
|
(stdout, ";; old answer:\n"),
|
||||||
|
ans, (resplen > anssiz) ? anssiz : resplen);
|
||||||
goto wait;
|
goto wait;
|
||||||
}
|
}
|
||||||
Perror(statp, stderr, "recvfrom", errno);
|
if (!(statp->options & RES_INSECURE1) &&
|
||||||
res_nclose(statp);
|
!res_ourserver_p(statp, &from)) {
|
||||||
return (0);
|
/*
|
||||||
}
|
* response from wrong server? ignore it.
|
||||||
*gotsomewhere = 1;
|
* XXX - potential security hazard could
|
||||||
if (resplen < HFIXEDSZ) {
|
* be detected here.
|
||||||
|
*/
|
||||||
|
DprintQ((statp->options & RES_DEBUG) ||
|
||||||
|
(statp->pfcode & RES_PRF_REPLY),
|
||||||
|
(stdout, ";; not our server:\n"),
|
||||||
|
ans, (resplen > anssiz) ? anssiz : resplen);
|
||||||
|
goto wait;
|
||||||
|
}
|
||||||
|
if (!(statp->options & RES_INSECURE2) &&
|
||||||
|
!res_queriesmatch(buf, buf + buflen,
|
||||||
|
ans, ans + anssiz)) {
|
||||||
|
/*
|
||||||
|
* response contains wrong query? ignore it.
|
||||||
|
* XXX - potential security hazard could
|
||||||
|
* be detected here.
|
||||||
|
*/
|
||||||
|
DprintQ((statp->options & RES_DEBUG) ||
|
||||||
|
(statp->pfcode & RES_PRF_REPLY),
|
||||||
|
(stdout, ";; wrong query name:\n"),
|
||||||
|
ans, (resplen > anssiz) ? anssiz : resplen);
|
||||||
|
goto wait;
|
||||||
|
}
|
||||||
|
if (anhp->rcode == SERVFAIL ||
|
||||||
|
anhp->rcode == NOTIMP ||
|
||||||
|
anhp->rcode == REFUSED) {
|
||||||
|
DprintQ(statp->options & RES_DEBUG,
|
||||||
|
(stdout, "server rejected query:\n"),
|
||||||
|
ans, (resplen > anssiz) ? anssiz : resplen);
|
||||||
|
res_nclose(statp);
|
||||||
|
/* don't retry if called from dig */
|
||||||
|
if (!statp->pfcode)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (!(statp->options & RES_IGNTC) && anhp->tc) {
|
||||||
|
/*
|
||||||
|
* To get the rest of answer,
|
||||||
|
* use TCP with same server.
|
||||||
|
*/
|
||||||
|
Dprint(statp->options & RES_DEBUG,
|
||||||
|
(stdout, ";; truncated answer\n"));
|
||||||
|
*v_circuit = 1;
|
||||||
|
res_nclose(statp);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Undersized message.
|
* All is well, or the error is fatal. Signal that the
|
||||||
|
* next nameserver ought not be tried.
|
||||||
*/
|
*/
|
||||||
Dprint(statp->options & RES_DEBUG,
|
return (resplen);
|
||||||
(stdout, ";; undersized: %d\n",
|
|
||||||
resplen));
|
|
||||||
*terrno = EMSGSIZE;
|
|
||||||
res_nclose(statp);
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
if (hp->id != anhp->id) {
|
|
||||||
/*
|
|
||||||
* response from old query, ignore it.
|
|
||||||
* XXX - potential security hazard could
|
|
||||||
* be detected here.
|
|
||||||
*/
|
|
||||||
DprintQ((statp->options & RES_DEBUG) ||
|
|
||||||
(statp->pfcode & RES_PRF_REPLY),
|
|
||||||
(stdout, ";; old answer:\n"),
|
|
||||||
ans, (resplen > anssiz) ? anssiz : resplen);
|
|
||||||
goto wait;
|
|
||||||
}
|
|
||||||
if (!(statp->options & RES_INSECURE1) &&
|
|
||||||
!res_ourserver_p(statp, &from)) {
|
|
||||||
/*
|
|
||||||
* response from wrong server? ignore it.
|
|
||||||
* XXX - potential security hazard could
|
|
||||||
* be detected here.
|
|
||||||
*/
|
|
||||||
DprintQ((statp->options & RES_DEBUG) ||
|
|
||||||
(statp->pfcode & RES_PRF_REPLY),
|
|
||||||
(stdout, ";; not our server:\n"),
|
|
||||||
ans, (resplen > anssiz) ? anssiz : resplen);
|
|
||||||
goto wait;
|
|
||||||
}
|
|
||||||
if (!(statp->options & RES_INSECURE2) &&
|
|
||||||
!res_queriesmatch(buf, buf + buflen,
|
|
||||||
ans, ans + anssiz)) {
|
|
||||||
/*
|
|
||||||
* response contains wrong query? ignore it.
|
|
||||||
* XXX - potential security hazard could
|
|
||||||
* be detected here.
|
|
||||||
*/
|
|
||||||
DprintQ((statp->options & RES_DEBUG) ||
|
|
||||||
(statp->pfcode & RES_PRF_REPLY),
|
|
||||||
(stdout, ";; wrong query name:\n"),
|
|
||||||
ans, (resplen > anssiz) ? anssiz : resplen);
|
|
||||||
goto wait;
|
|
||||||
}
|
|
||||||
if (anhp->rcode == SERVFAIL ||
|
|
||||||
anhp->rcode == NOTIMP ||
|
|
||||||
anhp->rcode == REFUSED) {
|
|
||||||
DprintQ(statp->options & RES_DEBUG,
|
|
||||||
(stdout, "server rejected query:\n"),
|
|
||||||
ans, (resplen > anssiz) ? anssiz : resplen);
|
|
||||||
res_nclose(statp);
|
|
||||||
/* don't retry if called from dig */
|
|
||||||
if (!statp->pfcode)
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (!(statp->options & RES_IGNTC) && anhp->tc) {
|
|
||||||
/*
|
|
||||||
* To get the rest of answer,
|
|
||||||
* use TCP with same server.
|
|
||||||
*/
|
|
||||||
Dprint(statp->options & RES_DEBUG,
|
|
||||||
(stdout, ";; truncated answer\n"));
|
|
||||||
*v_circuit = 1;
|
|
||||||
res_nclose(statp);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* All is well, or the error is fatal. Signal that the
|
|
||||||
* next nameserver ought not be tried.
|
|
||||||
*/
|
|
||||||
return (resplen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
Reference in New Issue
Block a user