mirror of https://github.com/getdnsapi/getdns.git
Initial pass at using unbound stock
This commit is contained in:
parent
d9e3485f8b
commit
2bcfedcf78
File diff suppressed because it is too large
Load Diff
|
@ -7103,6 +7103,10 @@ _lt_linker_boilerplate=`cat conftest.err`
|
|||
$RM -r conftest*
|
||||
|
||||
|
||||
## CAVEAT EMPTOR:
|
||||
## There is no encapsulation within the following macros, do not change
|
||||
## the running order or otherwise move them around unless you know exactly
|
||||
## what you are doing...
|
||||
if test -n "$compiler"; then
|
||||
|
||||
lt_prog_compiler_no_builtin_flag=
|
||||
|
@ -11014,9 +11018,9 @@ fi
|
|||
found_libunbound=1
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Checking for dependency libunbound" >&5
|
||||
$as_echo "$as_me: Checking for dependency libunbound" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ub_ctx_set_event in -lunbound" >&5
|
||||
$as_echo_n "checking for ub_ctx_set_event in -lunbound... " >&6; }
|
||||
if ${ac_cv_lib_unbound_ub_ctx_set_event+:} false; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ub_fd in -lunbound" >&5
|
||||
$as_echo_n "checking for ub_fd in -lunbound... " >&6; }
|
||||
if ${ac_cv_lib_unbound_ub_fd+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
|
@ -11030,27 +11034,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char ub_ctx_set_event ();
|
||||
char ub_fd ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return ub_ctx_set_event ();
|
||||
return ub_fd ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_unbound_ub_ctx_set_event=yes
|
||||
ac_cv_lib_unbound_ub_fd=yes
|
||||
else
|
||||
ac_cv_lib_unbound_ub_ctx_set_event=no
|
||||
ac_cv_lib_unbound_ub_fd=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unbound_ub_ctx_set_event" >&5
|
||||
$as_echo "$ac_cv_lib_unbound_ub_ctx_set_event" >&6; }
|
||||
if test "x$ac_cv_lib_unbound_ub_ctx_set_event" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unbound_ub_fd" >&5
|
||||
$as_echo "$ac_cv_lib_unbound_ub_fd" >&6; }
|
||||
if test "x$ac_cv_lib_unbound_ub_fd" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBUNBOUND 1
|
||||
_ACEOF
|
||||
|
@ -11063,7 +11067,7 @@ fi
|
|||
|
||||
if test $found_libunbound == 0
|
||||
then
|
||||
as_fn_error $? "libunbound is missing or does not incude event code, you may need to patch your libunbound sources and rebuild. See the getdns build instructions" "$LINENO" 5
|
||||
as_fn_error $? "libunbound is missing." "$LINENO" 5
|
||||
fi
|
||||
|
||||
for ac_prog in doxygen
|
||||
|
|
|
@ -142,10 +142,10 @@ fi
|
|||
# patch to the sources
|
||||
found_libunbound=1
|
||||
AC_MSG_NOTICE([Checking for dependency libunbound])
|
||||
AC_CHECK_LIB([unbound], [ub_ctx_set_event], [], [found_libunbound=0])
|
||||
AC_CHECK_LIB([unbound], [ub_fd], [], [found_libunbound=0])
|
||||
if test $found_libunbound == 0
|
||||
then
|
||||
AC_MSG_ERROR([libunbound is missing or does not incude event code, you may need to patch your libunbound sources and rebuild. See the getdns build instructions])
|
||||
AC_MSG_ERROR([libunbound is missing.])
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
|
|
|
@ -33,7 +33,7 @@ CFLAGS=@CFLAGS@ -Wall -I$(srcdir)/ -I/usr/local/include -std=c99
|
|||
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
||||
hostname.lo service.lo request-internal.lo validate_dnssec.lo \
|
||||
util-internal.lo getdns_error.lo
|
||||
util-internal.lo getdns_error.lo extension_libevent.lo
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
|
|
|
@ -29,17 +29,11 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unbound-event.h>
|
||||
#include <unbound.h>
|
||||
|
||||
#include "context.h"
|
||||
|
@ -275,11 +269,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->mf.mf.ext.realloc = realloc;
|
||||
result->mf.mf.ext.free = free;
|
||||
|
||||
result->event_base_sync = event_base_new();
|
||||
result->unbound_sync = ub_ctx_create_event(result->event_base_sync);
|
||||
/* create the async one also so options are kept up to date */
|
||||
result->unbound_async = ub_ctx_create_event(result->event_base_sync);
|
||||
result->event_base_async = NULL;
|
||||
result->unbound_ctx = ub_ctx_create();
|
||||
|
||||
result->resolution_type_set = 0;
|
||||
|
||||
|
@ -375,10 +365,7 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
getdns_list_destroy(context->upstream_list);
|
||||
|
||||
/* destroy the ub context */
|
||||
ub_ctx_delete(context->unbound_async);
|
||||
ub_ctx_delete(context->unbound_sync);
|
||||
|
||||
event_base_free(context->event_base_sync);
|
||||
ub_ctx_delete(context->unbound_ctx);
|
||||
|
||||
ldns_rbtree_free(context->outbound_requests);
|
||||
|
||||
|
@ -407,8 +394,7 @@ getdns_context_set_context_update_callback(struct getdns_context *context,
|
|||
static void
|
||||
set_ub_string_opt(struct getdns_context *ctx, char *opt, char *value)
|
||||
{
|
||||
ub_ctx_set_option(ctx->unbound_sync, opt, value);
|
||||
ub_ctx_set_option(ctx->unbound_async, opt, value);
|
||||
ub_ctx_set_option(ctx->unbound_ctx, opt, value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -883,27 +869,6 @@ getdns_context_set_memory_functions(struct getdns_context *context,
|
|||
context, MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free);
|
||||
} /* getdns_context_set_memory_functions*/
|
||||
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libevent_base
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base * this_event_base)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
if (this_event_base) {
|
||||
ub_ctx_set_event(context->unbound_async, this_event_base);
|
||||
context->event_base_async = this_event_base;
|
||||
} else {
|
||||
ub_ctx_set_event(context->unbound_async,
|
||||
context->event_base_sync);
|
||||
context->event_base_async = NULL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_extension_set_libevent_base */
|
||||
|
||||
/* cancel the request */
|
||||
static void
|
||||
cancel_dns_req(getdns_dns_req * req)
|
||||
|
@ -913,7 +878,7 @@ cancel_dns_req(getdns_dns_req * req)
|
|||
if (netreq->state == NET_REQ_IN_FLIGHT) {
|
||||
/* for ev based ub, this should always prevent
|
||||
* the callback from firing */
|
||||
ub_cancel(req->unbound, netreq->unbound_id);
|
||||
ub_cancel(req->context->unbound_ctx, netreq->unbound_id);
|
||||
netreq->state = NET_REQ_CANCELED;
|
||||
} else if (netreq->state == NET_REQ_NOT_SENT) {
|
||||
netreq->state = NET_REQ_CANCELED;
|
||||
|
@ -1063,19 +1028,15 @@ getdns_context_prepare_for_resolution(struct getdns_context *context)
|
|||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
/* set upstreams */
|
||||
ub_setup_stub(context->unbound_async, context->upstream_list,
|
||||
upstream_len);
|
||||
ub_setup_stub(context->unbound_sync, context->upstream_list,
|
||||
ub_setup_stub(context->unbound_ctx, context->upstream_list,
|
||||
upstream_len);
|
||||
/* use /etc/hosts */
|
||||
ub_ctx_hosts(context->unbound_sync, NULL);
|
||||
ub_ctx_hosts(context->unbound_async, NULL);
|
||||
ub_ctx_hosts(context->unbound_ctx, NULL);
|
||||
|
||||
} else if (context->resolution_type == GETDNS_CONTEXT_RECURSING) {
|
||||
/* set recursive */
|
||||
/* TODO: use the root servers via root hints file */
|
||||
ub_ctx_set_fwd(context->unbound_async, NULL);
|
||||
ub_ctx_set_fwd(context->unbound_sync, NULL);
|
||||
ub_ctx_set_fwd(context->unbound_ctx, NULL);
|
||||
|
||||
} else {
|
||||
/* bogus? */
|
||||
|
@ -1121,6 +1082,23 @@ getdns_context_clear_outbound_request(getdns_dns_req * req)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/* get the fd */
|
||||
int getdns_context_fd(struct getdns_context* context) {
|
||||
RETURN_IF_NULL(context, -1);
|
||||
return ub_fd(context->unbound_ctx);
|
||||
}
|
||||
|
||||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
if (ub_process(context->unbound_ctx) != 0) {
|
||||
/* need an async return code? */
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include <getdns/getdns.h>
|
||||
#include "types-internal.h"
|
||||
|
||||
struct event_base;
|
||||
struct getdns_dns_req;
|
||||
struct ldns_rbtree_t;
|
||||
struct ub_ctx;
|
||||
|
@ -63,15 +62,9 @@ struct getdns_context {
|
|||
struct mem_funcs mf;
|
||||
struct mem_funcs my_mf;
|
||||
|
||||
/* Event loop for sync requests */
|
||||
struct event_base *event_base_sync;
|
||||
/* Event loop for async requests */
|
||||
struct event_base *event_base_async;
|
||||
|
||||
/* The underlying unbound contexts that do
|
||||
* the real work */
|
||||
struct ub_ctx *unbound_sync;
|
||||
struct ub_ctx *unbound_async;
|
||||
struct ub_ctx *unbound_ctx;
|
||||
|
||||
/* which resolution type the contexts are configured for
|
||||
* 0 means nothing set
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "context.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define evutil_socket_t int
|
||||
# define event_free free
|
||||
# define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
|
||||
#endif
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
#ifndef HAVE_EVENT2_EVENT_H
|
||||
static struct event *
|
||||
event_new(struct event_base *b, evutil_socket_t fd, short ev, void* cb, void *arg)
|
||||
{
|
||||
struct event* e = (struct event*)calloc(1, sizeof(struct event));
|
||||
if(!e) return NULL;
|
||||
event_set(e, fd, ev, cb, arg);
|
||||
event_base_set(b, e);
|
||||
return e;
|
||||
}
|
||||
#endif /* no event2 */
|
||||
|
||||
void getdns_libevent_cb(evutil_socket_t fd, short what, void *userarg) {
|
||||
struct getdns_context* context = (struct getdns_context*) userarg;
|
||||
getdns_context_process_async(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libevent_base
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base * this_event_base)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(this_event_base, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* TODO: cleanup current extension base */
|
||||
int fd = getdns_context_fd(context);
|
||||
struct event *getdns_event = event_new(this_event_base, fd, EV_READ | EV_PERSIST, getdns_libevent_cb, context);
|
||||
event_add(getdns_event, NULL);
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_extension_set_libevent_base */
|
228
src/general.c
228
src/general.c
|
@ -35,17 +35,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define evutil_socket_t int
|
||||
# define event_free free
|
||||
# define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unbound.h>
|
||||
#include <unbound-event.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include "context.h"
|
||||
#include "types-internal.h"
|
||||
|
@ -56,11 +47,10 @@
|
|||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
|
||||
/* declarations */
|
||||
static void ub_resolve_callback(void *arg, int err, ldns_buffer * result,
|
||||
int sec, char *bogus);
|
||||
static void ub_resolve_timeout(evutil_socket_t fd, short what, void *arg);
|
||||
static void ub_local_resolve_timeout(evutil_socket_t fd, short what,
|
||||
void *arg);
|
||||
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
|
||||
// static void ub_resolve_timeout(evutil_socket_t fd, short what, void *arg);
|
||||
// static void ub_local_resolve_timeout(evutil_socket_t fd, short what,
|
||||
// void *arg);
|
||||
|
||||
static void handle_network_request_error(getdns_network_req * netreq, int err);
|
||||
static void handle_dns_request_complete(getdns_dns_req * dns_req);
|
||||
|
@ -75,60 +65,48 @@ typedef struct netreq_cb_data
|
|||
char *bogus;
|
||||
} netreq_cb_data;
|
||||
|
||||
#ifndef HAVE_EVENT2_EVENT_H
|
||||
static struct event *
|
||||
event_new(struct event_base *b, evutil_socket_t fd, short ev, void* cb, void *arg)
|
||||
{
|
||||
struct event* e = (struct event*)calloc(1, sizeof(struct event));
|
||||
if(!e) return NULL;
|
||||
event_set(e, fd, ev, cb, arg);
|
||||
event_base_set(b, e);
|
||||
return e;
|
||||
}
|
||||
#endif /* no event2 */
|
||||
// /* cancel, cleanup and send timeout to callback */
|
||||
// static void
|
||||
// ub_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
// {
|
||||
// getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||
// struct getdns_context *context = dns_req->context;
|
||||
// getdns_transaction_t trans_id = dns_req->trans_id;
|
||||
// getdns_callback_t cb = dns_req->user_callback;
|
||||
// void *user_arg = dns_req->user_pointer;
|
||||
|
||||
/* cancel, cleanup and send timeout to callback */
|
||||
static void
|
||||
ub_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||
struct getdns_context *context = dns_req->context;
|
||||
getdns_transaction_t trans_id = dns_req->trans_id;
|
||||
getdns_callback_t cb = dns_req->user_callback;
|
||||
void *user_arg = dns_req->user_pointer;
|
||||
// /* cancel the req - also clears it from outbound */
|
||||
// getdns_context_cancel_request(context, trans_id, 0);
|
||||
|
||||
/* cancel the req - also clears it from outbound */
|
||||
getdns_context_cancel_request(context, trans_id, 0);
|
||||
// /* cleanup */
|
||||
// dns_req_free(dns_req);
|
||||
|
||||
/* cleanup */
|
||||
dns_req_free(dns_req);
|
||||
// cb(context, GETDNS_CALLBACK_TIMEOUT, NULL, user_arg, trans_id);
|
||||
// }
|
||||
|
||||
cb(context, GETDNS_CALLBACK_TIMEOUT, NULL, user_arg, trans_id);
|
||||
}
|
||||
// static void
|
||||
// ub_local_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
// {
|
||||
// netreq_cb_data *cb_data = (netreq_cb_data *) arg;
|
||||
|
||||
static void
|
||||
ub_local_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
netreq_cb_data *cb_data = (netreq_cb_data *) arg;
|
||||
// /* cleanup the local timer here since the memory may be
|
||||
// * invalid after calling ub_resolve_callback
|
||||
// */
|
||||
// getdns_dns_req *dnsreq = cb_data->netreq->owner;
|
||||
// event_free(dnsreq->local_cb_timer);
|
||||
// dnsreq->local_cb_timer = NULL;
|
||||
|
||||
/* cleanup the local timer here since the memory may be
|
||||
* invalid after calling ub_resolve_callback
|
||||
*/
|
||||
getdns_dns_req *dnsreq = cb_data->netreq->owner;
|
||||
event_free(dnsreq->local_cb_timer);
|
||||
dnsreq->local_cb_timer = NULL;
|
||||
// /* just call ub_resolve_callback */
|
||||
// ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->result,
|
||||
// cb_data->sec, cb_data->bogus);
|
||||
|
||||
/* just call ub_resolve_callback */
|
||||
ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->result,
|
||||
cb_data->sec, cb_data->bogus);
|
||||
|
||||
/* cleanup the state */
|
||||
ldns_buffer_free(cb_data->result);
|
||||
if (cb_data->bogus) {
|
||||
free(cb_data->bogus);
|
||||
}
|
||||
free(cb_data);
|
||||
}
|
||||
// /* cleanup the state */
|
||||
// ldns_buffer_free(cb_data->result);
|
||||
// if (cb_data->bogus) {
|
||||
// free(cb_data->bogus);
|
||||
// }
|
||||
// free(cb_data);
|
||||
// }
|
||||
|
||||
/* cleanup and send an error to the user callback */
|
||||
static void
|
||||
|
@ -174,7 +152,7 @@ static int
|
|||
submit_network_request(getdns_network_req * netreq)
|
||||
{
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
int r = ub_resolve_event(dns_req->unbound,
|
||||
int r = ub_resolve_async(dns_req->context->unbound_ctx,
|
||||
dns_req->name,
|
||||
netreq->request_type,
|
||||
netreq->request_class,
|
||||
|
@ -186,82 +164,84 @@ submit_network_request(getdns_network_req * netreq)
|
|||
}
|
||||
|
||||
static void
|
||||
ub_resolve_callback(void *arg, int err, ldns_buffer * result, int sec,
|
||||
char *bogus)
|
||||
ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
||||
// ub_resolve_callback(void *arg, int err, ldns_buffer * result, int sec,
|
||||
// char *bogus)
|
||||
{
|
||||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
if (err != 0) {
|
||||
handle_network_request_error(netreq, err);
|
||||
return;
|
||||
}
|
||||
/* if netreq->state == NET_REQ_NOT_SENT here, that implies
|
||||
* that ub called us back immediately - probably from a local file.
|
||||
* This most likely means that getdns_general has not returned
|
||||
*/
|
||||
if (netreq->state == NET_REQ_NOT_SENT) {
|
||||
/* TODO!!!! */
|
||||
/* just do a very short timer since this was called immediately.
|
||||
* we can make this less hacky, but it gets interesting when multiple
|
||||
* netreqs need to be issued and some resolve immediately vs. not.
|
||||
*/
|
||||
struct timeval tv;
|
||||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
netreq_cb_data *cb_data =
|
||||
(netreq_cb_data *) malloc(sizeof(netreq_cb_data));
|
||||
// struct timeval tv;
|
||||
// getdns_dns_req *dnsreq = netreq->owner;
|
||||
// netreq_cb_data *cb_data =
|
||||
// (netreq_cb_data *) malloc(sizeof(netreq_cb_data));
|
||||
|
||||
cb_data->netreq = netreq;
|
||||
cb_data->err = err;
|
||||
cb_data->sec = sec;
|
||||
cb_data->result = NULL;
|
||||
cb_data->bogus = NULL; /* unused but here in case we need it */
|
||||
if (result) {
|
||||
cb_data->result =
|
||||
ldns_buffer_new(ldns_buffer_limit(result));
|
||||
if (!cb_data->result) {
|
||||
cb_data->err = GETDNS_RETURN_GENERIC_ERROR;
|
||||
} else {
|
||||
/* copy */
|
||||
ldns_buffer_copy(cb_data->result, result);
|
||||
}
|
||||
}
|
||||
/* schedule the timeout */
|
||||
dnsreq->local_cb_timer =
|
||||
evtimer_new(dnsreq->ev_base, ub_local_resolve_timeout,
|
||||
cb_data);
|
||||
tv.tv_sec = 0;
|
||||
/* half ms */
|
||||
tv.tv_usec = 500;
|
||||
evtimer_add(dnsreq->local_cb_timer, &tv);
|
||||
// cb_data->netreq = netreq;
|
||||
// cb_data->err = err;
|
||||
// cb_data->sec = sec;
|
||||
// cb_data->result = NULL;
|
||||
// cb_data->bogus = NULL; /* unused but here in case we need it */
|
||||
// if (result) {
|
||||
// cb_data->result =
|
||||
// ldns_buffer_new(ldns_buffer_limit(result));
|
||||
// if (!cb_data->result) {
|
||||
// cb_data->err = GETDNS_RETURN_GENERIC_ERROR;
|
||||
// } else {
|
||||
// /* copy */
|
||||
// ldns_buffer_copy(cb_data->result, result);
|
||||
// }
|
||||
// }
|
||||
// /* schedule the timeout */
|
||||
// dnsreq->local_cb_timer =
|
||||
// evtimer_new(dnsreq->ev_base, ub_local_resolve_timeout,
|
||||
// cb_data);
|
||||
// tv.tv_sec = 0;
|
||||
// /* half ms */
|
||||
// tv.tv_usec = 500;
|
||||
// evtimer_add(dnsreq->local_cb_timer, &tv);
|
||||
return;
|
||||
}
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
if (err) {
|
||||
handle_network_request_error(netreq, err);
|
||||
} else {
|
||||
/* parse */
|
||||
ldns_status r =
|
||||
ldns_buffer2pkt_wire(&(netreq->result), result);
|
||||
if (r != LDNS_STATUS_OK) {
|
||||
handle_network_request_error(netreq, r);
|
||||
/* parse */
|
||||
/* TODO: optimize */
|
||||
getdns_return_t r = getdns_apply_network_result(netreq, ub_res);
|
||||
ub_resolve_free(ub_res);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
handle_network_request_error(netreq, err);
|
||||
} else {
|
||||
/* is this the last request */
|
||||
if (!netreq->next) {
|
||||
/* finished */
|
||||
handle_dns_request_complete(netreq->owner);
|
||||
} else {
|
||||
/* is this the last request */
|
||||
if (!netreq->next) {
|
||||
/* finished */
|
||||
handle_dns_request_complete(netreq->owner);
|
||||
} else {
|
||||
/* not finished - update to next request and ship it */
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
dns_req->current_req = netreq->next;
|
||||
submit_network_request(netreq->next);
|
||||
}
|
||||
/* not finished - update to next request and ship it */
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
dns_req->current_req = netreq->next;
|
||||
submit_network_request(netreq->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_general_ub(struct ub_ctx *unbound,
|
||||
struct event_base *ev_base,
|
||||
struct getdns_context *context,
|
||||
getdns_general_ub(struct getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
struct getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn)
|
||||
getdns_transaction_t * transaction_id,
|
||||
getdns_callback_t callbackfn)
|
||||
{
|
||||
/* timeout */
|
||||
struct timeval tv;
|
||||
|
@ -279,7 +259,6 @@ getdns_general_ub(struct ub_ctx *unbound,
|
|||
|
||||
/* request state */
|
||||
getdns_dns_req *req = dns_req_new(context,
|
||||
unbound,
|
||||
name,
|
||||
request_type,
|
||||
extensions);
|
||||
|
@ -296,12 +275,13 @@ getdns_general_ub(struct ub_ctx *unbound,
|
|||
|
||||
getdns_context_track_outbound_request(req);
|
||||
|
||||
/* assign a timeout */
|
||||
req->ev_base = ev_base;
|
||||
req->timeout = evtimer_new(ev_base, ub_resolve_timeout, req);
|
||||
tv.tv_sec = context->timeout / 1000;
|
||||
tv.tv_usec = (context->timeout % 1000) * 1000;
|
||||
evtimer_add(req->timeout, &tv);
|
||||
/* TODO: timeout.. */
|
||||
// /* assign a timeout */
|
||||
// req->ev_base = ev_base;
|
||||
// req->timeout = evtimer_new(ev_base, ub_resolve_timeout, req);
|
||||
// tv.tv_sec = context->timeout / 1000;
|
||||
// tv.tv_usec = (context->timeout % 1000) * 1000;
|
||||
// evtimer_add(req->timeout, &tv);
|
||||
|
||||
/* issue the first network req */
|
||||
|
||||
|
@ -329,7 +309,7 @@ getdns_general(struct getdns_context *context,
|
|||
{
|
||||
int extcheck = GETDNS_RETURN_GOOD;
|
||||
|
||||
if (!context || !context->event_base_async) {
|
||||
if (!context) {
|
||||
/* Can't do async without an event loop
|
||||
* or callback
|
||||
*/
|
||||
|
@ -345,9 +325,7 @@ getdns_general(struct getdns_context *context,
|
|||
if (extcheck != GETDNS_RETURN_GOOD)
|
||||
return extcheck;
|
||||
|
||||
return getdns_general_ub(context->unbound_async,
|
||||
context->event_base_async,
|
||||
context,
|
||||
return getdns_general_ub(context,
|
||||
name, request_type, extensions, userarg, transaction_id, callback);
|
||||
|
||||
} /* getdns_general */
|
||||
|
|
|
@ -40,13 +40,8 @@
|
|||
|
||||
/* private inner helper used by sync and async */
|
||||
|
||||
struct ub_ctx;
|
||||
struct event_base;
|
||||
|
||||
getdns_return_t
|
||||
getdns_general_ub(struct ub_ctx *unbound,
|
||||
struct event_base *ev_base,
|
||||
struct getdns_context *context,
|
||||
getdns_general_ub(struct getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
struct getdns_dict *extensions,
|
||||
|
|
|
@ -884,4 +884,11 @@ getdns_return_t
|
|||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base *this_event_base);
|
||||
|
||||
/* get the fd */
|
||||
int getdns_context_fd(struct getdns_context* context);
|
||||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(struct getdns_context* context);
|
||||
|
||||
|
||||
|
||||
#endif /* GETDNS_H */
|
||||
|
|
|
@ -34,15 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define event_free free
|
||||
#endif
|
||||
#include "types-internal.h"
|
||||
#include "util-internal.h"
|
||||
#include <unbound.h>
|
||||
|
||||
void
|
||||
network_req_free(getdns_network_req * net_req)
|
||||
|
@ -103,17 +96,6 @@ dns_req_free(getdns_dns_req * req)
|
|||
net_req = next;
|
||||
}
|
||||
|
||||
/* cleanup timeout */
|
||||
if (req->timeout) {
|
||||
event_del(req->timeout);
|
||||
event_free(req->timeout);
|
||||
}
|
||||
|
||||
if (req->local_cb_timer) {
|
||||
event_del(req->local_cb_timer);
|
||||
event_free(req->local_cb_timer);
|
||||
}
|
||||
|
||||
/* free strduped name */
|
||||
free(req->name);
|
||||
|
||||
|
@ -123,7 +105,6 @@ dns_req_free(getdns_dns_req * req)
|
|||
/* create a new dns req to be submitted */
|
||||
getdns_dns_req *
|
||||
dns_req_new(struct getdns_context *context,
|
||||
struct ub_ctx *unbound,
|
||||
const char *name, uint16_t request_type, struct getdns_dict *extensions)
|
||||
{
|
||||
|
||||
|
@ -139,14 +120,13 @@ dns_req_new(struct getdns_context *context,
|
|||
|
||||
result->name = strdup(name);
|
||||
result->context = context;
|
||||
result->unbound = unbound;
|
||||
result->canceled = 0;
|
||||
result->current_req = NULL;
|
||||
result->first_req = NULL;
|
||||
result->trans_id = ldns_get_random();
|
||||
result->timeout = NULL;
|
||||
result->local_cb_timer = NULL;
|
||||
result->ev_base = NULL;
|
||||
// result->timeout = NULL;
|
||||
// result->local_cb_timer = NULL;
|
||||
// result->ev_base = NULL;
|
||||
|
||||
getdns_dict_copy(extensions, &result->extensions);
|
||||
|
||||
|
|
59
src/sync.c
59
src/sync.c
|
@ -34,13 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
#endif
|
||||
#include <getdns/getdns.h>
|
||||
#include <unbound-event.h>
|
||||
#include <unbound.h>
|
||||
#include "context.h"
|
||||
#include "general.h"
|
||||
#include "types-internal.h"
|
||||
|
@ -51,14 +46,28 @@
|
|||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
static void
|
||||
sync_callback_func(struct getdns_context *context,
|
||||
uint16_t callback_type,
|
||||
struct getdns_dict *response,
|
||||
void *userarg, getdns_transaction_t transaction_id)
|
||||
{
|
||||
|
||||
*((struct getdns_dict **) userarg) = response;
|
||||
getdns_return_t submit_request_sync(getdns_dns_req* req) {
|
||||
struct ub_result* ub_res = NULL;
|
||||
getdns_return_t gr = GETDNS_RETURN_GOOD;
|
||||
getdns_network_req *netreq = req->first_req;
|
||||
while (netreq) {
|
||||
int r = ub_resolve(req->context->unbound_ctx,
|
||||
req->name,
|
||||
netreq->request_type,
|
||||
netreq->request_class,
|
||||
&ub_res);
|
||||
if (r != 0) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
gr = getdns_apply_network_result(netreq, ub_res);
|
||||
ub_resolve_free(ub_res);
|
||||
ub_res = NULL;
|
||||
if (gr != GETDNS_RETURN_GOOD) {
|
||||
return gr;
|
||||
}
|
||||
netreq = netreq->next;
|
||||
}
|
||||
return gr;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
|
@ -73,12 +82,22 @@ getdns_general_sync(struct getdns_context *context,
|
|||
RETURN_IF_NULL(response, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
response_status = validate_extensions(extensions);
|
||||
if (response_status == GETDNS_RETURN_GOOD) {
|
||||
response_status = getdns_general_ub(context->unbound_sync,
|
||||
context->event_base_sync,
|
||||
context, name, request_type,
|
||||
extensions, (void *) response, NULL, sync_callback_func);
|
||||
|
||||
event_base_dispatch(context->event_base_sync);
|
||||
/* for each netreq we call ub_ctx_resolve */
|
||||
/* request state */
|
||||
getdns_dns_req *req = dns_req_new(context,
|
||||
name,
|
||||
request_type,
|
||||
extensions);
|
||||
if (!req) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
response_status = submit_request_sync(req);
|
||||
if (response_status != GETDNS_RETURN_GOOD) {
|
||||
dns_req_free(req);
|
||||
return response_status;
|
||||
}
|
||||
*response = create_getdns_response(req);
|
||||
dns_req_free(req);
|
||||
}
|
||||
return response_status;
|
||||
}
|
||||
|
|
|
@ -99,9 +99,6 @@ struct getdns_context;
|
|||
/* declarations */
|
||||
struct getdns_dns_req;
|
||||
struct getdns_network_req;
|
||||
struct ub_ctx;
|
||||
struct event;
|
||||
struct event_base;
|
||||
|
||||
typedef enum network_req_state_enum
|
||||
{
|
||||
|
@ -164,21 +161,9 @@ typedef struct getdns_dns_req
|
|||
/* first request in list */
|
||||
struct getdns_network_req *first_req;
|
||||
|
||||
/* request timeout event */
|
||||
struct event *timeout;
|
||||
|
||||
/* local callback timer */
|
||||
struct event *local_cb_timer;
|
||||
|
||||
/* event base this req is scheduled on */
|
||||
struct event_base *ev_base;
|
||||
|
||||
/* context that owns the request */
|
||||
struct getdns_context *context;
|
||||
|
||||
/* ub_ctx issuing the request */
|
||||
struct ub_ctx *unbound;
|
||||
|
||||
/* request extensions */
|
||||
struct getdns_dict *extensions;
|
||||
|
||||
|
@ -246,7 +231,6 @@ getdns_network_req *network_req_new(getdns_dns_req * owner,
|
|||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *dns_req_new(struct getdns_context *context,
|
||||
struct ub_ctx *unbound,
|
||||
const char *name, uint16_t request_type, struct getdns_dict *extensions);
|
||||
|
||||
void dns_req_free(getdns_dns_req * req);
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "list.h"
|
||||
#include "util-internal.h"
|
||||
#include "types-internal.h"
|
||||
#include <unbound.h>
|
||||
|
||||
/**
|
||||
* this is a comprehensive list of extensions and their data types
|
||||
|
@ -677,4 +678,20 @@ validate_extensions(struct getdns_dict * extensions)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* validate_extensions */
|
||||
|
||||
getdns_return_t getdns_apply_network_result(getdns_network_req* netreq,
|
||||
struct ub_result* ub_res) {
|
||||
ldns_buffer *result = ldns_buffer_new(ub_res->answer_len);
|
||||
if (!result) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
ldns_buffer_new_frm_data(result, ub_res->answer_packet, ub_res->answer_len);
|
||||
ldns_status r =
|
||||
ldns_buffer2pkt_wire(&(netreq->result), result);
|
||||
ldns_buffer_free(result);
|
||||
if (r != LDNS_STATUS_OK) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/* util-internal.c */
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#include <ldns/ldns.h>
|
||||
#include "context.h"
|
||||
|
||||
struct ub_result;
|
||||
struct getdns_network_req;
|
||||
getdns_return_t getdns_apply_network_result(getdns_network_req* netreq, struct ub_result* result);
|
||||
|
||||
/**
|
||||
* add an item to the tail of a list - note that this was not in the getdns API
|
||||
* description but the list_set functions seem to be designed to modify an existing
|
||||
|
|
Loading…
Reference in New Issue