mirror of https://github.com/getdnsapi/getdns.git
Schedule dnsreqs with absolute timeout/expiry time
This commit is contained in:
parent
5f3de12644
commit
639239f45c
|
@ -3032,6 +3032,7 @@ static void check_chain_complete(chain_head *chain)
|
|||
|
||||
int r = GETDNS_RETURN_GOOD;
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
dnsreq->avoid_dnssec_roadblocks = 1;
|
||||
|
||||
|
@ -3041,7 +3042,7 @@ static void check_chain_complete(chain_head *chain)
|
|||
|
||||
netreq->state = NET_REQ_NOT_SENT;
|
||||
netreq->owner = dnsreq;
|
||||
r = _getdns_submit_netreq(netreq);
|
||||
r = _getdns_submit_netreq(netreq, &now_ms);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
{
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
int results_found = 0, r;
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
for (netreq_p = dns_req->netreqs; (netreq = *netreq_p); netreq_p++)
|
||||
if (!_getdns_netreq_finished(netreq))
|
||||
|
@ -126,7 +127,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
; (netreq = *netreq_p)
|
||||
; netreq_p++ ) {
|
||||
_getdns_netreq_reinit(netreq);
|
||||
if ((r = _getdns_submit_netreq(netreq))) {
|
||||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED)
|
||||
return;
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
|
@ -164,7 +165,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
; (netreq = *netreq_p)
|
||||
; netreq_p++ ) {
|
||||
_getdns_netreq_reinit(netreq);
|
||||
if ((r = _getdns_submit_netreq(netreq))) {
|
||||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED)
|
||||
return;
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
|
@ -248,7 +249,7 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
|||
|
||||
|
||||
int
|
||||
_getdns_submit_netreq(getdns_network_req *netreq)
|
||||
_getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms)
|
||||
{
|
||||
getdns_return_t r;
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
|
@ -284,7 +285,8 @@ _getdns_submit_netreq(getdns_network_req *netreq)
|
|||
_getdns_context_request_timed_out;
|
||||
dns_req->timeout.ev = NULL;
|
||||
if ((r = dns_req->loop->vmt->schedule(dns_req->loop, -1,
|
||||
dns_req->context->timeout, &dns_req->timeout)))
|
||||
_getdns_ms_until_expiry2(dns_req->expires, now_ms),
|
||||
&dns_req->timeout)))
|
||||
return r;
|
||||
}
|
||||
(void) gldns_wire2str_dname_buf(dns_req->name,
|
||||
|
@ -314,7 +316,7 @@ _getdns_submit_netreq(getdns_network_req *netreq)
|
|||
}
|
||||
/* Submit with stub resolver */
|
||||
dns_req->freed = &dnsreq_freed;
|
||||
r = _getdns_submit_stub_request(netreq);
|
||||
r = _getdns_submit_stub_request(netreq, now_ms);
|
||||
if (dnsreq_freed)
|
||||
return DNS_REQ_FINISHED;
|
||||
dns_req->freed = NULL;
|
||||
|
@ -413,6 +415,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
getdns_dns_req *req;
|
||||
getdns_dict *localnames_response;
|
||||
size_t i;
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
if (!context || !name || (!callbackfn && !internal_cb))
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
@ -430,7 +433,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
/* create the request */
|
||||
if (!(req = _getdns_dns_req_new(
|
||||
context, loop, name, request_type, extensions)))
|
||||
context, loop, name, request_type, extensions, &now_ms)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
req->user_pointer = userarg;
|
||||
|
@ -448,7 +451,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
for ( netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++) {
|
||||
if ((r = _getdns_submit_netreq(netreq))) {
|
||||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED) {
|
||||
if (return_netreq_p)
|
||||
*return_netreq_p = NULL;
|
||||
|
@ -500,7 +503,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
for ( netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++) {
|
||||
if ((r = _getdns_submit_netreq(netreq))) {
|
||||
if ((r = _getdns_submit_netreq(netreq, &now_ms))) {
|
||||
if (r == DNS_REQ_FINISHED) {
|
||||
if (return_netreq_p)
|
||||
*return_netreq_p = NULL;
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
void _getdns_call_user_callback(getdns_dns_req *, getdns_dict *);
|
||||
void _getdns_check_dns_req_complete(getdns_dns_req *dns_req);
|
||||
int _getdns_submit_netreq(getdns_network_req *netreq);
|
||||
int _getdns_submit_netreq(getdns_network_req *netreq, uint64_t *now_ms);
|
||||
|
||||
|
||||
getdns_return_t
|
||||
|
|
|
@ -658,7 +658,8 @@ static const uint8_t no_suffixes[] = { 1, 0 };
|
|||
/* create a new dns req to be submitted */
|
||||
getdns_dns_req *
|
||||
_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions)
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions,
|
||||
uint64_t *now_ms)
|
||||
{
|
||||
int dnssec_return_status = is_extension_set(
|
||||
extensions, "dnssec_return_status",
|
||||
|
@ -953,5 +954,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
netreq_sz - sizeof(getdns_network_req), max_query_sz,
|
||||
extensions);
|
||||
|
||||
if (*now_ms == 0 && (*now_ms = _getdns_get_now_ms()) == 0)
|
||||
result->expires = 0;
|
||||
else
|
||||
result->expires = *now_ms + context->timeout;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
23
src/stub.c
23
src/stub.c
|
@ -1358,8 +1358,8 @@ stub_udp_read_cb(void *userarg)
|
|||
dnsreq)) == -1)
|
||||
break;
|
||||
upstream_schedule_netreq(netreq->upstream, netreq);
|
||||
GETDNS_SCHEDULE_EVENT(
|
||||
dnsreq->loop, -1, dnsreq->context->timeout,
|
||||
GETDNS_SCHEDULE_EVENT(dnsreq->loop, -1,
|
||||
_getdns_ms_until_expiry(dnsreq->expires),
|
||||
getdns_eventloop_event_init(&netreq->event,
|
||||
netreq, NULL, NULL, stub_timeout_cb));
|
||||
|
||||
|
@ -1421,8 +1421,8 @@ stub_udp_write_cb(void *userarg)
|
|||
#endif
|
||||
return;
|
||||
}
|
||||
GETDNS_SCHEDULE_EVENT(
|
||||
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
|
||||
GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd,
|
||||
_getdns_ms_until_expiry(dnsreq->expires),
|
||||
getdns_eventloop_event_init(&netreq->event, netreq,
|
||||
stub_udp_read_cb, NULL, stub_timeout_cb));
|
||||
}
|
||||
|
@ -1928,12 +1928,13 @@ upstream_find_for_netreq(getdns_network_req *netreq)
|
|||
static int
|
||||
fallback_on_write(getdns_network_req *netreq)
|
||||
{
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
/* Deal with UDP one day*/
|
||||
DEBUG_STUB("%s %-35s: MSG: %p FALLING BACK \n", STUB_DEBUG_SCHEDULE, __FUNC__, (void*)netreq);
|
||||
|
||||
/* Try to find a fallback transport*/
|
||||
getdns_return_t result = _getdns_submit_stub_request(netreq);
|
||||
getdns_return_t result = _getdns_submit_stub_request(netreq, &now_ms);
|
||||
|
||||
if (result != GETDNS_RETURN_GOOD)
|
||||
return STUB_TCP_ERROR;
|
||||
|
@ -1997,8 +1998,8 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
|
|||
if (upstream->queries_sent == 0) {
|
||||
/* Set a timeout on the upstream so we can catch failed setup*/
|
||||
upstream->event.timeout_cb = upstream_setup_timeout_cb;
|
||||
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
||||
upstream->fd, netreq->owner->context->timeout / 2,
|
||||
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
|
||||
_getdns_ms_until_expiry(netreq->owner->expires)/2,
|
||||
&upstream->event);
|
||||
} else {
|
||||
GETDNS_SCHEDULE_EVENT(upstream->loop,
|
||||
|
@ -2027,7 +2028,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
_getdns_submit_stub_request(getdns_network_req *netreq)
|
||||
_getdns_submit_stub_request(getdns_network_req *netreq, uint64_t *now_ms)
|
||||
{
|
||||
DEBUG_STUB("%s %-35s: MSG: %p TYPE: %d\n", STUB_DEBUG_ENTRY, __FUNC__,
|
||||
(void*)netreq, netreq->request_type);
|
||||
|
@ -2046,8 +2047,8 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
|
|||
case GETDNS_TRANSPORT_UDP:
|
||||
netreq->fd = fd;
|
||||
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
|
||||
GETDNS_SCHEDULE_EVENT(
|
||||
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
|
||||
GETDNS_SCHEDULE_EVENT(dnsreq->loop, netreq->fd,
|
||||
_getdns_ms_until_expiry2(dnsreq->expires, now_ms),
|
||||
getdns_eventloop_event_init(&netreq->event, netreq,
|
||||
NULL, stub_udp_write_cb, stub_timeout_cb));
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
@ -2121,7 +2122,7 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
|
|||
*/
|
||||
GETDNS_SCHEDULE_EVENT(
|
||||
dnsreq->loop, -1,
|
||||
dnsreq->context->timeout,
|
||||
_getdns_ms_until_expiry2(dnsreq->expires, now_ms),
|
||||
getdns_eventloop_event_init(
|
||||
&netreq->event, netreq, NULL, NULL,
|
||||
stub_timeout_cb));
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
#include "getdns/getdns.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
getdns_return_t _getdns_submit_stub_request(getdns_network_req *netreq);
|
||||
getdns_return_t _getdns_submit_stub_request(
|
||||
getdns_network_req *netreq, uint64_t *now_ms);
|
||||
|
||||
void _getdns_cancel_stub_request(getdns_network_req *netreq);
|
||||
|
||||
|
|
|
@ -338,6 +338,11 @@ typedef struct getdns_dns_req {
|
|||
/* the transaction id */
|
||||
getdns_transaction_t trans_id;
|
||||
|
||||
/* Absolute time (in miliseconds since epoch),
|
||||
* after which this dns request is expired; i.e. timed out
|
||||
*/
|
||||
uint64_t expires;
|
||||
|
||||
/* for scheduling timeouts when using libunbound */
|
||||
getdns_eventloop_event timeout;
|
||||
|
||||
|
@ -408,7 +413,7 @@ extern getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks;
|
|||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions);
|
||||
const char *name, uint16_t request_type, getdns_dict *extensions, uint64_t *now_ms);
|
||||
|
||||
void _getdns_dns_req_free(getdns_dns_req * req);
|
||||
|
||||
|
|
|
@ -198,5 +198,25 @@ INLINE void _dname_canonicalize2(uint8_t *dname)
|
|||
_dname_canonicalize(dname, dname);
|
||||
}
|
||||
|
||||
INLINE uint64_t _getdns_get_now_ms()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
(void) gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
INLINE uint64_t _getdns_ms_until_expiry(uint64_t expires)
|
||||
{
|
||||
uint64_t now_ms = _getdns_get_now_ms();
|
||||
return now_ms >= expires ? 0 : expires - now_ms;
|
||||
}
|
||||
|
||||
INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms)
|
||||
{
|
||||
if (*now_ms == 0) *now_ms = _getdns_get_now_ms();
|
||||
return *now_ms >= expires ? 0 : expires - *now_ms;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* util-internal.h */
|
||||
|
|
Loading…
Reference in New Issue