mirror of https://github.com/getdnsapi/getdns.git
Fix callbacks during scheduling in DNSSEC code too
This commit is contained in:
parent
15271d0438
commit
d61e64c9c7
34
src/dnssec.c
34
src/dnssec.c
|
@ -736,6 +736,8 @@ typedef struct chain_node chain_node;
|
|||
struct chain_head {
|
||||
struct mem_funcs my_mf;
|
||||
|
||||
size_t lock;
|
||||
|
||||
chain_head *next;
|
||||
chain_node *parent;
|
||||
size_t node_count; /* Number of nodes attached directly
|
||||
|
@ -857,6 +859,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
|
|||
head = *chain_p = (chain_head *)region;
|
||||
|
||||
head->my_mf = *mf;
|
||||
head->lock = 1;
|
||||
head->next = NULL;
|
||||
head->rrset.name = head->name_spc;
|
||||
memcpy(head->name_spc, rrset->name, dname_len);
|
||||
|
@ -1319,6 +1322,7 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq)
|
|||
default : check_chain_complete(node->chains);
|
||||
return;
|
||||
}
|
||||
node->lock++;
|
||||
n_signers = 0;
|
||||
for ( i = rrset_iter_init(&i_spc,netreq->response,netreq->response_len)
|
||||
; i
|
||||
|
@ -1344,6 +1348,7 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq)
|
|||
*/
|
||||
val_chain_sched_soa_node(node->parent);
|
||||
|
||||
node->lock--;
|
||||
check_chain_complete(node->chains);
|
||||
}
|
||||
|
||||
|
@ -1363,17 +1368,21 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq)
|
|||
! _dname_equal(node->ds.name, rrset->name))
|
||||
node = node->parent;
|
||||
|
||||
if (node)
|
||||
if (node) {
|
||||
node->lock++;
|
||||
val_chain_sched_ds_node(node);
|
||||
else {
|
||||
} else {
|
||||
/* SOA for a different name */
|
||||
node = (chain_node *)dnsreq->user_pointer;
|
||||
node->lock++;
|
||||
val_chain_sched_soa_node(node->parent);
|
||||
}
|
||||
|
||||
} else if (node->parent)
|
||||
} else if (node->parent) {
|
||||
node->lock++;
|
||||
val_chain_sched_soa_node(node->parent);
|
||||
|
||||
}
|
||||
node->lock--;
|
||||
check_chain_complete(node->chains);
|
||||
}
|
||||
|
||||
|
@ -3003,7 +3012,7 @@ static size_t count_outstanding_requests(chain_head *head)
|
|||
if (!head)
|
||||
return 0;
|
||||
|
||||
for ( node = head->parent, count = 0
|
||||
for ( node = head->parent, count = head->lock
|
||||
; node
|
||||
; node = node->parent) {
|
||||
|
||||
|
@ -3245,6 +3254,7 @@ static void check_chain_complete(chain_head *chain)
|
|||
}
|
||||
|
||||
/* Final user callback */
|
||||
dnsreq->validating = 0;
|
||||
_getdns_call_user_callback(dnsreq, response_dict);
|
||||
}
|
||||
|
||||
|
@ -3252,7 +3262,11 @@ static void check_chain_complete(chain_head *chain)
|
|||
void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
||||
{
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
chain_head *chain = NULL;
|
||||
chain_head *chain = NULL, *chain_p;
|
||||
|
||||
if (dnsreq->validating)
|
||||
return;
|
||||
dnsreq->validating = 1;
|
||||
|
||||
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
||||
if (! netreq->response
|
||||
|
@ -3277,11 +3291,15 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
|||
, netreq
|
||||
);
|
||||
}
|
||||
if (chain)
|
||||
if (chain) {
|
||||
for (chain_p = chain; chain_p; chain_p = chain_p->next)
|
||||
chain_p->lock--;
|
||||
check_chain_complete(chain);
|
||||
else
|
||||
} else {
|
||||
dnsreq->validating = 0;
|
||||
_getdns_call_user_callback(dnsreq,
|
||||
_getdns_create_getdns_response(dnsreq));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -903,6 +903,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
result->finished_next = NULL;
|
||||
result->freed = NULL;
|
||||
result->validating = 0;
|
||||
|
||||
network_req_init(result->netreqs[0], result,
|
||||
request_type, dnssec_extension_set, with_opt,
|
||||
|
|
|
@ -304,10 +304,15 @@ typedef struct getdns_dns_req {
|
|||
int dnssec_ok_checking_disabled;
|
||||
int is_sync_request;
|
||||
|
||||
/* Integer pointed to by pointer will be set to 1 (if set),
|
||||
* before the request is freed.
|
||||
* To be used by _getdns_submit_netreq only!
|
||||
/* The validating and freed variables are used to make sure a single
|
||||
* code path is followed while processing a DNS request, even when
|
||||
* callbacks are already fired whilst the registering/scheduling call
|
||||
* (i.e. ub_resolve_event) has not returned yet.
|
||||
*
|
||||
* validating is touched by _getdns_get_validation_chain only and
|
||||
* freed is touched by _getdns_submit_netreq only
|
||||
*/
|
||||
int validating;
|
||||
int *freed;
|
||||
|
||||
/* internally scheduled request */
|
||||
|
|
Loading…
Reference in New Issue