This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
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
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |