From a435932b04c4cc124863899525063b85c3ada969 Mon Sep 17 00:00:00 2001 From: wtoorop Date: Thu, 23 Jun 2016 14:02:55 +0200 Subject: [PATCH] Features/call reporting timeout (#1) * Timed out and canceled netreqs are finished too * Minor code duplication elemination * Blah typo * Embarrassing logic error --- src/dnssec.c | 12 +++--------- src/general.c | 3 +-- src/stub.c | 8 +++----- src/types-internal.h | 16 +++++++++------- src/util-internal.c | 45 ++++++++++++-------------------------------- 5 files changed, 28 insertions(+), 56 deletions(-) diff --git a/src/dnssec.c b/src/dnssec.c index 95c8cbbf..2e6425fb 100644 --- a/src/dnssec.c +++ b/src/dnssec.c @@ -2776,19 +2776,13 @@ static size_t count_outstanding_requests(chain_head *head) count += node->lock; - if (node->dnskey_req && - node->dnskey_req->state != NET_REQ_FINISHED && - node->dnskey_req->state != NET_REQ_CANCELED) + if (!_getdns_netreq_finished(node->dnskey_req)) count++; - if (node->ds_req && - node->ds_req->state != NET_REQ_FINISHED && - node->ds_req->state != NET_REQ_CANCELED) + if (!_getdns_netreq_finished(node->ds_req)) count++; - if (node->soa_req && - node->soa_req->state != NET_REQ_FINISHED && - node->soa_req->state != NET_REQ_CANCELED) + if (!_getdns_netreq_finished(node->soa_req)) count++; } return count + count_outstanding_requests(head->next); diff --git a/src/general.c b/src/general.c index 4b80dbdd..9de39116 100644 --- a/src/general.c +++ b/src/general.c @@ -104,8 +104,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req) int results_found = 0, r; for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++) - if (netreq->state != NET_REQ_FINISHED && - netreq->state != NET_REQ_CANCELED) + if (!_getdns_netreq_finished(netreq)) return; else if (netreq->response_len > 0) results_found = 1; diff --git a/src/stub.c b/src/stub.c index 2126ee21..4aa14dae 100644 --- a/src/stub.c +++ b/src/stub.c @@ -565,14 +565,12 @@ stub_timeout_cb(void *userarg) stub_next_upstream(netreq); stub_cleanup(netreq); if (netreq->fd >= 0) close(netreq->fd); - if (netreq->owner->user_callback) { - netreq->state = NET_REQ_TIMED_OUT; + netreq->state = NET_REQ_TIMED_OUT; + if (netreq->owner->user_callback) { netreq->debug_end_time = _getdns_get_time_as_uintt64(); (void) _getdns_context_request_timed_out(netreq->owner); - } else { - netreq->state = NET_REQ_FINISHED; + } else _getdns_check_dns_req_complete(netreq->owner); - } } diff --git a/src/types-internal.h b/src/types-internal.h index a43bd8f6..6f7d99ea 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -154,11 +154,12 @@ priv_getdns_context_mf(getdns_context *context); typedef enum network_req_state_enum { - NET_REQ_NOT_SENT, - NET_REQ_IN_FLIGHT, - NET_REQ_FINISHED, - NET_REQ_CANCELED, - NET_REQ_TIMED_OUT + NET_REQ_NOT_SENT = 0, + NET_REQ_IN_FLIGHT = 1, + NET_REQ_FINISHED = 2, /* Finish type in bits 2 and 3 */ + NET_REQ_CANCELED = 6, /* 2 + (1 << 2) */ + NET_REQ_TIMED_OUT = 10, /* 2 + (2 << 2) */ + NET_REQ_ERRORED = 14 /* 2 + (3 << 2) */ } network_req_state; @@ -256,11 +257,12 @@ typedef struct getdns_network_req uint8_t *response; size_t wire_data_sz; uint8_t wire_data[]; - - } getdns_network_req; +static inline int _getdns_netreq_finished(getdns_network_req *req) +{ return !req || (req->state & NET_REQ_FINISHED); } + /** * dns request - manages a number of network requests and * the initial data passed to getdns_general diff --git a/src/util-internal.c b/src/util-internal.c index f3295ec4..3a70f81c 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -1109,6 +1109,18 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) for ( netreq_p = completed_request->netreqs ; (netreq = *netreq_p) ; netreq_p++) { + if (call_reporting && ( netreq->response_len + || netreq->state == NET_REQ_TIMED_OUT)) { + if (!(netreq_debug = + _getdns_create_call_reporting_dict(context,netreq))) + goto error; + + if (_getdns_list_append_this_dict( + call_reporting, netreq_debug)) + goto error; + + netreq_debug = NULL; + } if (! netreq->response_len) continue; @@ -1171,43 +1183,10 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) getdns_dict_destroy(reply); goto error; } - - if (call_reporting) { - if (!(netreq_debug = - _getdns_create_call_reporting_dict(context,netreq))) - goto error; - - if (_getdns_list_append_this_dict( - call_reporting, netreq_debug)) { - - getdns_dict_destroy(netreq_debug); - goto error; - } - } - if (_getdns_list_append_const_bindata(replies_full, netreq->response_len, netreq->response)) goto error; } - if (!nreplies && call_reporting) { - for ( netreq_p = completed_request->netreqs - ; (netreq = *netreq_p) ; netreq_p++) { - /* Add call_reporting info for timed out request */ - if (netreq->state == NET_REQ_TIMED_OUT) { - if (!(netreq_debug = - _getdns_create_call_reporting_dict(context,netreq))) - goto error; - - if (_getdns_list_append_this_dict( - call_reporting, netreq_debug)) { - - getdns_dict_destroy(netreq_debug); - goto error; - } - } - } - } - if (_getdns_dict_set_this_list(result, "replies_tree", replies_tree)) goto error; replies_tree = NULL;