Major changes to how dighost handles lists and shutdown conditions.

Probably not safe to pull up to release branch, since, though it works, it
needs serious testing and more changes are still pending.  In particular,
I INSIST lots of things I didn't used to INSIST, which may be set off
under certain conditions.
This commit is contained in:
Michael Sawyer
2000-07-13 00:32:20 +00:00
parent 2e1236ad1e
commit d2895dd9bb

View File

@@ -15,7 +15,7 @@
* SOFTWARE.
*/
/* $Id: dighost.c,v 1.77 2000/07/12 00:42:54 mws Exp $ */
/* $Id: dighost.c,v 1.78 2000/07/13 00:32:20 mws Exp $ */
/*
* Notice to programmers: Do not use this code as an example of how to
@@ -88,6 +88,7 @@ isc_sockaddr_t bind_any;
char *rootspace[BUFSIZE];
isc_buffer_t rootbuf;
int sendcount = 0;
int recvcount = 0;
int sockcount = 0;
int ndots = -1;
int tries = 3;
@@ -107,7 +108,7 @@ extern isc_boolean_t isc_mem_debugging;
isc_boolean_t debugging = ISC_FALSE;
char *progname = NULL;
static isc_boolean_t
static void
cancel_lookup(dig_lookup_t *lookup);
static int
@@ -237,8 +238,7 @@ requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
debug("requeue_lookup()");
if (free_now)
return(ISC_R_SUCCESS);
INSIST(!free_now);
lookup_counter++;
if (lookup_counter > LOOKUP_LIMIT)
@@ -615,19 +615,114 @@ add_question(dns_message_t *message, dns_name_t *name,
}
/*
* Return ISC_TRUE if we're in the process of shutting down on the
* return.
* We're done iff all the counts are zero and the lookup list is empty
*/
static void
check_if_done(void) {
debug("check_if_done()");
if ((sockcount == 0) && (recvcount == 0) && (sendcount == 0)
&& ISC_LIST_EMPTY(lookup_list)) {
debug("shutting down");
dighost_shutdown();
}
}
/*
* Clear out a query when we're done with it. WARNING: This routine
* WILL invalidate the query pointer.
*/
static void
clear_query(dig_query_t *query) {
dig_lookup_t *lookup;
REQUIRE(query != NULL);
lookup = query->lookup;
ISC_LIST_UNLINK(lookup->q, query, link);
if (ISC_LINK_LINKED(&query->recvbuf, link))
ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
link);
if (ISC_LINK_LINKED(&query->lengthbuf, link))
ISC_LIST_DEQUEUE(query->lengthlist, &query->lengthbuf,
link);
isc_buffer_invalidate(&query->recvbuf);
isc_buffer_invalidate(&query->lengthbuf);
isc_mem_free(mctx, query);
}
static isc_boolean_t
check_next_lookup(dig_lookup_t *lookup) {
try_clear_lookup(dig_lookup_t *lookup) {
dig_server_t *s;
void *ptr;
REQUIRE(lookup != NULL);
if (ISC_LIST_HEAD(lookup->q) != NULL)
return (ISC_FALSE);
/*
* At this point, we know there are no queries on the lookup,
* so can make it go away also.
*/
if (lookup->use_my_server_list) {
s = ISC_LIST_HEAD(lookup->my_server_list);
while (s != NULL) {
debug("freeing server %p belonging to %p",
s, lookup);
ptr = s;
s = ISC_LIST_NEXT(s, link);
ISC_LIST_DEQUEUE(lookup->my_server_list,
(dig_server_t *)ptr, link);
isc_mem_free(mctx, ptr);
}
}
if (lookup->sendmsg != NULL)
dns_message_destroy(&lookup->sendmsg);
if (lookup->querysig != NULL) {
debug("freeing buffer %p", lookup->querysig);
isc_buffer_free(&lookup->querysig);
}
if (lookup->timer != NULL)
isc_timer_detach(&lookup->timer);
ptr = lookup;
lookup = ISC_LIST_NEXT(lookup, link);
ISC_LIST_DEQUEUE(lookup_list, (dig_lookup_t *)ptr, link);
isc_mem_free(mctx, ptr);
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
* started yet.
*/
static void
begin_next_lookup(void) {
dig_lookup_t *next;
next = ISC_LIST_HEAD(lookup_list);
if (next != NULL) {
setup_lookup(next);
do_lookup(next);
} else {
check_if_done();
}
}
/*
* WARNING: The following routine may invalidate the lookup pointer.
* Never depend on being able to reference lookup or query pointers on the
* current lookup after calling this.
*/
static void
check_next_lookup(dig_lookup_t *lookup) {
dig_query_t *query;
isc_boolean_t still_working=ISC_FALSE;
if (free_now)
return (ISC_TRUE);
INSIST(!free_now);
debug("check_next_lookup(%p)", lookup);
debug("is_lookup_done(%p)", lookup);
for (query = ISC_LIST_HEAD(lookup->q);
query != NULL;
query = ISC_LIST_NEXT(query, link)) {
@@ -637,54 +732,11 @@ check_next_lookup(dig_lookup_t *lookup) {
}
}
if (still_working)
return (ISC_FALSE);
debug("have %d retries left for %s",
lookup->retries-1, lookup->textname);
debug("lookup %s pending", lookup->pending ? "is" : "is not");
next = ISC_LIST_NEXT(lookup, link);
if (lookup->tcp_mode) {
if (next == NULL) {
debug("shutting down", stderr);
dighost_shutdown();
return (ISC_TRUE);
}
if (next->sendmsg == NULL) {
debug("setting up for TCP");
setup_lookup(next);
do_lookup(next);
}
} else {
if (!lookup->pending) {
if (next == NULL) {
debug("shutting down", stderr);
dighost_shutdown();
return (ISC_TRUE);
}
if (next->sendmsg == NULL) {
debug("setting up for UDP");
setup_lookup(next);
do_lookup(next);
}
} else {
if (lookup->retries > 1) {
debug("retrying");
lookup->retries --;
if (lookup->timer != NULL)
isc_timer_detach(&lookup->timer);
send_udp(lookup);
} else {
debug("cancelling");
return(cancel_lookup(lookup));
}
}
}
return (ISC_FALSE);
return;
if (try_clear_lookup(lookup))
begin_next_lookup();
}
static void
followup_lookup(dns_message_t *msg, dig_query_t *query,
dns_section_t section) {
@@ -699,9 +751,9 @@ followup_lookup(dns_message_t *msg, dig_query_t *query,
isc_boolean_t success = ISC_FALSE;
int len;
INSIST(!free_now);
debug("followup_lookup()");
if (free_now)
return;
result = dns_message_firstname(msg,section);
if (result != ISC_R_SUCCESS) {
debug("firstname returned %s",
@@ -810,9 +862,9 @@ next_origin(dns_message_t *msg, dig_query_t *query) {
UNUSED(msg);
INSIST(!free_now);
debug("next_origin()");
if (free_now)
return;
debug("following up %s", query->lookup->textname);
if (query->lookup->origin == NULL) {
@@ -903,12 +955,10 @@ setup_lookup(dig_lookup_t *lookup) {
char store[MXNAME];
REQUIRE(lookup != NULL);
INSIST(!free_now);
debug("setup_lookup(%p)",lookup);
if (free_now)
return;
debug("setting up for looking up %s @%p->%p",
lookup->textname, lookup,
lookup->link.next);
@@ -1142,12 +1192,12 @@ send_done(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
debug("send_done()");
sendcount--;
debug("sendcount=%d",sendcount);
INSIST(sendcount >= 0);
}
/*
* Return ISC_TRUE if we're in the process of shutting down
*/
static isc_boolean_t
void
cancel_lookup(dig_lookup_t *lookup) {
dig_query_t *query = NULL;
@@ -1163,12 +1213,13 @@ cancel_lookup(dig_lookup_t *lookup) {
ISC_SOCKCANCEL_ALL);
isc_socket_detach(&query->sock);
sockcount--;
debug("socket = %d", sockcount);
debug("sockcount=%d", sockcount);
INSIST(sockcount >= 0);
check_if_done();
}
}
lookup->pending = ISC_FALSE;
lookup->retries = 0;
return(check_next_lookup(lookup));
}
static void
@@ -1214,8 +1265,8 @@ for (query = ISC_LIST_HEAD(lookup->q);
result = isc_socket_recvv(query->sock, &query->recvlist, 1,
global_task, recv_done, query);
check_result(result, "isc_socket_recvv");
sendcount++;
debug("sent count number %d", sendcount);
recvcount++;
debug("recvcount=%d", recvcount);
ISC_LIST_ENQUEUE(query->sendlist, &lookup->sendbuf, link);
debug("sending a request");
result = isc_time_now(&query->time_sent);
@@ -1225,6 +1276,7 @@ for (query = ISC_LIST_HEAD(lookup->q);
global_task, send_done, query,
&query->sockaddr, NULL);
check_result(result, "isc_socket_sendtov");
sendcount++;
}
}
@@ -1253,27 +1305,26 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
q != NULL;
q = ISC_LIST_NEXT(q, link)) {
if (q->working) {
if (!free_now) {
isc_buffer_clear(b);
result = isc_sockaddr_totext(&q->sockaddr, b);
check_result(result, "isc_sockaddr_totext");
isc_buffer_usedregion(b, &r);
if ((q->lookup->retries > 1) &&
(!q->lookup->tcp_mode))
printf(";; Connection to server %.*s "
"for %s timed out. "
"Retrying %d.\n",
(int)r.length, r.base,
q->lookup->textname,
q->lookup->retries-1);
else {
printf(";; Connection to "
"server %.*s "
"for %s timed out. "
"Giving up.\n",
(int)r.length, r.base,
q->lookup->textname);
}
INSIST(!free_now);
isc_buffer_clear(b);
result = isc_sockaddr_totext(&q->sockaddr, b);
check_result(result, "isc_sockaddr_totext");
isc_buffer_usedregion(b, &r);
if ((q->lookup->retries > 1) &&
(!q->lookup->tcp_mode))
printf(";; Connection to server %.*s "
"for %s timed out. "
"Retrying %d.\n",
(int)r.length, r.base,
q->lookup->textname,
q->lookup->retries-1);
else {
printf(";; Connection to "
"server %.*s "
"for %s timed out. "
"Giving up.\n",
(int)r.length, r.base,
q->lookup->textname);
}
isc_socket_cancel(q->sock, task,
ISC_SOCKCANCEL_ALL);
@@ -1295,16 +1346,12 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
isc_uint16_t length;
REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
INSIST(!free_now);
UNUSED(task);
debug("tcp_length_done()");
if (free_now) {
isc_event_free(&event);
return;
}
sevent = (isc_socketevent_t *)event;
query = event->ev_arg;
@@ -1326,9 +1373,10 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
isc_result_totext(sevent->result));
isc_buffer_free(&b);
query->working = ISC_FALSE;
sockcount--;
debug("socket = %d",sockcount);
isc_socket_detach(&query->sock);
sockcount--;
debug("sockcount=%d",sockcount);
INSIST(sockcount >= 0);
isc_event_free(&event);
check_next_lookup(query->lookup);
return;
@@ -1354,7 +1402,9 @@ tcp_length_done(isc_task_t *task, isc_event_t *event) {
result = isc_socket_recvv(query->sock, &query->recvlist, length, task,
recv_done, query);
check_result(result, "isc_socket_recvv");
debug("resubmitted recv request with length %d", length);
recvcount++;
debug("resubmitted recv request with length %d, recvcount=%d",
length, recvcount);
isc_event_free(&event);
}
@@ -1362,16 +1412,16 @@ static void
launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
isc_result_t result;
debug("launch_next_query()");
INSIST(!free_now);
if (free_now)
return;
debug("launch_next_query()");
if (!query->lookup->pending) {
debug("ignoring launch_next_query because !pending");
sockcount--;
debug("socket = %d", sockcount);
isc_socket_detach(&query->sock);
sockcount--;
debug("sockcount=%d", sockcount);
INSIST(sockcount >= 0);
query->working = ISC_FALSE;
query->waiting_connect = ISC_FALSE;
check_next_lookup(query->lookup);
@@ -1391,14 +1441,17 @@ launch_next_query(dig_query_t *query, isc_boolean_t include_question) {
result = isc_socket_recvv(query->sock, &query->lengthlist, 0,
global_task, tcp_length_done, query);
check_result(result, "isc_socket_recvv");
sendcount++;
recvcount++;
debug("recvcount=%d",recvcount);
if (!query->first_soa_rcvd) {
debug("sending a request");
result = isc_time_now(&query->time_sent);
check_result(result, "isc_time_now");
result = isc_socket_sendv(query->sock, &query->sendlist,
global_task, send_done, query);
check_result(result, "isc_socket_recvv");
check_result(result, "isc_socket_sendv");
sendcount++;
debug("sendcount=%d", sendcount);
}
query->waiting_connect = ISC_FALSE;
check_next_lookup(query->lookup);
@@ -1416,14 +1469,10 @@ connect_done(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
INSIST(!free_now);
debug("connect_done()");
if (free_now) {
isc_event_free(&event);
return;
}
sevent = (isc_socketevent_t *)event;
query = sevent->ev_arg;
@@ -1644,38 +1693,30 @@ recv_done(isc_task_t *task, isc_event_t *event) {
isc_buffer_t ab;
char abspace[MXNAME];
isc_region_t r;
dig_lookup_t *n;
dig_lookup_t *n, *l;
isc_boolean_t docancel = ISC_FALSE;
isc_boolean_t result_bool;
unsigned int local_timeout;
UNUSED(task);
INSIST(!free_now);
debug("recv_done()");
if (free_now) {
isc_event_free(&event);
return;
}
recvcount--;
debug("recvcount=%d", recvcount);
INSIST(recvcount >= 0);
query = event->ev_arg;
debug("lookup=%p, query=%p", query->lookup, query);
if (free_now) {
debug("bailing out, since freeing now");
isc_event_free(&event);
return;
}
l = query->lookup;
sendcount--;
debug("in recv_done, counter down to %d", sendcount);
REQUIRE(event->ev_type == ISC_SOCKEVENT_RECVDONE);
sevent = (isc_socketevent_t *)event;
if ((query->lookup->tcp_mode) &&
(query->lookup->timer != NULL))
isc_timer_touch(query->lookup->timer);
if (!query->lookup->pending && !query->lookup->ns_search_only) {
if ((l->tcp_mode) && (l->timer != NULL))
isc_timer_touch(l->timer);
if (!l->pending && !l->ns_search_only) {
debug("no longer pending. Got %s",
isc_result_totext(sevent->result));
@@ -1683,10 +1724,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
query->waiting_connect = ISC_FALSE;
isc_event_free(&event);
/*
* In this case, we don't actually use result_bool
*/
result_bool = cancel_lookup(query->lookup);
clear_query(query);
check_next_lookup(l);
return;
}
@@ -1698,24 +1737,24 @@ recv_done(isc_task_t *task, isc_event_t *event) {
check_result(result, "dns_message_create");
if (key != NULL) {
debug("querysig 1 is %p", query->lookup->querysig);
if (query->lookup->querysig == NULL) {
debug("querysig 1 is %p", l->querysig);
if (l->querysig == NULL) {
debug("getting initial querysig");
result = dns_message_getquerytsig(
query->lookup->sendmsg,
mctx, &query->lookup->querysig);
l->sendmsg,
mctx, &l->querysig);
check_result(result,
"dns_message_getquerytsig");
}
result = dns_message_setquerytsig(msg,
query->lookup->querysig);
l->querysig);
check_result(result, "dns_message_setquerytsig");
result = dns_message_settsigkey(msg, key);
check_result(result, "dns_message_settsigkey");
msg->tsigctx = query->lookup->tsigctx;
if (query->lookup->msgcounter != 0)
msg->tsigctx = l->tsigctx;
if (l->msgcounter != 0)
msg->tcp_continuation = 1;
query->lookup->msgcounter++;
l->msgcounter++;
}
debug("before parse starts");
result = dns_message_parse(msg, b, ISC_TRUE);
@@ -1724,18 +1763,20 @@ recv_done(isc_task_t *task, isc_event_t *event) {
hex_dump(b);
query->working = ISC_FALSE;
query->waiting_connect = ISC_FALSE;
if (!query->lookup->tcp_mode) {
if (!l->tcp_mode) {
printf(";; Retrying in TCP mode.\n");
n = requeue_lookup(query->lookup, ISC_TRUE);
n = requeue_lookup(l, ISC_TRUE);
n->tcp_mode = ISC_TRUE;
}
dns_message_destroy(&msg);
isc_event_free(&event);
result_bool = cancel_lookup(query->lookup);
clear_query(query);
cancel_lookup(l);
check_next_lookup(l);
return;
}
if (key != NULL) {
debug("querysig 2 is %p", query->lookup->querysig);
debug("querysig 2 is %p", l->querysig);
debug("before verify");
result = dns_tsig_verify(&query->recvbuf, msg,
NULL, keyring);
@@ -1745,29 +1786,29 @@ recv_done(isc_task_t *task, isc_event_t *event) {
dns_result_totext(result));
validated = ISC_FALSE;
}
query->lookup->tsigctx = msg->tsigctx;
if (query->lookup->querysig != NULL) {
l->tsigctx = msg->tsigctx;
if (l->querysig != NULL) {
debug("freeing querysig buffer %p",
query->lookup->querysig);
isc_buffer_free(&query->lookup->querysig);
l->querysig);
isc_buffer_free(&l->querysig);
}
result = dns_message_getquerytsig(msg, mctx,
&query->lookup->querysig);
&l->querysig);
check_result(result,"dns_message_getquerytsig");
debug("querysig 3 is %p", query->lookup->querysig);
debug("querysig 3 is %p", l->querysig);
}
debug("after parse");
if (query->lookup->xfr_q == NULL) {
query->lookup->xfr_q = query;
if (l->xfr_q == NULL) {
l->xfr_q = query;
/*
* Once we are in the XFR message, increase
* the timeout to much longer, so brief network
* outages won't cause the XFR to abort
*/
if ((timeout != INT_MAX) &&
(query->lookup->timer != NULL)) {
(l->timer != NULL)) {
if (timeout == 0) {
if (query->lookup->tcp_mode)
if (l->tcp_mode)
local_timeout = TCP_TIMEOUT;
else
local_timeout = UDP_TIMEOUT;
@@ -1779,62 +1820,62 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
debug("have local timeout of %d",
local_timeout);
isc_interval_set(&query->lookup->interval,
isc_interval_set(&l->interval,
local_timeout, 0);
result = isc_timer_reset(query->lookup->timer,
result = isc_timer_reset(l->timer,
isc_timertype_once,
NULL,
&query->lookup->interval,
&l->interval,
ISC_FALSE);
check_result(result, "isc_timer_reset");
}
}
if (query->lookup->xfr_q == query) {
if ((query->lookup->trace)||
(query->lookup->ns_search_only)) {
if (l->xfr_q == query) {
if ((l->trace)||
(l->ns_search_only)) {
debug("in TRACE code");
if (show_details ||
(((dns_message_firstname(msg,
DNS_SECTION_ANSWER)
== ISC_R_SUCCESS)) &&
!query->lookup->trace_root)) {
!l->trace_root)) {
printmessage(query, msg, ISC_TRUE);
}
if ((msg->rcode != 0) &&
(query->lookup->origin != NULL)) {
(l->origin != NULL)) {
next_origin(msg, query);
} else {
result = dns_message_firstname
(msg,DNS_SECTION_ANSWER);
if ((result != ISC_R_SUCCESS) ||
query->lookup->trace_root)
l->trace_root)
followup_lookup(msg, query,
DNS_SECTION_AUTHORITY);
}
} else if ((msg->rcode != 0) &&
(query->lookup->origin != NULL)) {
(l->origin != NULL)) {
next_origin(msg, query);
if (show_details) {
printmessage(query, msg, ISC_TRUE);
}
} else {
if (query->first_soa_rcvd &&
query->lookup->doing_xfr)
l->doing_xfr)
printmessage(query, msg, ISC_FALSE);
else
printmessage(query, msg, ISC_TRUE);
}
} else if ((dns_message_firstname(msg, DNS_SECTION_ANSWER)
== ISC_R_SUCCESS) &&
query->lookup->ns_search_only &&
!query->lookup->trace_root ) {
l->ns_search_only &&
!l->trace_root ) {
printmessage(query, msg, ISC_TRUE);
}
if (query->lookup->pending)
if (l->pending)
debug("still pending.");
if (query->lookup->doing_xfr) {
if (query != query->lookup->xfr_q) {
if (l->doing_xfr) {
if (query != l->xfr_q) {
dns_message_destroy(&msg);
isc_event_free (&event);
query->working = ISC_FALSE;
@@ -1844,7 +1885,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
docancel = check_for_more_data(query, msg, sevent);
if (docancel) {
dns_message_destroy(&msg);
result_bool = cancel_lookup(query->lookup);
clear_query(query);
cancel_lookup(l);
}
if (msg != NULL)
dns_message_destroy(&msg);
@@ -1852,7 +1894,7 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
else {
if ((msg->rcode == 0) ||
(query->lookup->origin == NULL)) {
(l->origin == NULL)) {
isc_buffer_init(&ab, abspace, MXNAME);
result = isc_sockaddr_totext(&sevent->address,
&ab);
@@ -1869,17 +1911,16 @@ recv_done(isc_task_t *task, isc_event_t *event) {
}
query->working = ISC_FALSE;
query->lookup->pending = ISC_FALSE;
result_bool = ISC_FALSE;
if (!query->lookup->ns_search_only ||
query->lookup->trace_root) {
dns_message_destroy(&msg);
result_bool = cancel_lookup(query->lookup);
cancel_lookup(l);
}
if (msg != NULL)
dns_message_destroy(&msg);
isc_event_free(&event);
if ((!free_now) && (!result_bool))
check_next_lookup(query->lookup);
clear_query(query);
check_next_lookup(l);
}
return;
}
@@ -1892,7 +1933,8 @@ recv_done(isc_task_t *task, isc_event_t *event) {
query->working = ISC_FALSE;
query->waiting_connect = ISC_FALSE;
isc_event_free(&event);
check_next_lookup(query->lookup);
clear_query(query);
check_next_lookup(l);
return;
}
fatal("recv_done got result %s",
@@ -1972,13 +2014,13 @@ do_lookup_tcp(dig_lookup_t *lookup) {
query->waiting_connect = ISC_TRUE;
get_address(query->servname, port, &query->sockaddr);
sockcount++;
debug("socket = %d",sockcount);
ENSURE(query->sock == NULL);
result = isc_socket_create(socketmgr,
isc_sockaddr_pf(&query->sockaddr),
isc_sockettype_tcp, &query->sock) ;
check_result(result, "isc_socket_create");
sockcount++;
debug("sockcount=%d",sockcount);
if (specified_source)
result = isc_socket_bind(query->sock, &bind_address);
else {
@@ -2011,12 +2053,12 @@ do_lookup_udp(dig_lookup_t *lookup) {
query->waiting_connect = ISC_FALSE;
get_address(query->servname, port, &query->sockaddr);
sockcount++;
debug("socket = %d", sockcount);
result = isc_socket_create(socketmgr,
isc_sockaddr_pf(&query->sockaddr),
isc_sockettype_udp, &query->sock);
check_result(result, "isc_socket_create");
sockcount++;
debug("sockcount=%d", sockcount);
if (specified_source)
result = isc_socket_bind(query->sock, &bind_address);
else {
@@ -2048,10 +2090,9 @@ void
start_lookup(void) {
dig_lookup_t *lookup;
debug("start_lookup()");
INSIST(!free_now);
if (free_now)
return;
debug("start_lookup()");
lookup = ISC_LIST_HEAD(lookup_list);
if (lookup != NULL) {
@@ -2067,20 +2108,16 @@ onrun_callback(isc_task_t *task, isc_event_t *event) {
start_lookup();
}
void
free_lists(void) {
void *ptr;
#if 0
/*
* This will be used in the SIGINT handler, and perhaps other places.
*/
static void
cancel_all(void) {
dig_lookup_t *l;
dig_query_t *q;
dig_server_t *s;
dig_searchlist_t *o;
debug("free_lists()");
if (free_now)
return;
free_now = ISC_TRUE;
debug ("cancel_all()");
l = ISC_LIST_HEAD(lookup_list);
while (l != NULL) {
@@ -2095,12 +2132,35 @@ free_lists(void) {
ISC_SOCKCANCEL_ALL);
isc_socket_detach(&q->sock);
sockcount--;
debug("socket = %d",sockcount);
debug("sockcount=%d",sockcount);
INSIST(sockcount >= 0);
check_if_done();
}
q = ISC_LIST_NEXT(q, link);
}
l = ISC_LIST_NEXT(l, link);
}
check_if_done();
}
#endif
void
free_lists(void) {
void *ptr;
dig_server_t *s;
dig_searchlist_t *o;
debug("free_lists()");
REQUIRE(sockcount == 0);
REQUIRE(recvcount == 0);
REQUIRE(sendcount == 0);
INSIST(ISC_LIST_HEAD(lookup_list) == NULL);
INSIST(!free_now);
free_now = ISC_TRUE;
s = ISC_LIST_HEAD(server_list);
while (s != NULL) {
debug("freeing global server %p", s);
@@ -2136,47 +2196,6 @@ free_lists(void) {
if (namebuf != NULL)
isc_buffer_free(&namebuf);
l = ISC_LIST_HEAD(lookup_list);
while (l != NULL) {
q = ISC_LIST_HEAD(l->q);
while (q != NULL) {
debug("freeing query %p, belonging to %p",
q, l);
if (ISC_LINK_LINKED(&q->recvbuf, link))
ISC_LIST_DEQUEUE(q->recvlist, &q->recvbuf,
link);
if (ISC_LINK_LINKED(&q->lengthbuf, link))
ISC_LIST_DEQUEUE(q->lengthlist, &q->lengthbuf,
link);
isc_buffer_invalidate(&q->recvbuf);
isc_buffer_invalidate(&q->lengthbuf);
ptr = q;
q = ISC_LIST_NEXT(q, link);
isc_mem_free(mctx, ptr);
}
if (l->use_my_server_list) {
s = ISC_LIST_HEAD(l->my_server_list);
while (s != NULL) {
debug("freeing server %p belonging to %p",
s, l);
ptr = s;
s = ISC_LIST_NEXT(s, link);
isc_mem_free(mctx, ptr);
}
}
if (l->sendmsg != NULL)
dns_message_destroy(&l->sendmsg);
if (l->querysig != NULL) {
debug("freeing buffer %p", l->querysig);
isc_buffer_free(&l->querysig);
}
ptr = l;
l = ISC_LIST_NEXT(l, link);
isc_mem_free(mctx, ptr);
}
if (keyring != NULL) {
debug("freeing keyring %p", keyring);
dns_tsigkeyring_destroy(&keyring);