There's a bug in src/lib/libc/net/res_send.c, res_send():
If, say, gethostbyaddr() is called in a program that has an active, highfrequency
interval timer, it is possible that the resolver will get stuck in a
loop that never finishes, hanging the program. This could happen if a packet
is dropped on the way to/from the namserver:
In the code fragment below, there's a check to see if select() was interrupted
by a signal. If it was, the select is restarted w/ the same timeout value as
before. If the interval timer ticks faster than the timeout value, the program
will loop forever in a select-interrupted loop.
Proposed solution: when select is interrupted, it should restarted w/ a smaller
timeout (ideally, the residual timeout count from the last call).
/*
* Wait for reply
*/
timeout.tv_sec = (_resp->retrans << try);
if (try > 0)
timeout.tv_sec /= _resp->nscount;
if ((long) timeout.tv_sec <= 0)
timeout.tv_sec = 1;
timeout.tv_usec = 0;
wait:
dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
sizeof(fd_mask));
if (dsmaskp == NULL) {
res_close();
goto next_ns;
}
FD_SET(s, dsmaskp);
n = select(s+1, dsmaskp, (fd_set *)NULL,
(fd_set *)NULL, &timeout);
free(dsmaskp);
if (n < 0) {
if (errno == EINTR)
goto wait;
Perror(stderr, "select", errno);
res_close();
goto next_ns;
}
Received on Wed Mar 26 14:01:25 2003
This archive was generated by hypermail 2.1.8
: Wed Aug 23 2006 - 13:29:52 EDT
|