From 3634fff4dd42857c1a270746c4a260771a9c8777 Mon Sep 17 00:00:00 2001 From: Robert Groenenberg Date: Mon, 20 Jun 2016 18:39:15 +0200 Subject: [PATCH 1/3] Return call_reporting info in case of timeout, so that we can see which server did not respond. --- src/stub.c | 7 +++++-- src/types-internal.h | 3 ++- src/util-internal.c | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/stub.c b/src/stub.c index 2962b3fb..488da2fd 100644 --- a/src/stub.c +++ b/src/stub.c @@ -91,6 +91,7 @@ static int upstream_connect(getdns_upstream *upstream, static int fallback_on_write(getdns_network_req *netreq); static void stub_timeout_cb(void *userarg); +static uint64_t _getdns_get_time_as_uintt64() /*****************************/ /* General utility functions */ /*****************************/ @@ -564,9 +565,11 @@ stub_timeout_cb(void *userarg) stub_next_upstream(netreq); stub_cleanup(netreq); if (netreq->fd >= 0) close(netreq->fd); - if (netreq->owner->user_callback) + if (netreq->owner->user_callback) { + netreq->state = NET_REQ_TIMED_OUT; + netreq->debug_end_time = _getdns_get_time_as_uintt64(); (void) _getdns_context_request_timed_out(netreq->owner); - else { + } else { netreq->state = NET_REQ_FINISHED; _getdns_check_dns_req_complete(netreq->owner); } diff --git a/src/types-internal.h b/src/types-internal.h index f63fde13..a43bd8f6 100644 --- a/src/types-internal.h +++ b/src/types-internal.h @@ -157,7 +157,8 @@ typedef enum network_req_state_enum NET_REQ_NOT_SENT, NET_REQ_IN_FLIGHT, NET_REQ_FINISHED, - NET_REQ_CANCELED + NET_REQ_CANCELED, + NET_REQ_TIMED_OUT } network_req_state; diff --git a/src/util-internal.c b/src/util-internal.c index ca04c7f5..f3295ec4 100644 --- a/src/util-internal.c +++ b/src/util-internal.c @@ -1189,6 +1189,25 @@ _getdns_create_getdns_response(getdns_dns_req *completed_request) 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; From 60c6c8d8ca66f3f64dfc41c2f66dc539bbd8fd53 Mon Sep 17 00:00:00 2001 From: Robert Groenenberg Date: Tue, 21 Jun 2016 13:19:11 +0200 Subject: [PATCH 2/3] Fixed build --- src/stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stub.c b/src/stub.c index 488da2fd..2126ee21 100644 --- a/src/stub.c +++ b/src/stub.c @@ -91,7 +91,7 @@ static int upstream_connect(getdns_upstream *upstream, static int fallback_on_write(getdns_network_req *netreq); static void stub_timeout_cb(void *userarg); -static uint64_t _getdns_get_time_as_uintt64() +static uint64_t _getdns_get_time_as_uintt64(); /*****************************/ /* General utility functions */ /*****************************/ From a435932b04c4cc124863899525063b85c3ada969 Mon Sep 17 00:00:00 2001 From: wtoorop Date: Thu, 23 Jun 2016 14:02:55 +0200 Subject: [PATCH 3/3] 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;