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->outbound_requests, transaction_id_cmp);
|
||||||
_getdns_rbtree_init(&result->local_hosts, local_host_cmp);
|
_getdns_rbtree_init(&result->local_hosts, local_host_cmp);
|
||||||
|
/* TODO: Initialize pending_netreqs */
|
||||||
|
result->netreqs_in_flight = 0;
|
||||||
|
|
||||||
result->server = NULL;
|
result->server = NULL;
|
||||||
|
|
||||||
|
@ -2980,6 +2982,27 @@ _getdns_context_request_timed_out(getdns_dns_req *dnsreq)
|
||||||
_getdns_context_cancel_request(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
|
static void
|
||||||
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -291,6 +291,11 @@ struct getdns_context {
|
||||||
*/
|
*/
|
||||||
_getdns_rbtree_t outbound_requests;
|
_getdns_rbtree_t outbound_requests;
|
||||||
|
|
||||||
|
/* network requests
|
||||||
|
*/
|
||||||
|
size_t netreqs_in_flight;
|
||||||
|
_getdns_rbtree_t pending_netreqs;
|
||||||
|
|
||||||
struct listen_set *server;
|
struct listen_set *server;
|
||||||
|
|
||||||
/* Event loop extension. */
|
/* 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);
|
void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
|
||||||
|
|
||||||
|
|
||||||
/* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
|
/* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
|
||||||
* cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
|
* cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
|
||||||
*/
|
*/
|
||||||
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
|
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);
|
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
|
||||||
|
|
||||||
struct getdns_bindata *_getdns_bindata_copy(
|
struct getdns_bindata *_getdns_bindata_copy(
|
||||||
|
|
|
@ -3040,7 +3040,7 @@ static void check_chain_complete(chain_head *chain)
|
||||||
; !r && (netreq = *netreq_p)
|
; !r && (netreq = *netreq_p)
|
||||||
; netreq_p++) {
|
; netreq_p++) {
|
||||||
|
|
||||||
netreq->state = NET_REQ_NOT_SENT;
|
_getdns_netreq_change_state(netreq, NET_REQ_NOT_SENT);
|
||||||
netreq->owner = dnsreq;
|
netreq->owner = dnsreq;
|
||||||
r = _getdns_submit_netreq(netreq, &now_ms);
|
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 = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||||
if (r == DNS_REQ_FINISHED)
|
if (r == DNS_REQ_FINISHED)
|
||||||
return;
|
return;
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_getdns_check_dns_req_complete(dns_req);
|
_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 = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||||
if (r == DNS_REQ_FINISHED)
|
if (r == DNS_REQ_FINISHED)
|
||||||
return;
|
return;
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_getdns_check_dns_req_complete(dns_req);
|
_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_network_req *netreq = (getdns_network_req *) arg;
|
||||||
getdns_dns_req *dns_req = netreq->owner;
|
getdns_dns_req *dns_req = netreq->owner;
|
||||||
|
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||||
/* parse */
|
/* parse */
|
||||||
if (getdns_apply_network_result(
|
if (getdns_apply_network_result(
|
||||||
netreq, rcode, pkt, pkt_len, sec, why_bogus)) {
|
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_network_req *netreq = (getdns_network_req *) arg;
|
||||||
getdns_dns_req *dns_req = netreq->owner;
|
getdns_dns_req *dns_req = netreq->owner;
|
||||||
|
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
_getdns_call_user_callback(dns_req, NULL);
|
_getdns_call_user_callback(dns_req, NULL);
|
||||||
return;
|
return;
|
||||||
|
@ -259,6 +259,8 @@ _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
||||||
int ub_resolve_r;
|
int ub_resolve_r;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_getdns_netreq_change_state(netreq, NET_REQ_IN_FLIGHT);
|
||||||
|
|
||||||
#ifdef STUB_NATIVE_DNSSEC
|
#ifdef STUB_NATIVE_DNSSEC
|
||||||
# ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
# ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||||
|
|
||||||
|
@ -457,7 +459,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
||||||
*return_netreq_p = NULL;
|
*return_netreq_p = NULL;
|
||||||
return GETDNS_RETURN_GOOD;
|
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_netreq_p = NULL;
|
||||||
return GETDNS_RETURN_GOOD;
|
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 */
|
/* 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_netreq_p = NULL;
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -121,7 +121,7 @@ mdns_timeout_cb(void *userarg)
|
||||||
#else
|
#else
|
||||||
close(netreq->fd);
|
close(netreq->fd);
|
||||||
#endif
|
#endif
|
||||||
netreq->state = NET_REQ_TIMED_OUT;
|
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
||||||
if (netreq->owner->user_callback) {
|
if (netreq->owner->user_callback) {
|
||||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
||||||
(void)_getdns_context_request_timed_out(netreq->owner);
|
(void)_getdns_context_request_timed_out(netreq->owner);
|
||||||
|
@ -182,7 +182,7 @@ mdns_udp_read_cb(void *userarg)
|
||||||
|
|
||||||
netreq->response_len = read;
|
netreq->response_len = read;
|
||||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
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);
|
_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
|
/* variables that need to be reset on reinit
|
||||||
*/
|
*/
|
||||||
net_req->unbound_id = -1;
|
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->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||||
net_req->query_id = 0;
|
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_tls_auth_status = GETDNS_AUTH_NONE;
|
||||||
net_req->debug_udp = 0;
|
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) {
|
if (max_query_sz == 0) {
|
||||||
net_req->query = NULL;
|
net_req->query = NULL;
|
||||||
net_req->opt = 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 *)
|
netreq = (getdns_network_req *)
|
||||||
_getdns_rbtree_first(&upstream->netreq_by_query_id);
|
_getdns_rbtree_first(&upstream->netreq_by_query_id);
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
netreq->state = NET_REQ_FINISHED;
|
_getdns_netreq_change_state(netreq, NET_REQ_FINISHED);
|
||||||
_getdns_check_dns_req_complete(netreq->owner);
|
_getdns_check_dns_req_complete(netreq->owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ stub_timeout_cb(void *userarg)
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
DEBUG_STUB("%s %-35s: MSG: %p\n",
|
||||||
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
STUB_DEBUG_CLEANUP, __FUNC__, (void*)netreq);
|
||||||
stub_cleanup(netreq);
|
stub_cleanup(netreq);
|
||||||
netreq->state = NET_REQ_TIMED_OUT;
|
_getdns_netreq_change_state(netreq, NET_REQ_TIMED_OUT);
|
||||||
/* Handle upstream*/
|
/* Handle upstream*/
|
||||||
if (netreq->fd >= 0) {
|
if (netreq->fd >= 0) {
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
|
@ -1368,7 +1368,7 @@ stub_udp_read_cb(void *userarg)
|
||||||
netreq->response_len = read;
|
netreq->response_len = read;
|
||||||
dnsreq->upstreams->current_udp = 0;
|
dnsreq->upstreams->current_udp = 0;
|
||||||
netreq->debug_end_time = _getdns_get_time_as_uintt64();
|
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++;
|
upstream->udp_responses++;
|
||||||
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
|
||||||
if (upstream->udp_responses == 1 ||
|
if (upstream->udp_responses == 1 ||
|
||||||
|
@ -1495,7 +1495,7 @@ upstream_read_cb(void *userarg)
|
||||||
|
|
||||||
DEBUG_STUB("%s %-35s: MSG: %p (read)\n",
|
DEBUG_STUB("%s %-35s: MSG: %p (read)\n",
|
||||||
STUB_DEBUG_READ, __FUNC__, (void*)netreq);
|
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 = upstream->tcp.read_buf;
|
||||||
netreq->response_len =
|
netreq->response_len =
|
||||||
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
upstream->tcp.read_pos - upstream->tcp.read_buf;
|
||||||
|
@ -1614,7 +1614,7 @@ upstream_write_cb(void *userarg)
|
||||||
#endif
|
#endif
|
||||||
if (fallback_on_write(netreq) == STUB_TCP_ERROR) {
|
if (fallback_on_write(netreq) == STUB_TCP_ERROR) {
|
||||||
/* TODO: Need new state to report transport unavailable*/
|
/* 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);
|
_getdns_check_dns_req_complete(netreq->owner);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
# use .tpkg.var.test for in test variable passing
|
# use .tpkg.var.test for in test variable passing
|
||||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
[ -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}" | (
|
make && "./${TPKG_NAME}" | (
|
||||||
read PORT
|
read PORT
|
||||||
${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \
|
${GETDNS_STUB_QUERY} @127.0.0.1:$PORT TXT \
|
||||||
|
|
Loading…
Reference in New Issue