Setup getdns eventloop in libunbound

When unbound supports this
This commit is contained in:
Willem Toorop 2016-01-19 16:52:11 +01:00
parent 0c0868517c
commit ae2b16665b
8 changed files with 116 additions and 39 deletions

View File

@ -526,7 +526,15 @@ fi
if test $my_with_libunbound = 1
then
AC_MSG_NOTICE([Checking for dependency libunbound])
AC_CHECK_LIB([unbound], [ub_fd], [], [found_all_libs=0])
AC_CHECK_LIB([unbound], [ub_fd], [
AC_DEFINE_UNQUOTED([HAVE_LIBUNBOUND], [1], [Define to 1 if you have the `unbound' library (-lunbound).])
LIBS="$LIBS -lunbound"
AC_CHECK_HEADER([unbound-event.h],[
AC_CHECK_FUNC([ub_event_get_version], [
AC_DEFINE_UNQUOTED([HAVE_UNBOUND_EVENT_API], [1], [Define this when libunbound is compiled with the --enable-event-api option.])
])
],,[AC_INCLUDES_DEFAULT])
], [found_all_libs=0])
fi
if test $found_all_libs = 0
@ -1192,7 +1200,10 @@ const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifdef HAVE_LIBUNBOUND
#include <unbound.h>
# include <unbound.h>
# ifdef HAVE_UNBOUND_EVENT_API
# include <unbound-event.h>
# endif
#endif
])

View File

@ -1281,9 +1281,12 @@ getdns_context_request_count_changed(getdns_context *context)
"-> ub schedule(el_ev = %p, el_ev->ev = %p)\n",
&context->ub_event, context->ub_event.ev);
#ifndef USE_WINSOCK
context->extension->vmt->schedule(
context->extension, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &context->ub_event);
#ifdef HAVE_UNBOUND_EVENT_API
if (!context->unbound_event_api)
#endif
context->extension->vmt->schedule(
context->extension, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &context->ub_event);
#endif
}
else if (context->ub_event.ev) /* Only test if count == 0! */ {
@ -1292,8 +1295,11 @@ getdns_context_request_count_changed(getdns_context *context)
&context->ub_event, context->ub_event.ev);
#ifndef USE_WINSOCK
context->extension->vmt->clear(
context->extension, &context->ub_event);
#ifdef HAVE_UNBOUND_EVENT_API
if (!context->unbound_event_api)
#endif
context->extension->vmt->clear(
context->extension, &context->ub_event);
#endif
}
}
@ -1324,8 +1330,18 @@ rebuild_ub_ctx(struct getdns_context* context) {
context->unbound_ctx = NULL;
}
/* setup */
context->unbound_ctx = ub_ctx_create();
(void) ub_ctx_async(context->unbound_ctx, 1);
#ifdef HAVE_UNBOUND_EVENT_API
context->unbound_event_api =
strncmp(ub_event_get_version(), "getdns-event", 12) == 0;
if (context->unbound_event_api) {
context->unbound_ctx = ub_ctx_create_event((void *)context->extension);
} else {
#endif
context->unbound_ctx = ub_ctx_create();
(void) ub_ctx_async(context->unbound_ctx, 1);
#ifdef HAVE_UNBOUND_EVENT_API
}
#endif
context->unbound_ta_set = 0;
if (!context->unbound_ctx) {
return GETDNS_RETURN_MEMORY_ERROR;
@ -2891,6 +2907,11 @@ getdns_context_detach_eventloop(struct getdns_context* context)
context->extension->vmt->cleanup(context->extension);
context->extension = &context->default_eventloop.loop;
_getdns_default_eventloop_init(&context->default_eventloop);
#ifdef HAVE_UNBOUND_EVENT_API
if (context->unbound_event_api)
(void) ub_ctx_set_event(
context->unbound_ctx, (void *)context->extension);
#endif
return GETDNS_RETURN_GOOD;
}
@ -2905,6 +2926,11 @@ getdns_context_set_eventloop(getdns_context* context, getdns_eventloop* loop)
context->extension->vmt->cleanup(context->extension);
}
context->extension = loop;
#ifdef HAVE_UNBOUND_EVENT_API
if (context->unbound_event_api)
(void) ub_ctx_set_event(
context->unbound_ctx, (void *)context->extension);
#endif
return GETDNS_RETURN_GOOD;
}

View File

@ -220,6 +220,9 @@ struct getdns_context {
/* The underlying contexts that do the real work */
struct ub_ctx *unbound_ctx;
int unbound_ta_set;
#ifdef HAVE_UNBOUND_EVENT_API
int unbound_event_api;
#endif
#endif
/* A tree to hold local host information*/

View File

@ -256,6 +256,26 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
}
#ifdef HAVE_LIBUNBOUND
#ifdef HAVE_UNBOUND_EVENT_API
static void
ub_resolve_event_callback(void* arg, int rcode, void *pkt, int pkt_len,
int sec, char* why_bogus)
{
getdns_network_req *netreq = (getdns_network_req *) arg;
getdns_dns_req *dns_req = netreq->owner;
netreq->state = NET_REQ_FINISHED;
/* parse */
if (getdns_apply_network_result(
netreq, rcode, pkt, pkt_len, sec, why_bogus)) {
_getdns_call_user_callback(dns_req, NULL);
return;
}
_getdns_check_dns_req_complete(dns_req);
} /* ub_resolve_event_callback */
#endif
static void
ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
{
@ -268,7 +288,9 @@ ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
return;
}
/* parse */
if (getdns_apply_network_result(netreq, ub_res)) {
if (getdns_apply_network_result(netreq, ub_res->rcode,
ub_res->answer_packet, ub_res->answer_len,
(ub_res->secure ? 2 : ub_res->bogus ? 1 : 0), ub_res->why_bogus)) {
ub_resolve_free(ub_res);
_getdns_call_user_callback(dns_req, NULL);
return;
@ -319,10 +341,18 @@ _getdns_submit_netreq(getdns_network_req *netreq)
dns_req->name_len, name, sizeof(name));
#ifdef HAVE_LIBUNBOUND
return ub_resolve_async(dns_req->context->unbound_ctx,
name, netreq->request_type, netreq->owner->request_class,
netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
#ifdef HAVE_UNBOUND_EVENT_API
if (dns_req->context->unbound_event_api)
return ub_resolve_event(dns_req->context->unbound_ctx,
name, netreq->request_type, netreq->owner->request_class,
netreq, ub_resolve_event_callback, &(netreq->unbound_id)) ?
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
else
#endif
return ub_resolve_async(dns_req->context->unbound_ctx,
name, netreq->request_type, netreq->owner->request_class,
netreq, ub_resolve_callback, &(netreq->unbound_id)) ?
GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
#else
return GETDNS_RETURN_NOT_IMPLEMENTED;
#endif

View File

@ -75,11 +75,15 @@ getdns_sync_loop_init(getdns_context *context, getdns_sync_loop *loop)
loop->ub_event.timeout_cb = NULL;
loop->ub_event.ev = NULL;
return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &loop->ub_event);
#else
return GETDNS_RETURN_GOOD;
# ifdef HAVE_UNBOUND_EVENT_API
if (context->unbound_event_api) {
(void) ub_ctx_set_event(context->unbound_ctx, (void *)ext);
} else
# endif
return ext->vmt->schedule(ext, ub_fd(context->unbound_ctx),
TIMEOUT_FOREVER, &loop->ub_event);
#endif
return GETDNS_RETURN_GOOD;
}
static void
@ -88,7 +92,13 @@ getdns_sync_loop_cleanup(getdns_sync_loop *loop)
getdns_eventloop *ext = &loop->loop.loop;
#if defined(HAVE_LIBUNBOUND) && !defined(USE_WINSOCK)
ext->vmt->clear(ext, &loop->ub_event);
# ifdef HAVE_UNBOUND_EVENT_API
if (loop->context->unbound_event_api) {
(void) ub_ctx_set_event(loop->context->unbound_ctx,
(void *)loop->context->extension);
} else
# endif
ext->vmt->clear(ext, &loop->ub_event);
#endif
ext->vmt->cleanup(ext);
}

View File

@ -1305,8 +1305,6 @@ main(int argc, char **argv)
return r;
}
my_eventloop_init(&my_loop);
if ((r = getdns_context_set_eventloop(context, &my_loop.base)))
goto done_destroy_context;
if ((r = getdns_context_set_use_threads(context, 1)))
goto done_destroy_context;
extensions = getdns_dict_create();
@ -1329,10 +1327,14 @@ main(int argc, char **argv)
/* Make the call */
if (interactive) {
getdns_eventloop_event read_line_ev = {
&read_line_ev, read_line_cb, NULL, NULL, NULL };
(void) my_eventloop_schedule(
&my_loop.base, fileno(fp), -1, &read_line_ev);
if ((r = getdns_context_set_eventloop(context, &my_loop.base)))
goto done_destroy_context;
if (!query_file) {
printf("> ");
fflush(stdout);

View File

@ -1020,30 +1020,24 @@ error_free_result:
#ifdef HAVE_LIBUNBOUND
getdns_return_t
getdns_apply_network_result(getdns_network_req* netreq,
struct ub_result* ub_res)
int rcode, void *pkt, int pkt_len, int sec, char* why_bogus)
{
if (ub_res->bogus)
netreq->dnssec_status = GETDNS_DNSSEC_BOGUS;
else if (ub_res->secure)
netreq->dnssec_status = GETDNS_DNSSEC_SECURE;
else if (netreq->owner->context->trust_anchors)
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
netreq->dnssec_status = sec == 0 ? GETDNS_DNSSEC_INSECURE
: sec == 2 ? GETDNS_DNSSEC_SECURE
: GETDNS_DNSSEC_BOGUS;
if (ub_res == NULL) /* Timeout */
return GETDNS_RETURN_GOOD;
if (ub_res->answer_packet) {
if (netreq->max_udp_payload_size < ub_res->answer_len)
if (pkt) {
if (netreq->max_udp_payload_size < pkt_len)
netreq->response = GETDNS_XMALLOC(
netreq->owner->context->mf,
uint8_t, ub_res->answer_len
uint8_t, pkt_len
);
(void) memcpy(netreq->response, ub_res->answer_packet,
(netreq->response_len = ub_res->answer_len));
(void) memcpy(netreq->response, pkt,
(netreq->response_len = pkt_len));
return GETDNS_RETURN_GOOD;
}
if (ub_res->rcode == GETDNS_RCODE_SERVFAIL) {
if (rcode == GETDNS_RCODE_SERVFAIL) {
/* Likely to be caused by timeout from a synchronous
* lookup. Don't forge a packet.
*/
@ -1064,7 +1058,7 @@ getdns_apply_network_result(getdns_network_req* netreq,
GLDNS_QR_SET(netreq->response);
GLDNS_RD_SET(netreq->response);
GLDNS_RA_SET(netreq->response);
GLDNS_RCODE_SET(netreq->response, ub_res->rcode);
GLDNS_RCODE_SET(netreq->response, rcode);
(void) memcpy( netreq->response + GLDNS_HEADER_SIZE
, netreq->owner->name, netreq->owner->name_len);

View File

@ -56,7 +56,8 @@
struct ub_result;
struct getdns_network_req;
getdns_return_t getdns_apply_network_result(getdns_network_req* netreq, struct ub_result* result);
getdns_return_t getdns_apply_network_result(getdns_network_req* netreq,
int rcode, void *pkt, int pkt_len, int sec, char* why_bogus);
#define GETDNS_MAX_DNAME_LEN 255
#define GETDNS_MAX_LABEL_LEN 63