mirror of
https://github.com/isc-projects/bind9.git
synced 2026-02-28 04:21:07 -05:00
2091. [port] dighost.c: race condition on cleanup. [RT #16417]
This commit is contained in:
parent
7b19edc3ba
commit
5209cedf01
2 changed files with 29 additions and 8 deletions
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dighost.c,v 1.259.18.34 2006/08/01 00:54:38 marka Exp $ */
|
||||
/* $Id: dighost.c,v 1.259.18.35 2006/10/02 03:14:35 marka Exp $ */
|
||||
|
||||
/*! \file
|
||||
* \note
|
||||
|
|
@ -697,6 +697,8 @@ make_empty_lookup(void) {
|
|||
fatal("memory allocation failure in %s:%d",
|
||||
__FILE__, __LINE__);
|
||||
looknew->pending = ISC_TRUE;
|
||||
looknew->waiting_senddone = ISC_FALSE;
|
||||
looknew->pending_clear = ISC_FALSE;
|
||||
looknew->textname[0] = 0;
|
||||
looknew->cmdline[0] = 0;
|
||||
looknew->rdtype = dns_rdatatype_a;
|
||||
|
|
@ -1004,9 +1006,8 @@ setup_system(void) {
|
|||
if (lwresult != LWRES_R_SUCCESS)
|
||||
fatal("lwres_context_create failed");
|
||||
|
||||
if (isc_file_exists(RESOLV_CONF))
|
||||
lwresult = lwres_conf_parse(lwctx, RESOLV_CONF);
|
||||
if (lwresult != LWRES_R_SUCCESS)
|
||||
lwresult = lwres_conf_parse(lwctx, RESOLV_CONF);
|
||||
if (lwresult != LWRES_R_SUCCESS && lwresult != LWRES_R_NOTFOUND)
|
||||
fatal("parse of %s failed", RESOLV_CONF);
|
||||
|
||||
lwconf = lwres_conf_get(lwctx);
|
||||
|
|
@ -1259,7 +1260,10 @@ clear_query(dig_query_t *query) {
|
|||
isc_mempool_put(commctx, query->recvspace);
|
||||
isc_buffer_invalidate(&query->recvbuf);
|
||||
isc_buffer_invalidate(&query->lengthbuf);
|
||||
isc_mem_free(mctx, query);
|
||||
if (lookup->waiting_senddone)
|
||||
query->pending_free = ISC_TRUE;
|
||||
else
|
||||
isc_mem_free(mctx, query);
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
@ -1284,9 +1288,15 @@ try_clear_lookup(dig_lookup_t *lookup) {
|
|||
debug("query to %s still pending", q->servname);
|
||||
q = ISC_LIST_NEXT(q, link);
|
||||
}
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
if (lookup->waiting_senddone) {
|
||||
lookup->pending_clear = ISC_TRUE;
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we know there are no queries on the lookup,
|
||||
* so can make it go away also.
|
||||
|
|
@ -1319,7 +1329,6 @@ try_clear_lookup(dig_lookup_t *lookup) {
|
|||
return (ISC_TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*%
|
||||
* If we can, start the next lookup in the queue running.
|
||||
* This assumes that the lookup on the head of the queue hasn't been
|
||||
|
|
@ -1987,6 +1996,7 @@ setup_lookup(dig_lookup_t *lookup) {
|
|||
query, lookup);
|
||||
query->lookup = lookup;
|
||||
query->waiting_connect = ISC_FALSE;
|
||||
query->pending_free = ISC_FALSE;
|
||||
query->recv_made = ISC_FALSE;
|
||||
query->first_pass = ISC_TRUE;
|
||||
query->first_soa_rcvd = ISC_FALSE;
|
||||
|
|
@ -2052,6 +2062,7 @@ send_done(isc_task_t *_task, isc_event_t *event) {
|
|||
|
||||
query = event->ev_arg;
|
||||
l = query->lookup;
|
||||
l->waiting_senddone = ISC_FALSE;
|
||||
|
||||
if (l->ns_search_only && !l->trace_root) {
|
||||
debug("sending next, since searching");
|
||||
|
|
@ -2062,6 +2073,11 @@ send_done(isc_task_t *_task, isc_event_t *event) {
|
|||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (query->pending_free)
|
||||
isc_mem_free(mctx, query);
|
||||
if (l->pending_clear)
|
||||
try_clear_lookup(l);
|
||||
|
||||
check_if_done();
|
||||
UNLOCK_LOOKUP;
|
||||
}
|
||||
|
|
@ -2252,6 +2268,7 @@ send_udp(dig_query_t *query) {
|
|||
debug("sending a request");
|
||||
TIME_NOW(&query->time_sent);
|
||||
INSIST(query->sock != NULL);
|
||||
l->waiting_senddone = ISC_TRUE;
|
||||
result = isc_socket_sendtov(query->sock, &query->sendlist,
|
||||
global_task, send_done, query,
|
||||
&query->sockaddr, NULL);
|
||||
|
|
@ -2451,6 +2468,7 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
|
|||
if (!query->first_soa_rcvd) {
|
||||
debug("sending a request in launch_next_query");
|
||||
TIME_NOW(&query->time_sent);
|
||||
query->lookup->waiting_senddone = ISC_TRUE;
|
||||
result = isc_socket_sendv(query->sock, &query->sendlist,
|
||||
global_task, send_done, query);
|
||||
check_result(result, "isc_socket_sendv");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dig.h,v 1.82.18.16 2006/01/27 23:57:44 marka Exp $ */
|
||||
/* $Id: dig.h,v 1.82.18.17 2006/10/02 03:14:35 marka Exp $ */
|
||||
|
||||
#ifndef DIG_H
|
||||
#define DIG_H
|
||||
|
|
@ -103,6 +103,8 @@ typedef struct dig_searchlist dig_searchlist_t;
|
|||
struct dig_lookup {
|
||||
isc_boolean_t
|
||||
pending, /*%< Pending a successful answer */
|
||||
waiting_senddone,
|
||||
pending_clear,
|
||||
waiting_connect,
|
||||
doing_xfr,
|
||||
ns_search_only, /*%< dig +nssearch, host -C */
|
||||
|
|
@ -186,6 +188,7 @@ isc_boolean_t sigchase;
|
|||
struct dig_query {
|
||||
dig_lookup_t *lookup;
|
||||
isc_boolean_t waiting_connect,
|
||||
pending_free,
|
||||
first_pass,
|
||||
first_soa_rcvd,
|
||||
second_rr_rcvd,
|
||||
|
|
|
|||
Loading…
Reference in a new issue