From 24b58074bff76de26b292ba9c737008bb4b08cb0 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 20 Jan 2016 13:09:18 +0100 Subject: [PATCH] Prevent chain checks to be performed too early --- src/dnssec.c | 43 +++++++++++++++++++++++++++---------------- src/general.c | 42 +++++++++++++++++++++--------------------- src/general.h | 2 +- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 7cf54ec7..b4e55ac5 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -749,6 +749,8 @@ struct chain_head { struct chain_node { chain_node *parent; + + size_t lock; getdns_rrset dnskey; getdns_network_req *dnskey_req; @@ -878,6 +880,7 @@ static chain_head *add_rrset2val_chain(struct mem_funcs *mf, ; node_count ; node_count--, node = node->parent =&node[1], dname += *dname + 1) { + node->lock = 0; node->ds.name = dname; node->dnskey.name = dname; node->ds.rr_class = head->rrset.rr_class; @@ -1135,7 +1138,6 @@ static void val_chain_sched_soa_node(chain_node *node) { getdns_context *context; getdns_eventloop *loop; - getdns_dns_req *dnsreq; char name[1024]; context = node->chains->netreq->owner->context; @@ -1147,12 +1149,15 @@ static void val_chain_sched_soa_node(chain_node *node) DEBUG_SEC("schedule SOA lookup for %s\n", name); + node->lock++; if (! node->soa_req && - ! _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_SOA, - CD_extension(node->chains->netreq->owner), node, &dnsreq, NULL, - val_chain_node_soa_cb)) + _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_SOA, + CD_extension(node->chains->netreq->owner), node, &node->soa_req, + NULL, val_chain_node_soa_cb)) - node->soa_req = dnsreq->netreqs[0]; + node->soa_req = NULL; + + node->lock--; } /* A SOA lookup is scheduled as a last resort. No signatures were found and @@ -1183,7 +1188,6 @@ static void val_chain_sched_node(chain_node *node) { getdns_context *context; getdns_eventloop *loop; - getdns_dns_req *dnsreq; char name[1024]; context = node->chains->netreq->owner->context; @@ -1195,19 +1199,22 @@ static void val_chain_sched_node(chain_node *node) DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name); + node->lock++; if (! node->dnskey_req /* not scheduled */ && - ! _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DNSKEY, + _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DNSKEY, CD_extension(node->chains->netreq->owner), - node, &dnsreq, NULL, val_chain_node_cb)) + node, &node->dnskey_req, NULL, val_chain_node_cb)) - node->dnskey_req = dnsreq->netreqs[0]; + node->dnskey_req = NULL; if (! node->ds_req && node->parent /* not root */ && - ! _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS, + _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS, CD_extension(node->chains->netreq->owner), - node, &dnsreq, NULL, val_chain_node_cb)) + node, &node->ds_req, NULL, val_chain_node_cb)) - node->ds_req = dnsreq->netreqs[0]; + node->ds_req = NULL; + + node->lock--; } static void val_chain_sched(chain_head *head, const uint8_t *dname) @@ -1228,7 +1235,6 @@ static void val_chain_sched_ds_node(chain_node *node) { getdns_context *context; getdns_eventloop *loop; - getdns_dns_req *ds_req; char name[1024]; context = node->chains->netreq->owner->context; @@ -1241,12 +1247,15 @@ static void val_chain_sched_ds_node(chain_node *node) DEBUG_SEC("schedule DS lookup for %s\n", name); + node->lock++; if (! node->ds_req && node->parent /* not root */ && - ! _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS, + _getdns_general_loop(context, loop, name, GETDNS_RRTYPE_DS, CD_extension(node->chains->netreq->owner), - node, &ds_req, NULL, val_chain_node_cb)) + node, &node->ds_req, NULL, val_chain_node_cb)) - node->ds_req = ds_req->netreqs[0]; + node->ds_req = NULL; + + node->lock--; } static void val_chain_sched_ds(chain_head *head, const uint8_t *dname) @@ -2998,6 +3007,8 @@ static size_t count_outstanding_requests(chain_head *head) ; node ; node = node->parent) { + count += node->lock; + if (node->dnskey_req && node->dnskey_req->state != NET_REQ_FINISHED && node->dnskey_req->state != NET_REQ_CANCELED) diff --git a/src/general.c b/src/general.c index af156c05..43cd8724 100644 --- a/src/general.c +++ b/src/general.c @@ -442,7 +442,7 @@ validate_extensions(struct getdns_dict * extensions) static getdns_return_t getdns_general_ns(getdns_context *context, getdns_eventloop *loop, const char *name, uint16_t request_type, getdns_dict *extensions, - void *userarg, getdns_dns_req **dnsreq_p, + void *userarg, getdns_network_req **return_netreq_p, getdns_callback_t callbackfn, internal_cb_t internal_cb, int usenamespaces) { getdns_return_t r = GETDNS_RETURN_GOOD; @@ -473,8 +473,8 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, req->user_callback = callbackfn; req->internal_cb = internal_cb; - if (dnsreq_p) - *dnsreq_p = req; + if (return_netreq_p) + *return_netreq_p = req->netreqs[0]; _getdns_context_track_outbound_request(req); @@ -523,12 +523,12 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop, getdns_return_t _getdns_general_loop(getdns_context *context, getdns_eventloop *loop, const char *name, uint16_t request_type, getdns_dict *extensions, - void *userarg, getdns_dns_req **dnsreq_p, + void *userarg, getdns_network_req **netreq_p, getdns_callback_t callback, internal_cb_t internal_cb) { return getdns_general_ns(context, loop, name, request_type, extensions, - userarg, dnsreq_p, callback, internal_cb, 0); + userarg, netreq_p, callback, internal_cb, 0); } /* getdns_general_loop */ @@ -540,7 +540,7 @@ _getdns_address_loop(getdns_context *context, getdns_eventloop *loop, getdns_dict *my_extensions = extensions; getdns_return_t r; uint32_t value; - getdns_dns_req *dnsreq = NULL; + getdns_network_req *netreq = NULL; if (!my_extensions) { if (!(my_extensions=getdns_dict_create_with_context(context))) @@ -556,9 +556,9 @@ _getdns_address_loop(getdns_context *context, getdns_eventloop *loop, r = getdns_general_ns(context, loop, name, GETDNS_RRTYPE_AAAA, my_extensions, - userarg, &dnsreq, callback, NULL, 1); - if (dnsreq && transaction_id) - *transaction_id = dnsreq->trans_id; + userarg, &netreq, callback, NULL, 1); + if (netreq && transaction_id) + *transaction_id = netreq->owner->trans_id; if (my_extensions != extensions) getdns_dict_destroy(my_extensions); @@ -576,7 +576,7 @@ _getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop, uint16_t req_type; char name[1024]; getdns_return_t retval; - getdns_dns_req *dnsreq = NULL; + getdns_network_req *netreq= NULL; if ((retval = getdns_dict_get_bindata(address, "address_data", @@ -650,9 +650,9 @@ _getdns_hostname_loop(getdns_context *context, getdns_eventloop *loop, return GETDNS_RETURN_INVALID_PARAMETER; } retval = _getdns_general_loop(context, loop, name, req_type, - extensions, userarg, &dnsreq, callback, NULL); - if (dnsreq && transaction_id) - *transaction_id = dnsreq->trans_id; + extensions, userarg, &netreq, callback, NULL); + if (netreq && transaction_id) + *transaction_id = netreq->owner->trans_id; return retval; } /* getdns_hostname_loop */ @@ -662,11 +662,11 @@ _getdns_service_loop(getdns_context *context, getdns_eventloop *loop, getdns_transaction_t * transaction_id, getdns_callback_t callback) { getdns_return_t r; - getdns_dns_req *dnsreq = NULL; + getdns_network_req *netreq = NULL; r = getdns_general_ns(context, loop, name, GETDNS_RRTYPE_SRV, - extensions, userarg, &dnsreq, callback, NULL, 1); - if (dnsreq && transaction_id) - *transaction_id = dnsreq->trans_id; + extensions, userarg, &netreq, callback, NULL, 1); + if (netreq && transaction_id) + *transaction_id = netreq->owner->trans_id; return r; } /* getdns_service_loop */ @@ -680,14 +680,14 @@ getdns_general(getdns_context *context, getdns_callback_t callback) { getdns_return_t r; - getdns_dns_req *dnsreq = NULL; + getdns_network_req *netreq = NULL; if (!context) return GETDNS_RETURN_INVALID_PARAMETER; r = _getdns_general_loop(context, context->extension, name, request_type, extensions, - userarg, &dnsreq, callback, NULL); - if (dnsreq && transaction_id) - *transaction_id = dnsreq->trans_id; + userarg, &netreq, callback, NULL); + if (netreq && transaction_id) + *transaction_id = netreq->owner->trans_id; return r; } /* getdns_general */ diff --git a/src/general.h b/src/general.h index 58201056..e9a4529e 100644 --- a/src/general.h +++ b/src/general.h @@ -50,7 +50,7 @@ getdns_return_t _getdns_submit_netreq(getdns_network_req *netreq); getdns_return_t _getdns_general_loop(getdns_context *context, getdns_eventloop *loop, const char *name, uint16_t request_type, getdns_dict *extensions, - void *userarg, getdns_dns_req **dnsreq, + void *userarg, getdns_network_req **netreq_p, getdns_callback_t callbackfn, internal_cb_t internal_cb); getdns_return_t