mirror of https://github.com/getdnsapi/getdns.git
Track netreqs "in flight"
This commit is contained in:
parent
b8f43c8acd
commit
14c9f3aafc
|
@ -1330,6 +1330,8 @@ getdns_context_create_with_extended_memory_functions(
|
|||
|
||||
_getdns_rbtree_init(&result->outbound_requests, transaction_id_cmp);
|
||||
_getdns_rbtree_init(&result->local_hosts, local_host_cmp);
|
||||
/* TODO: Initialize pending_netreqs */
|
||||
result->netreqs_in_flight = 0;
|
||||
|
||||
result->server = NULL;
|
||||
|
||||
|
@ -2980,6 +2982,27 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq)
|
|||
_getdns_context_cancel_request(dnsreq);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_getdns_netreq_change_state(getdns_network_req *netreq, network_req_state new_state)
|
||||
{
|
||||
if (!netreq)
|
||||
return;
|
||||
|
||||
if (netreq->state != NET_REQ_IN_FLIGHT) {
|
||||
if (new_state == NET_REQ_IN_FLIGHT)
|
||||
netreq->owner->context->netreqs_in_flight += 1;
|
||||
netreq->state = new_state;
|
||||
return;
|
||||
}
|
||||
if (new_state == NET_REQ_IN_FLIGHT) /* No change */
|
||||
return;
|
||||
netreq->state = new_state;
|
||||
netreq->owner->context->netreqs_in_flight -= 1;
|
||||
/* TODO: Schedule pending netreqs
|
||||
* when netreqs_in_flight < oustanding_queries */
|
||||
}
|
||||
|
||||
static void
|
||||
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
||||
{
|
||||
|
|
|
@ -291,6 +291,11 @@ struct getdns_context {
|
|||
*/
|
||||
_getdns_rbtree_t outbound_requests;
|
||||
|
||||
/* network requests
|
||||
*/
|
||||
size_t netreqs_in_flight;
|
||||
_getdns_rbtree_t pending_netreqs;
|
||||
|
||||
struct listen_set *server;
|
||||
|
||||
/* Event loop extension. */
|
||||
|
@ -372,12 +377,22 @@ void _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq);
|
|||
*/
|
||||
void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
|
||||
|
||||
|
||||
/* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
|
||||
* cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
|
||||
*/
|
||||
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
|
||||
|
||||
/* Change state of the netreq req.
|
||||
* - Increments context->netreqs_in_flight
|
||||
* when state changes from NOT_SENT to IN_FLIGHT
|
||||
* - Decrements context->netreqs_in_flight
|
||||
* when state changes from IN_FLIGHT to FINISHED, TIMED_OUT or ERRORED
|
||||
* - Resubmits NOT_SENT netreqs from context->pending_netreqs,
|
||||
* when # pending_netreqs < limit_outstanding_queries
|
||||
*/
|
||||
void _getdns_netreq_change_state(
|
||||
getdns_network_req *req, network_req_state new_state);
|
||||
|
||||
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
|
||||
|
||||
struct getdns_bindata *_getdns_bindata_copy(
|
||||
|
|
|
@ -3040,7 +3040,7 @@ static void check_chain_complete(chain_head *chain)
|
|||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++) {
|
||||
|
||||
netreq->state = NET_REQ_NOT_SENT;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT);
|
||||
netreq->owner = dnsreq;
|
||||
r = _getdns_submit_netreq(netreq, &now_ms);
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED)
|
||||
return;
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
_getdns_check_dns_req_complete(dns_req);
|
||||
|
@ -168,7 +168,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED)
|
||||
return;
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
_getdns_check_dns_req_complete(dns_req);
|
||||
|
@ -209,7 +209,7 @@ ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len,
|
|||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
/* parse */
|
||||
if (getdns_apply_network_result(
|
||||
netreq, rcode, pkt, pkt_len, sec, why_bogus)) {
|
||||
|
@ -227,7 +227,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
|||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
if (err != 0) {
|
||||
_getdns_call_user_callback(dns_req, NULL);
|
||||
return;
|
||||
|
@ -259,6 +259,8 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
|||
int ub_resolve_r;
|
||||
#endif
|
||||
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_IN_FLIGHT);
|
||||
|
||||
#ifdef STUB_NATIVE_DNSSEC
|
||||
# ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
|
||||
|
@ -457,7 +459,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
*return_netreq_p = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,7 +488,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
*return_netreq_p = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
/* Stop processing more namespaces, since there was a match */
|
||||
|
@ -509,7 +511,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
*return_netreq_p = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -121,7 +121,7 @@ mdns_timeout_cb(void *userarg)
|
|||
#else
|
||||
close(netreq->fd);
|
||||
#endif
|
||||
netreq->state = NET_REQ_TIMED_OUT;
|
||||
_getdns_netreq_change_state(netreq, 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);
|
||||
|
@ -182,7 +182,7 @@ mdns_udp_read_cb(void *userarg)
|
|||
|
||||
netreq->response_len = read;
|
||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
_getdns_check_dns_req_complete(dnsreq);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ netreq_reset(getdns_network_req *net_req)
|
|||
/* variables that need to be reset on reinit
|
||||
*/
|
||||
net_req->unbound_id = -1;
|
||||
net_req->state = NET_REQ_NOT_SENT;
|
||||
_getdns_netreq_change_state(net_req, NET_REQ_NOT_SENT);
|
||||
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
net_req->query_id = 0;
|
||||
|
@ -183,6 +183,10 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
|||
net_req->debug_tls_auth_status = GETDNS_AUTH_NONE;
|
||||
net_req->debug_udp = 0;
|
||||
|
||||
/* Scheduling, touch only via _getdns_netreq_change_state!
|
||||
*/
|
||||
net_req->state = NET_REQ_NOT_SENT;
|
||||
|
||||
if (max_query_sz == 0) {
|
||||
net_req->query = NULL;
|
||||
net_req->opt = NULL;
|
||||
|
|
10
src/stub.c
10
src/stub.c
|
@ -550,7 +550,7 @@ upstream_failed(getdns_upstream *upstream, int during_setup)
|
|||
netreq = (getdns_network_req *)
|
||||
_getdns_rbtree_first(&upstream->netreq_by_query_id);
|
||||
stub_cleanup(netreq);
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
_getdns_check_dns_req_complete(netreq->owner);
|
||||
}
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ stub_timeout_cb(void *userarg)
|
|||
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
||||
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
||||
stub_cleanup(netreq);
|
||||
netreq->state = NET_REQ_TIMED_OUT;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
||||
/* Handle upstream*/
|
||||
if (netreq->fd >= 0) {
|
||||
#ifdef USE_WINSOCK
|
||||
|
@ -1368,7 +1368,7 @@ stub_udp_read_cb(void *userarg)
|
|||
netreq->response_len = read;
|
||||
dnsreq->upstreams->current_udp = 0;
|
||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
upstream->udp_responses++;
|
||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||
if (upstream->udp_responses == 1 ||
|
||||
|
@ -1495,7 +1495,7 @@ upstream_read_cb(void *userarg)
|
|||
|
||||
DEBUG_STUB("%s %-35s: MSG: %p (read)\n",
|
||||
STUB_DEBUG_READ, __FUNC__, (void*)netreq);
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
netreq->response = upstream->tcp.read_buf;
|
||||
netreq->response_len =
|
||||
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
||||
|
@ -1614,7 +1614,7 @@ upstream_write_cb(void *userarg)
|
|||
#endif
|
||||
if (fallback_on_write(netreq) == STUB_TCP_ERROR) {
|
||||
/* TODO: Need new state to report transport unavailable*/
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||
_getdns_check_dns_req_complete(netreq->owner);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
QLIMIT=10
|
||||
# TODO: Change QLIMIT to 10 once implement pending netreq resubmission
|
||||
#
|
||||
QLIMIT=1000
|
||||
make && "./${TPKG_NAME}" | (
|
||||
read PORT
|
||||
${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \
|
||||
|
|
Loading…
Reference in New Issue