[PATCH] Avoid res_nsend fd leaks
Jakub Jelinek
jakub@redhat.com
Wed Jan 3 14:38:00 GMT 2001
Hi!
res_nsend badly leaks filedescriptors.
A testcase is e.g.:
#include <netdb.h>
main()
{
char * name = "acs.ac.sg";
int i;
for (i = 0; i < 1000; i++)
gethostbyname(name);
}
The issue is that res_nclose clears _u._ext.nscount but it is initialized
only at the beginning of res_nsend, so if res_nclose is for some reason
called and res_nsend tries another nameserver and/or retries, next time
_u._ext.nscount will be 0 and thus res_nclose does not attempt to close any
sockets (and they get overwritten next time).
This patch attempts to solve this by separating two functions of nscount:
keeps it as count of IPv4 nameservers and moves the meaning that
initialization is needed on next res_nsend to new field nsinit.
Like this, res_nclose can be called as many times as it wishes from within
one res_nsend and no leaks happen.
2001-01-03 Jakub Jelinek <jakub@redhat.com>
* resolv/resolv.h (struct __res_state): Add nsinit field.
* resolv/res_send.c (res_nsend): Use it instead of nscount.
* resolv/res_init.c (__res_vinit): Initialize it.
(res_nclose): Clear it instead of nscount.
--- libc/resolv/res_send.c.jj Fri Aug 25 18:59:43 2000
+++ libc/resolv/res_send.c Wed Jan 3 23:35:20 2001
@@ -394,7 +394,7 @@ res_nsend(res_state statp,
* If the ns_addr_list in the resolver context has changed, then
* invalidate our cached copy and the associated timing data.
*/
- if (EXT(statp).nscount != 0) {
+ if (EXT(statp).nsinit) {
int needclose = 0;
if (EXT(statp).nscount != statp->nscount)
@@ -420,7 +420,7 @@ res_nsend(res_state statp,
/*
* Maybe initialize our private copy of the ns_addr_list.
*/
- if (EXT(statp).nscount == 0) {
+ if (EXT(statp).nsinit == 0) {
#ifdef _LIBC
n = 0;
#endif
@@ -454,6 +454,7 @@ res_nsend(res_state statp,
#endif
}
EXT(statp).nscount = statp->nscount;
+ EXT(statp).nsinit = 1;
#ifdef _LIBC
/* If holes left, free memory and set to NULL */
while (n < MAXNS) {
--- libc/resolv/res_init.c.jj Wed Jan 3 22:45:30 2001
+++ libc/resolv/res_init.c Wed Jan 3 23:33:50 2001
@@ -177,6 +177,7 @@ __res_vinit(res_state statp, int preinit
statp->_flags = 0;
statp->qhook = NULL;
statp->rhook = NULL;
+ statp->_u._ext.nsinit = 0;
statp->_u._ext.nscount = 0;
#ifdef _LIBC
statp->_u._ext.nscount6 = 0;
@@ -544,5 +545,5 @@ res_nclose(res_state statp) {
statp->_u._ext.nssocks[ns] = -1;
}
}
- statp->_u._ext.nscount = 0;
+ statp->_u._ext.nsinit = 0;
}
--- libc/resolv/resolv.h.jj Thu Aug 10 09:39:05 2000
+++ libc/resolv/resolv.h Wed Jan 3 23:32:23 2001
@@ -154,6 +154,7 @@ struct __res_state {
u_int16_t nstimes[MAXNS]; /* ms. */
int nssocks[MAXNS];
u_int16_t nscount6;
+ u_int16_t nsinit;
struct sockaddr_in6 *nsaddrs[MAXNS];
} _ext;
} _u;
Jakub
More information about the Libc-hacker
mailing list