diff --git a/ChangeLog b/ChangeLog index 1d84631b3d..ee4b378cb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2005-10-31 Ulrich Drepper + * resolv/res_init.c (__res_iclose): New function. Broken out of + res_nclose. Take addition parameter which determines whether + addresses should be freed. + (res_nclose): Call __res_iclose. + (res_thread_freeres): Likewise. + * resolv/res_data.c (res_close): Call __res_iclose. + * resolv/res_libc.c (res_init): No need to separately free the + addresses. + (__res_maybe_init): Likewise. + * resolv/res_send.c: Use __res_iclose instead of res_nclose. + * resolv/Versions [GLIBC_PRIVATE]: Add __res_iclose. + * include/resolv.h: Declare __res_iclose. + Add libc_hidden_proto for __res_iclose. + * hesiod/hesiod.c (__hesiod_res_set): No need to free name server + addresses here again. + [BZ #1579] * debug/execinfo.h: Change backtrace_symbols_fd comment. diff --git a/hesiod/hesiod.c b/hesiod/hesiod.c index b73aa3ce94..b3706b506b 100644 --- a/hesiod/hesiod.c +++ b/hesiod/hesiod.c @@ -487,12 +487,6 @@ __hesiod_res_set(void *context, struct __res_state *res, if (ctx->res && ctx->free_res) { res_nclose(ctx->res); - if ((ctx->res->options & RES_INIT) && ctx->res->nscount > 0) { - for (int ns = 0; ns < MAXNS; ns++) { - free (ctx->res->_u._ext.nsaddrs[ns]); - ctx->res->_u._ext.nsaddrs[ns] = NULL; - } - } (*ctx->free_res)(ctx->res); } diff --git a/include/resolv.h b/include/resolv.h index 9c24bd3bc7..958fb957c6 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -46,9 +46,11 @@ extern void res_send_setqhook (res_send_qhook __hook); extern void res_send_setrhook (res_send_rhook __hook); extern int res_ourserver_p (const res_state __statp, const struct sockaddr_in6 *__inp); +extern void __res_iclose(res_state statp, bool free_addr); libc_hidden_proto (__res_ninit) libc_hidden_proto (__res_maybe_init) libc_hidden_proto (__res_nclose) +libc_hidden_proto (__res_iclose) libc_hidden_proto (__res_randomid) libc_hidden_proto (__res_state) diff --git a/resolv/Versions b/resolv/Versions index 2a67677d8e..7016365be5 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -39,7 +39,7 @@ libc { h_errno; __resp; %endif - __res_maybe_init; + __res_maybe_init; __res_iclose; } } diff --git a/resolv/res_data.c b/resolv/res_data.c index adadcdcd7a..1beea1dc4f 100644 --- a/resolv/res_data.c +++ b/resolv/res_data.c @@ -246,7 +246,9 @@ res_close(void) { if ((_res.options & RES_INIT) == 0) return; #endif - res_nclose(&_res); + /* We don't free the name server addresses because we never + did it and it would be done implicitly on shutdown. */ + __res_iclose(&_res, false); } #ifdef BIND_UPDATE diff --git a/resolv/res_init.c b/resolv/res_init.c index 731c784e17..f881060d58 100644 --- a/resolv/res_init.c +++ b/resolv/res_init.c @@ -555,7 +555,7 @@ libc_hidden_def (__res_randomid) * This routine is not expected to be user visible. */ void -res_nclose(res_state statp) { +__res_iclose(res_state statp, bool free_addr) { int ns; if (statp->_vcsock >= 0) { @@ -568,13 +568,25 @@ res_nclose(res_state statp) { #else for (ns = 0; ns < statp->_u._ext.nscount; ns++) #endif - if (statp->_u._ext.nsaddrs[ns] - && statp->_u._ext.nssocks[ns] != -1) { - close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); - statp->_u._ext.nssocks[ns] = -1; + if (statp->_u._ext.nsaddrs[ns]) { + if (statp->_u._ext.nssocks[ns] != -1) { + close_not_cancel_no_status(statp->_u._ext.nssocks[ns]); + statp->_u._ext.nssocks[ns] = -1; + } + if (free_addr) { + free (statp->_u._ext.nsaddrs[ns]); + statp->_u._ext.nsaddrs[ns] = NULL; + } } statp->_u._ext.nsinit = 0; } +libc_hidden_def (__res_iclose) + +void +res_nclose(res_state statp) +{ + __res_iclose (statp, true); +} #ifdef _LIBC libc_hidden_def (__res_nclose) #endif @@ -589,14 +601,7 @@ res_thread_freeres (void) /* Never called res_ninit. */ return; - __res_nclose (&_res); /* Close any VC sockets. */ - - for (int ns = 0; ns < MAXNS; ns++) - if (_res._u._ext.nsaddrs[ns] != NULL) - { - free (_res._u._ext.nsaddrs[ns]); - _res._u._ext.nsaddrs[ns] = NULL; - } + __res_iclose (&_res, true); /* Close any VC sockets. */ /* Make sure we do a full re-initialization the next time. */ _res.options = 0; diff --git a/resolv/res_libc.c b/resolv/res_libc.c index 76abca8442..834773c32f 100644 --- a/resolv/res_libc.c +++ b/resolv/res_libc.c @@ -70,14 +70,8 @@ res_init(void) { _res.retry = 4; if (!(_res.options & RES_INIT)) _res.options = RES_DEFAULT; - else if (_res.nscount > 0) { - __res_nclose (&_res); /* Close any VC sockets. */ - - for (int ns = 0; ns < MAXNS; ns++) { - free (_res._u._ext.nsaddrs[ns]); - _res._u._ext.nsaddrs[ns] = NULL; - } - } + else if (_res.nscount > 0) + __res_iclose (&_res, true); /* Close any VC sockets. */ /* * This one used to initialize implicitly to zero, so unless the app @@ -103,11 +97,7 @@ __res_maybe_init (res_state resp, int preinit) if (resp->options & RES_INIT) { if (__res_initstamp != resp->_u._ext.initstamp) { if (resp->nscount > 0) { - __res_nclose (resp); - for (int ns = 0; ns < MAXNS; ns++) { - free (resp->_u._ext.nsaddrs[ns]); - resp->_u._ext.nsaddrs[ns] = NULL; - } + __res_iclose (resp, true); return __res_vinit (resp, 1); } } diff --git a/resolv/res_send.c b/resolv/res_send.c index e62cde2360..ff7be11509 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -381,7 +381,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, } } if (needclose) - res_nclose(statp); + __res_iclose(statp, false); } /* @@ -488,7 +488,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - res_nclose(statp); + __res_iclose(statp, false); goto next_ns; case res_done: return (resplen); @@ -553,7 +553,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, */ if ((v_circuit && (statp->options & RES_USEVC) == 0) || (statp->options & RES_STAYOPEN) == 0) { - res_nclose(statp); + __res_iclose(statp, false); } if (statp->rhook) { int done = 0, loops = 0; @@ -570,7 +570,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - res_nclose(statp); + __res_iclose(statp, false); goto next_ns; case res_modified: /* give the hook another try */ @@ -589,7 +589,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, next_ns: ; } /*foreach ns*/ } /*foreach retry*/ - res_nclose(statp); + __res_iclose(statp, false); if (!v_circuit) { if (!gotsomewhere) __set_errno (ECONNREFUSED); /* no nameservers found */ @@ -637,14 +637,14 @@ send_vc(res_state statp, if (getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || !sock_eq(&peer, nsap)) { - res_nclose(statp); + __res_iclose(statp, false); statp->_flags &= ~RES_F_VC; } } if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { if (statp->_vcsock >= 0) - res_nclose(statp); + __res_iclose(statp, false); statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0); if (statp->_vcsock < 0) { @@ -660,7 +660,7 @@ send_vc(res_state statp, *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, (struct sockaddr *) nsap); - res_nclose(statp); + __res_iclose(statp, false); return (0); } statp->_flags |= RES_F_VC; @@ -676,7 +676,7 @@ send_vc(res_state statp, != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } /* @@ -694,7 +694,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read failed", errno); - res_nclose(statp); + __res_iclose(statp, false); /* * A long running process might get its TCP * connection reset if the remote server was @@ -706,10 +706,8 @@ send_vc(res_state statp, */ if (*terrno == ECONNRESET && !connreset) { connreset = 1; - res_nclose(statp); goto same_ns; } - res_nclose(statp); return (0); } resplen = ns_get16(ans); @@ -718,7 +716,7 @@ send_vc(res_state statp, ans = malloc (MAXPACKET); if (ans == NULL) { *terrno = ENOMEM; - res_nclose(statp); + __res_iclose(statp, false); return (0); } anssiz = MAXPACKET; @@ -743,7 +741,7 @@ send_vc(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len)); *terrno = EMSGSIZE; - res_nclose(statp); + __res_iclose(statp, false); return (0); } cp = ans; @@ -754,7 +752,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } if (truncating) { @@ -847,7 +845,7 @@ send_dg(res_state statp, sizeof *nsap) < 0) { Aerror(statp, stderr, "connect(dg)", errno, (struct sockaddr *) nsap); - res_nclose(statp); + __res_iclose(statp, false); return (0); } /* Make socket non-blocking. */ @@ -879,7 +877,7 @@ send_dg(res_state statp, evNowTime(&now); if (evCmpTime(finish, now) <= 0) { Perror(statp, stderr, "select", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } evSubTime(&timeout, &finish, &now); @@ -910,7 +908,7 @@ send_dg(res_state statp, } } Perror(statp, stderr, "poll", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } __set_errno (0); @@ -919,7 +917,7 @@ send_dg(res_state statp, if (errno == EINTR || errno == EAGAIN) goto recompute_resend; Perror(statp, stderr, "send", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } pfd[0].events = POLLIN; @@ -950,7 +948,7 @@ send_dg(res_state statp, goto wait; } Perror(statp, stderr, "recvfrom", errno); - res_nclose(statp); + __res_iclose(statp, false); return (0); } *gotsomewhere = 1; @@ -962,7 +960,7 @@ send_dg(res_state statp, (stdout, ";; undersized: %d\n", resplen)); *terrno = EMSGSIZE; - res_nclose(statp); + __res_iclose(statp, false); return (0); } if (hp->id != anhp->id) { @@ -1011,7 +1009,7 @@ send_dg(res_state statp, (stdout, "server rejected query:\n"), ans, (resplen > anssiz) ? anssiz : resplen); next_ns: - res_nclose(statp); + __res_iclose(statp, false); /* don't retry if called from dig */ if (!statp->pfcode) return (0); @@ -1031,7 +1029,7 @@ send_dg(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n")); *v_circuit = 1; - res_nclose(statp); + __res_iclose(statp, false); return (1); } /* @@ -1041,7 +1039,7 @@ send_dg(res_state statp, return (resplen); } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { /* Something went wrong. We can stop trying. */ - res_nclose(statp); + __res_iclose(statp, false); return (0); } else {