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