Skip to content

Commit

Permalink
Update.
Browse files Browse the repository at this point in the history
2004-10-23  Ulrich Drepper  <drepper@redhat.com>

	* resolv/res_send.c (send_dg): Combine write and read to socket
	into one loop.
  • Loading branch information
Ulrich Drepper committed Oct 23, 2004
1 parent 390c662 commit 17a1031
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 137 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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>

* elf/elf.h: Add R_MN10300_* relocation numbers.
Expand Down
264 changes: 127 additions & 137 deletions resolv/res_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/

#include <assert.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
Expand Down Expand Up @@ -808,7 +809,7 @@ send_dg(res_state statp,
int ptimeout;
struct sockaddr_in6 from;
static int socket_pf = 0;
int fromlen, resplen, seconds, n, s;
int fromlen, resplen, seconds, n;

if (EXT(statp).nssocks[ns] == -1) {
/* only try IPv6 if IPv6 NS and if not failed before */
Expand Down Expand Up @@ -854,7 +855,7 @@ send_dg(res_state statp,
Dprint(statp->options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
}
s = EXT(statp).nssocks[ns];

/*
* Compute time for the total operation.
*/
Expand All @@ -867,13 +868,25 @@ send_dg(res_state statp,
evConsTime(&timeout, seconds, 0);
evAddTime(&finish, &now, &timeout);
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. */
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;

pfd[0].fd = s;
pfd[0].events = POLLOUT;
n = __poll (pfd, 1, 0);
n = 0;
if (nwritten == 0)
n = __poll (pfd, 1, 0);
if (__builtin_expect (n == 0, 0)) {
n = __poll (pfd, 1, ptimeout);
need_recompute = 1;
Expand All @@ -890,157 +903,134 @@ send_dg(res_state statp,
evNowTime(&now);
if (evCmpTime(finish, now) > 0) {
evSubTime(&timeout, &finish, &now);
goto resend;
goto wait;
}
}
Perror(statp, stderr, "select", errno);
res_nclose(statp);
return (0);
}
__set_errno (0);
if (send(s, (char*)buf, buflen, 0) != buflen) {
if (errno == EINTR || errno == EAGAIN)
goto recompute_resend;
Perror(statp, stderr, "send", errno);
res_nclose(statp);
return (0);
}

wait:
if (need_recompute) {
evNowTime(&now);
if (evCmpTime(finish, now) <= 0) {
err_return:
Perror(statp, stderr, "select", errno);
if (pfd[0].revents & POLLOUT) {
if (send(pfd[0].fd, (char*)buf, buflen, 0) != buflen) {
if (errno == EINTR || errno == EAGAIN)
goto recompute_resend;
Perror(statp, stderr, "send", errno);
res_nclose(statp);
return (0);
}
evSubTime(&timeout, &finish, &now);
}
/* Convert struct timespec in milliseconds. */
ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
pfd[0].events = POLLIN;
++nwritten;
goto wait;
} else {
assert(pfd[0].revents & POLLIN);

pfd[0].events = POLLIN;
n = __poll (pfd, 1, ptimeout);
if (n == 0) {
Dprint(statp->options & RES_DEBUG, (stdout,
";; timeout receiving\n"));
fromlen = sizeof(struct sockaddr_in6);
if (anssiz < MAXPACKET
&& anscp
&& (ioctl (pfd[0].fd, FIONREAD, &resplen) < 0
|| anssiz < resplen)) {
ans = malloc (MAXPACKET);
if (ans == NULL)
ans = *ansp;
else {
anssiz = MAXPACKET;
*anssizp = MAXPACKET;
*ansp = ans;
*anscp = ans;
anhp = (HEADER *) ans;
}
}
resplen = recvfrom(pfd[0].fd, (char*)ans, anssiz,0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
if (errno == EINTR || errno == EAGAIN) {
need_recompute = 1;
goto wait;
}
Perror(statp, stderr, "recvfrom", errno);
res_nclose(statp);
return (0);
}
*gotsomewhere = 1;
return (0);
}
if (n < 0) {
if (errno == EINTR) {
need_recompute = 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 err_return;
}
__set_errno (0);
fromlen = sizeof(struct sockaddr_in6);
if (anssiz < MAXPACKET
&& anscp
&& (ioctl (s, FIONREAD, &resplen) < 0
|| anssiz < resplen)) {
ans = malloc (MAXPACKET);
if (ans == NULL)
ans = *ansp;
else {
anssiz = MAXPACKET;
*anssizp = MAXPACKET;
*ansp = ans;
*anscp = ans;
anhp = (HEADER *) ans;
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;
}
}
resplen = recvfrom(s, (char*)ans, anssiz,0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
if (errno == EINTR || errno == EAGAIN) {
need_recompute = 1;
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;
}
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;
}
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) {
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);
}
/*
* To get the rest of answer,
* use TCP with same server.
* All is well, or the error is fatal. Signal that the
* next nameserver ought not be tried.
*/
Dprint(statp->options & RES_DEBUG,
(stdout, ";; truncated answer\n"));
*v_circuit = 1;
res_nclose(statp);
return (1);
return (resplen);
}
/*
* All is well, or the error is fatal. Signal that the
* next nameserver ought not be tried.
*/
return (resplen);
}

#ifdef DEBUG
Expand Down

0 comments on commit 17a1031

Please sign in to comment.