mirror of https://github.com/getdnsapi/getdns.git
Preliminary timeout implementation for stubs
This commit is contained in:
parent
68520e91d4
commit
a9d37df6b8
44
src/stub.c
44
src/stub.c
|
@ -59,19 +59,35 @@ typedef struct stub_resolver {
|
||||||
uint8_t *request_pkt;
|
uint8_t *request_pkt;
|
||||||
|
|
||||||
size_t ns_index;
|
size_t ns_index;
|
||||||
int sockfd;
|
size_t to_retry;
|
||||||
|
int udp_fd;
|
||||||
} stub_resolver;
|
} stub_resolver;
|
||||||
|
|
||||||
|
static void
|
||||||
|
resolver_done(stub_resolver *resolver)
|
||||||
|
{
|
||||||
|
(void) getdns_event_base_loopexit(resolver->base, NULL);
|
||||||
|
|
||||||
|
if (--resolver->upstreams->referenced == 0)
|
||||||
|
GETDNS_FREE(resolver->upstreams->mf, resolver->upstreams);
|
||||||
|
GETDNS_FREE(resolver->context->mf, resolver);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cb_udp_request(int fd, short bits, void *arg)
|
cb_udp_request(int fd, short bits, void *arg)
|
||||||
{
|
{
|
||||||
stub_resolver *resolver = (stub_resolver *)arg;
|
stub_resolver *resolver = (stub_resolver *)arg;
|
||||||
ssize_t read;
|
ssize_t read;
|
||||||
|
|
||||||
|
if (bits & EV_TIMEOUT) {
|
||||||
|
fprintf(stderr, "TIMEOUT!\n");
|
||||||
|
resolver_done(resolver);
|
||||||
|
}
|
||||||
|
|
||||||
if (! (bits & EV_READ))
|
if (! (bits & EV_READ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
read = recvfrom(resolver->sockfd,
|
read = recvfrom(resolver->udp_fd,
|
||||||
gldns_buffer_current(resolver->response),
|
gldns_buffer_current(resolver->response),
|
||||||
gldns_buffer_remaining(resolver->response),
|
gldns_buffer_remaining(resolver->response),
|
||||||
0, NULL, NULL);
|
0, NULL, NULL);
|
||||||
|
@ -90,11 +106,7 @@ cb_udp_request(int fd, short bits, void *arg)
|
||||||
free(str);
|
free(str);
|
||||||
} while(0);
|
} while(0);
|
||||||
#endif
|
#endif
|
||||||
(void) getdns_event_base_loopexit(resolver->base, NULL);
|
resolver_done(resolver);
|
||||||
|
|
||||||
if (--resolver->upstreams->referenced == 0)
|
|
||||||
GETDNS_FREE(resolver->upstreams->mf, resolver->upstreams);
|
|
||||||
GETDNS_FREE(resolver->context->mf, resolver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static getdns_return_t
|
static getdns_return_t
|
||||||
|
@ -102,6 +114,7 @@ query_ns(stub_resolver *resolver)
|
||||||
{
|
{
|
||||||
struct getdns_upstream *upstream;
|
struct getdns_upstream *upstream;
|
||||||
ssize_t sent;
|
ssize_t sent;
|
||||||
|
struct timeval tv;
|
||||||
struct getdns_event *ev;
|
struct getdns_event *ev;
|
||||||
|
|
||||||
assert(resolver);
|
assert(resolver);
|
||||||
|
@ -111,23 +124,29 @@ query_ns(stub_resolver *resolver)
|
||||||
|
|
||||||
upstream = &resolver->upstreams->upstreams[resolver->ns_index];
|
upstream = &resolver->upstreams->upstreams[resolver->ns_index];
|
||||||
/* TODO: Try next upstream if something is not right with this one
|
/* TODO: Try next upstream if something is not right with this one
|
||||||
* Also later on... for example when socket returns -1
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO: Check how to connect first (udp or tcp) */
|
/* TODO: Check how to connect first (udp or tcp) */
|
||||||
|
|
||||||
resolver->sockfd = socket(upstream->addr.ss_family, SOCK_DGRAM,
|
resolver->udp_fd = socket(upstream->addr.ss_family, SOCK_DGRAM,
|
||||||
IPPROTO_UDP);
|
IPPROTO_UDP);
|
||||||
sent = sendto(resolver->sockfd,
|
if (resolver->udp_fd == -1) {
|
||||||
|
/* Retry with tcp? */
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sent = sendto(resolver->udp_fd,
|
||||||
resolver->request_pkt, resolver->request_pkt_len, 0,
|
resolver->request_pkt, resolver->request_pkt_len, 0,
|
||||||
(struct sockaddr *)&upstream->addr, upstream->addr_len);
|
(struct sockaddr *)&upstream->addr, upstream->addr_len);
|
||||||
if (sent == -1 || sent != resolver->request_pkt_len)
|
if (sent == -1 || sent != resolver->request_pkt_len)
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
|
||||||
ev = GETDNS_MALLOC(resolver->context->mf, struct getdns_event);
|
ev = GETDNS_MALLOC(resolver->context->mf, struct getdns_event);
|
||||||
getdns_event_set(ev, resolver->sockfd, EV_READ, cb_udp_request, resolver);
|
getdns_event_set(ev, resolver->udp_fd, EV_READ | EV_TIMEOUT, cb_udp_request, resolver);
|
||||||
(void) getdns_event_base_set(resolver->base, ev);
|
(void) getdns_event_base_set(resolver->base, ev);
|
||||||
(void) getdns_event_add(ev, NULL);
|
tv.tv_sec = resolver->context->timeout / 1000;
|
||||||
|
tv.tv_usec = (resolver->context->timeout % 1000) * 1000;
|
||||||
|
(void) getdns_event_add(ev, &tv);
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +186,7 @@ getdns_stub_dns_query_async(struct getdns_event_base *base,
|
||||||
} while(0);
|
} while(0);
|
||||||
#endif
|
#endif
|
||||||
resolver->ns_index = 0;
|
resolver->ns_index = 0;
|
||||||
|
resolver->to_retry = 2;
|
||||||
r = query_ns(resolver);
|
r = query_ns(resolver);
|
||||||
if (r) {
|
if (r) {
|
||||||
if (--resolver->upstreams->referenced == 0)
|
if (--resolver->upstreams->referenced == 0)
|
||||||
|
|
Loading…
Reference in New Issue