Update.
* resolv/res_send.c: Add locks for res_send and res_close use.
This commit is contained in:
parent
e28bacf578
commit
30f9ca19e0
@ -1,5 +1,7 @@
|
|||||||
1999-07-24 Ulrich Drepper <drepper@cygnus.com>
|
1999-07-24 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* resolv/res_send.c: Add locks for res_send and res_close use.
|
||||||
|
|
||||||
* elf/Makefile (dl-routines): Add preinit.
|
* elf/Makefile (dl-routines): Add preinit.
|
||||||
* elf/Versions [ld.so] (GLIBC_2.2): Export _dl_preinit_next.
|
* elf/Versions [ld.so] (GLIBC_2.2): Export _dl_preinit_next.
|
||||||
* elf/link.h (struct link_map): Add new field l_preinitcount.
|
* elf/link.h (struct link_map): Add new field l_preinitcount.
|
||||||
|
@ -87,6 +87,13 @@ static char rcsid[] = "$Id$";
|
|||||||
# include "../conf/portability.h"
|
# include "../conf/portability.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <bits/libc-lock.h>
|
||||||
|
|
||||||
|
/* Lock to protect the connection use. */
|
||||||
|
__libc_lock_define_initialized (static, lock)
|
||||||
|
|
||||||
|
static void res_close_internal (void);
|
||||||
|
|
||||||
#if defined(USE_OPTIONS_H)
|
#if defined(USE_OPTIONS_H)
|
||||||
# include <../conf/options.h>
|
# include <../conf/options.h>
|
||||||
#endif
|
#endif
|
||||||
@ -293,6 +300,7 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
|
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
|
||||||
register int n;
|
register int n;
|
||||||
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
|
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||||
/* errno should have been set by res_init() in this case. */
|
/* errno should have been set by res_init() in this case. */
|
||||||
@ -310,6 +318,8 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
terrno = ETIMEDOUT;
|
terrno = ETIMEDOUT;
|
||||||
badns = 0;
|
badns = 0;
|
||||||
|
|
||||||
|
__libc_lock_lock (lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send request, RETRY times, or until successful
|
* Send request, RETRY times, or until successful
|
||||||
*/
|
*/
|
||||||
@ -318,7 +328,7 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
|
struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
|
||||||
same_ns:
|
same_ns:
|
||||||
if (badns & (1 << ns)) {
|
if (badns & (1 << ns)) {
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,10 +345,11 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
case res_nextns:
|
case res_nextns:
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
case res_done:
|
case res_done:
|
||||||
return (resplen);
|
result = resplen;
|
||||||
|
goto and_out;
|
||||||
case res_modified:
|
case res_modified:
|
||||||
/* give the hook another try */
|
/* give the hook another try */
|
||||||
if (++loops < 42) /*doug adams*/
|
if (++loops < 42) /*doug adams*/
|
||||||
@ -347,7 +358,7 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
case res_error:
|
case res_error:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
default:
|
default:
|
||||||
return (-1);
|
goto and_out;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
}
|
}
|
||||||
@ -370,13 +381,13 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
truncated = 0;
|
truncated = 0;
|
||||||
if ((s < 0) || (!vc)) {
|
if ((s < 0) || (!vc)) {
|
||||||
if (s >= 0)
|
if (s >= 0)
|
||||||
res_close();
|
res_close_internal();
|
||||||
|
|
||||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
terrno = errno;
|
terrno = errno;
|
||||||
Perror(stderr, "socket(vc)", errno);
|
Perror(stderr, "socket(vc)", errno);
|
||||||
return (-1);
|
goto and_out;
|
||||||
}
|
}
|
||||||
__set_errno (0);
|
__set_errno (0);
|
||||||
if (connect(s, (struct sockaddr *)nsap,
|
if (connect(s, (struct sockaddr *)nsap,
|
||||||
@ -385,7 +396,7 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
Aerror(stderr, "connect/vc",
|
Aerror(stderr, "connect/vc",
|
||||||
errno, *nsap);
|
errno, *nsap);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
vc = 1;
|
vc = 1;
|
||||||
@ -402,7 +413,7 @@ res_send(buf, buflen, ans, anssiz)
|
|||||||
terrno = errno;
|
terrno = errno;
|
||||||
Perror(stderr, "write failed", errno);
|
Perror(stderr, "write failed", errno);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -419,7 +430,7 @@ read_len:
|
|||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
terrno = errno;
|
terrno = errno;
|
||||||
Perror(stderr, "read failed", errno);
|
Perror(stderr, "read failed", errno);
|
||||||
res_close();
|
res_close_internal();
|
||||||
/*
|
/*
|
||||||
* A long running process might get its TCP
|
* A long running process might get its TCP
|
||||||
* connection reset if the remote server was
|
* connection reset if the remote server was
|
||||||
@ -431,10 +442,10 @@ read_len:
|
|||||||
*/
|
*/
|
||||||
if (terrno == ECONNRESET && !connreset) {
|
if (terrno == ECONNRESET && !connreset) {
|
||||||
connreset = 1;
|
connreset = 1;
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto same_ns;
|
goto same_ns;
|
||||||
}
|
}
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
resplen = _getshort(ans);
|
resplen = _getshort(ans);
|
||||||
@ -454,7 +465,7 @@ read_len:
|
|||||||
(stdout, ";; undersized: %d\n", len));
|
(stdout, ";; undersized: %d\n", len));
|
||||||
terrno = EMSGSIZE;
|
terrno = EMSGSIZE;
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
cp = ans;
|
cp = ans;
|
||||||
@ -466,7 +477,7 @@ read_len:
|
|||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
terrno = errno;
|
terrno = errno;
|
||||||
Perror(stderr, "read(vc)", errno);
|
Perror(stderr, "read(vc)", errno);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
if (truncated) {
|
if (truncated) {
|
||||||
@ -513,7 +524,7 @@ read_len:
|
|||||||
|
|
||||||
if ((s < 0) || vc) {
|
if ((s < 0) || vc) {
|
||||||
if (vc)
|
if (vc)
|
||||||
res_close();
|
res_close_internal();
|
||||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
#if !CAN_RECONNECT
|
#if !CAN_RECONNECT
|
||||||
@ -521,7 +532,7 @@ read_len:
|
|||||||
#endif
|
#endif
|
||||||
terrno = errno;
|
terrno = errno;
|
||||||
Perror(stderr, "socket(dg)", errno);
|
Perror(stderr, "socket(dg)", errno);
|
||||||
return (-1);
|
goto and_out;
|
||||||
}
|
}
|
||||||
connected = 0;
|
connected = 0;
|
||||||
}
|
}
|
||||||
@ -553,7 +564,7 @@ read_len:
|
|||||||
"connect(dg)",
|
"connect(dg)",
|
||||||
errno, *nsap);
|
errno, *nsap);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
connected = 1;
|
connected = 1;
|
||||||
@ -561,7 +572,7 @@ read_len:
|
|||||||
if (send(s, (char*)buf, buflen, 0) != buflen) {
|
if (send(s, (char*)buf, buflen, 0) != buflen) {
|
||||||
Perror(stderr, "send", errno);
|
Perror(stderr, "send", errno);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -598,7 +609,7 @@ read_len:
|
|||||||
!= buflen) {
|
!= buflen) {
|
||||||
Aerror(stderr, "sendto", errno, *nsap);
|
Aerror(stderr, "sendto", errno, *nsap);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -614,7 +625,7 @@ read_len:
|
|||||||
wait:
|
wait:
|
||||||
if (s < 0 || s >= FD_SETSIZE) {
|
if (s < 0 || s >= FD_SETSIZE) {
|
||||||
Perror(stderr, "s out-of-bounds", EMFILE);
|
Perror(stderr, "s out-of-bounds", EMFILE);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
pfd[0].fd = s;
|
pfd[0].fd = s;
|
||||||
@ -624,7 +635,7 @@ read_len:
|
|||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
goto wait;
|
goto wait;
|
||||||
Perror(stderr, "poll", errno);
|
Perror(stderr, "poll", errno);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
@ -634,7 +645,7 @@ read_len:
|
|||||||
Dprint(_res.options & RES_DEBUG,
|
Dprint(_res.options & RES_DEBUG,
|
||||||
(stdout, ";; timeout\n"));
|
(stdout, ";; timeout\n"));
|
||||||
gotsomewhere = 1;
|
gotsomewhere = 1;
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
__set_errno (0);
|
__set_errno (0);
|
||||||
@ -643,7 +654,7 @@ read_len:
|
|||||||
(struct sockaddr *)&from, &fromlen);
|
(struct sockaddr *)&from, &fromlen);
|
||||||
if (resplen <= 0) {
|
if (resplen <= 0) {
|
||||||
Perror(stderr, "recvfrom", errno);
|
Perror(stderr, "recvfrom", errno);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
gotsomewhere = 1;
|
gotsomewhere = 1;
|
||||||
@ -656,7 +667,7 @@ read_len:
|
|||||||
resplen));
|
resplen));
|
||||||
terrno = EMSGSIZE;
|
terrno = EMSGSIZE;
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
}
|
}
|
||||||
if (hp->id != anhp->id) {
|
if (hp->id != anhp->id) {
|
||||||
@ -707,7 +718,7 @@ read_len:
|
|||||||
(stdout, "server rejected query:\n"),
|
(stdout, "server rejected query:\n"),
|
||||||
ans, (resplen>anssiz)?anssiz:resplen);
|
ans, (resplen>anssiz)?anssiz:resplen);
|
||||||
badns |= (1 << ns);
|
badns |= (1 << ns);
|
||||||
res_close();
|
res_close_internal();
|
||||||
/* don't retry if called from dig */
|
/* don't retry if called from dig */
|
||||||
if (!_res.pfcode)
|
if (!_res.pfcode)
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
@ -720,7 +731,7 @@ read_len:
|
|||||||
Dprint(_res.options & RES_DEBUG,
|
Dprint(_res.options & RES_DEBUG,
|
||||||
(stdout, ";; truncated answer\n"));
|
(stdout, ";; truncated answer\n"));
|
||||||
v_circuit = 1;
|
v_circuit = 1;
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto same_ns;
|
goto same_ns;
|
||||||
}
|
}
|
||||||
} /*if vc/dg*/
|
} /*if vc/dg*/
|
||||||
@ -742,7 +753,7 @@ read_len:
|
|||||||
*/
|
*/
|
||||||
if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
|
if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
|
||||||
!(_res.options & RES_STAYOPEN)) {
|
!(_res.options & RES_STAYOPEN)) {
|
||||||
res_close();
|
res_close_internal();
|
||||||
}
|
}
|
||||||
if (Rhook) {
|
if (Rhook) {
|
||||||
int done = 0, loops = 0;
|
int done = 0, loops = 0;
|
||||||
@ -758,7 +769,7 @@ read_len:
|
|||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
case res_nextns:
|
case res_nextns:
|
||||||
res_close();
|
res_close_internal();
|
||||||
goto next_ns;
|
goto next_ns;
|
||||||
case res_modified:
|
case res_modified:
|
||||||
/* give the hook another try */
|
/* give the hook another try */
|
||||||
@ -768,16 +779,17 @@ read_len:
|
|||||||
case res_error:
|
case res_error:
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
default:
|
default:
|
||||||
return (-1);
|
goto and_out;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
|
|
||||||
}
|
}
|
||||||
return (resplen);
|
result = resplen;
|
||||||
|
goto and_out;
|
||||||
next_ns: ;
|
next_ns: ;
|
||||||
} /*foreach ns*/
|
} /*foreach ns*/
|
||||||
} /*foreach retry*/
|
} /*foreach retry*/
|
||||||
res_close();
|
res_close_internal();
|
||||||
if (!v_circuit) {
|
if (!v_circuit) {
|
||||||
if (!gotsomewhere)
|
if (!gotsomewhere)
|
||||||
__set_errno (ECONNREFUSED); /* no nameservers found */
|
__set_errno (ECONNREFUSED); /* no nameservers found */
|
||||||
@ -785,7 +797,11 @@ read_len:
|
|||||||
__set_errno (ETIMEDOUT); /* no answer obtained */
|
__set_errno (ETIMEDOUT); /* no answer obtained */
|
||||||
} else
|
} else
|
||||||
__set_errno (terrno);
|
__set_errno (terrno);
|
||||||
return (-1);
|
|
||||||
|
and_out:
|
||||||
|
__libc_lock_unlock (lock);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -795,8 +811,8 @@ read_len:
|
|||||||
*
|
*
|
||||||
* This routine is not expected to be user visible.
|
* This routine is not expected to be user visible.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
res_close()
|
res_close_internal()
|
||||||
{
|
{
|
||||||
if (s >= 0) {
|
if (s >= 0) {
|
||||||
(void) close(s);
|
(void) close(s);
|
||||||
@ -806,6 +822,14 @@ res_close()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
res_close ()
|
||||||
|
{
|
||||||
|
__libc_lock_lock (lock);
|
||||||
|
res_close_internal ();
|
||||||
|
__libc_lock_unlock (lock);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ultrix
|
#ifdef ultrix
|
||||||
/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here.
|
/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here.
|
||||||
* there is more gunk of this kind over in res_debug.c.
|
* there is more gunk of this kind over in res_debug.c.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user