mirror of https://github.com/getdnsapi/getdns.git
cancel_outstanding_requests by transaction_id
to prevent double frees as side effect of getdns_dns_req being canceled by user callbacks.
This commit is contained in:
parent
c7ae2f5011
commit
8fccd66813
|
@ -2983,38 +2983,34 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq)
|
||||||
static void
|
static void
|
||||||
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
||||||
{
|
{
|
||||||
*(*(getdns_dns_req ***)arg)++ = (getdns_dns_req *)node;
|
*(*(getdns_transaction_t**)arg)++ = ((getdns_dns_req*)node)->trans_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cancel_outstanding_requests(getdns_context* context)
|
cancel_outstanding_requests(getdns_context* context)
|
||||||
{
|
{
|
||||||
getdns_dns_req **dnsreqs, **dnsreq_a, **dnsreq_i;
|
getdns_transaction_t *trans_ids, *tids_a, *tids_i;
|
||||||
|
|
||||||
if (context->outbound_requests.count == 0)
|
if (context->outbound_requests.count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dnsreq_i = dnsreq_a = dnsreqs = GETDNS_XMALLOC(context->my_mf,
|
tids_i = tids_a = trans_ids = GETDNS_XMALLOC(context->my_mf,
|
||||||
getdns_dns_req *, context->outbound_requests.count);
|
getdns_transaction_t, context->outbound_requests.count);
|
||||||
|
|
||||||
_getdns_traverse_postorder(&context->outbound_requests,
|
_getdns_traverse_postorder(&context->outbound_requests,
|
||||||
accumulate_outstanding_transactions, &dnsreq_a);
|
accumulate_outstanding_transactions, &tids_a);
|
||||||
|
|
||||||
while (dnsreq_i < dnsreq_a) {
|
while (tids_i < tids_a) {
|
||||||
getdns_dns_req *dnsreq = *dnsreq_i;
|
|
||||||
|
|
||||||
if (dnsreq->user_callback) {
|
/* We have to cancel by transaction_id because we do not know
|
||||||
dnsreq->context->processing = 1;
|
* what happens when the user_callback is called. It might
|
||||||
dnsreq->user_callback(dnsreq->context,
|
* delete getdns_dns_req's that were scheduled to be canceled.
|
||||||
GETDNS_CALLBACK_CANCEL, NULL,
|
* The extra lookup with transaction_id makes sure we do not
|
||||||
dnsreq->user_pointer, dnsreq->trans_id);
|
* access freed memory.
|
||||||
dnsreq->context->processing = 0;
|
*/
|
||||||
|
(void) getdns_cancel_callback(context, *tids_i++);
|
||||||
}
|
}
|
||||||
_getdns_context_cancel_request(dnsreq);
|
GETDNS_FREE(context->my_mf, trans_ids);
|
||||||
|
|
||||||
dnsreq_i += 1;
|
|
||||||
}
|
|
||||||
GETDNS_FREE(context->my_mf, dnsreqs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STUB_NATIVE_DNSSEC
|
#ifndef STUB_NATIVE_DNSSEC
|
||||||
|
|
Loading…
Reference in New Issue