mirror of https://github.com/getdnsapi/getdns.git
eventloop separate from context & libmini_event
This commit is contained in:
parent
a21895d145
commit
1f203485e2
|
@ -78,7 +78,8 @@ EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
|
|||
GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
||||
hostname.lo service.lo request-internal.lo util-internal.lo \
|
||||
getdns_error.lo rr-dict.lo dnssec.lo const-info.lo \
|
||||
ub_timed_resolve.lo stub.lo
|
||||
ub_timed_resolve.lo stub.lo \
|
||||
libmini_event.lo
|
||||
|
||||
GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
|
||||
str2wire.lo
|
||||
|
@ -97,7 +98,7 @@ UTIL_OBJ=mini_event.lo rbtree.lo
|
|||
.c.lo:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ):
|
||||
$(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) libmini_event.lo:
|
||||
@:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
|
@ -193,10 +194,11 @@ configure.status: configure
|
|||
|
||||
depend:
|
||||
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
||||
(cd $(srcdir) ; gcc -MM -I. gldns/*.c compat/*.c util/*.c | \
|
||||
(cd $(srcdir) ; gcc -MM -I. gldns/*.c compat/*.c util/*.c extension/libmini_event.c| \
|
||||
sed -e 's?gldns/?$$(srcdir)/gldns/?g' \
|
||||
-e 's?compat/?$$(srcdir)/compat/?g' \
|
||||
-e 's?util/?$$(srcdir)/util/?g' \
|
||||
-e 's?extension/?$$(srcdir)/extension/?g' \
|
||||
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in.new )
|
||||
(cd $(srcdir) ; diff Makefile.in.new Makefile.in && rm Makefile.in.new \
|
||||
|| mv Makefile.in.new Makefile.in )
|
||||
|
@ -204,7 +206,7 @@ depend:
|
|||
.PHONY: clean test example
|
||||
FORCE:
|
||||
|
||||
# Dependencies for gldns and compatibility functions
|
||||
# Dependencies for gldns, utils, the mini_event extension and compat functions
|
||||
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
|
||||
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h
|
||||
parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \
|
||||
|
@ -221,3 +223,6 @@ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/
|
|||
$(srcdir)/util/fptr_wlist.h
|
||||
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/rbtree.h
|
||||
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c config.h \
|
||||
$(srcdir)/extension/libmini_event.h types-internal.h getdns/getdns.h \
|
||||
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
|
||||
|
|
495
src/context.c
495
src/context.c
|
@ -517,129 +517,6 @@ create_ldns_rbtree(getdns_context * context,
|
|||
return result;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
******************************************************************************
|
||||
*****
|
||||
***** Start of mini_event extension
|
||||
***** TODO: Move to own source file
|
||||
*****/
|
||||
|
||||
/** call timeouts handlers, and return how long to wait for next one or -1 */
|
||||
void getdns_handle_timeouts(struct getdns_event_base* base,
|
||||
struct timeval* now, struct timeval* wait);
|
||||
/** call select and callbacks for that */
|
||||
int getdns_handle_select(struct getdns_event_base* base, struct timeval* wait);
|
||||
|
||||
int
|
||||
getdns_mini_event_settime(getdns_mini_event_extension *e)
|
||||
{
|
||||
if (gettimeofday(e->base->time_tv, NULL) < 0)
|
||||
return -1;
|
||||
*e->base->time_secs = (time_t)e->base->time_tv->tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_mini_event_timeout_cb(int fd, short bits, void *arg)
|
||||
{
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*)arg;
|
||||
timeout_data->callback(timeout_data->userarg);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_schedule_timeout(getdns_context *context, void *ext,
|
||||
uint64_t timeout, getdns_timeout_data_t *timeout_data)
|
||||
{
|
||||
getdns_mini_event_extension *e = (getdns_mini_event_extension *)ext;
|
||||
struct timeval tv;
|
||||
struct getdns_event *ev;
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ev = GETDNS_MALLOC(context->mf, struct getdns_event);
|
||||
timeout_data->extension_timer = ev;
|
||||
getdns_event_set(ev, -1, EV_TIMEOUT, getdns_mini_event_timeout_cb,
|
||||
timeout_data);
|
||||
|
||||
(void) getdns_mini_event_settime(e);
|
||||
(void) getdns_event_base_set(e->base, ev);
|
||||
(void) getdns_event_add(ev, &tv);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_clear_timeout(getdns_context *context, void *ext, void *timer)
|
||||
{
|
||||
/* getdns_mini_event_extension *e = (getdns_mini_event_extension *)ext;
|
||||
*/
|
||||
struct getdns_event *ev = (struct getdns_event *)timer;
|
||||
|
||||
(void) getdns_event_del(ev);
|
||||
GETDNS_FREE(context->mf, ev);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_request_count_changed(getdns_context *context,
|
||||
uint32_t request_count, void *ext)
|
||||
{
|
||||
getdns_mini_event_extension *e = (getdns_mini_event_extension *)ext;
|
||||
|
||||
if (request_count == 0)
|
||||
(void) getdns_event_del(&e->ub_event);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_mini_event_cb(int fd, short bits, void *arg)
|
||||
{
|
||||
getdns_context *context = (getdns_context *)arg;
|
||||
|
||||
if (getdns_context_process_async(context))
|
||||
return;
|
||||
|
||||
getdns_mini_event_request_count_changed(context,
|
||||
getdns_context_get_num_pending_requests(context, NULL),
|
||||
context->extension_data);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_cleanup(getdns_context *context, void *ext);
|
||||
getdns_return_t
|
||||
getdns_mini_event_extension_init(getdns_mini_event_extension *e)
|
||||
{
|
||||
e->base = getdns_event_init(&e->time_secs, &e->time_tv);
|
||||
if (!e->base)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
e->ub_event.ev_fd = -1;
|
||||
e->ext.cleanup_data = getdns_mini_event_cleanup;
|
||||
e->ext.schedule_timeout = getdns_mini_event_schedule_timeout;
|
||||
e->ext.clear_timeout = getdns_mini_event_clear_timeout;
|
||||
e->ext.request_count_changed = getdns_mini_event_request_count_changed;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_cleanup(getdns_context *context, void *ext)
|
||||
{
|
||||
getdns_mini_event_extension *e = (getdns_mini_event_extension *)ext;
|
||||
|
||||
if (e->ub_event.ev_fd != -1) {
|
||||
getdns_event_del(&e->ub_event);
|
||||
e->ub_event.ev_fd = -1;
|
||||
}
|
||||
/* TODO: Cleanup all synchronous events? Maybe not... */
|
||||
getdns_event_base_free(e->base);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/*****
|
||||
***** End of mini_event extension
|
||||
*****
|
||||
*****************************************************************************
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* getdns_context_create
|
||||
*
|
||||
|
@ -655,99 +532,95 @@ getdns_context_create_with_extended_memory_functions(
|
|||
void (*free)(void *userarg, void *)
|
||||
)
|
||||
{
|
||||
struct getdns_context *result = NULL;
|
||||
mf_union mf;
|
||||
getdns_return_t r;
|
||||
struct getdns_context *result = NULL;
|
||||
mf_union mf;
|
||||
|
||||
if (!context || !malloc || !realloc || !free)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
if (!context || !malloc || !realloc || !free)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
/** default init **/
|
||||
mf.ext.malloc = malloc;
|
||||
result = userarg == MF_PLAIN
|
||||
? (*mf.pln.malloc)( sizeof(struct getdns_context))
|
||||
: (*mf.ext.malloc)(userarg, sizeof(struct getdns_context));
|
||||
if (!result) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
result->processing = 0;
|
||||
result->destroying = 0;
|
||||
result->my_mf.mf_arg = userarg;
|
||||
result->my_mf.mf.ext.malloc = malloc;
|
||||
result->my_mf.mf.ext.realloc = realloc;
|
||||
result->my_mf.mf.ext.free = free;
|
||||
/** default init **/
|
||||
mf.ext.malloc = malloc;
|
||||
result = userarg == MF_PLAIN
|
||||
? (*mf.pln.malloc)( sizeof(struct getdns_context))
|
||||
: (*mf.ext.malloc)(userarg, sizeof(struct getdns_context));
|
||||
|
||||
result->update_callback = NULL;
|
||||
if (!result)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
result->mf.mf_arg = userarg;
|
||||
result->mf.mf.ext.malloc = malloc;
|
||||
result->mf.mf.ext.realloc = realloc;
|
||||
result->mf.mf.ext.free = free;
|
||||
result->processing = 0;
|
||||
result->destroying = 0;
|
||||
result->my_mf.mf_arg = userarg;
|
||||
result->my_mf.mf.ext.malloc = malloc;
|
||||
result->my_mf.mf.ext.realloc = realloc;
|
||||
result->my_mf.mf.ext.free = free;
|
||||
|
||||
result->resolution_type_set = 0;
|
||||
result->update_callback = NULL;
|
||||
|
||||
result->outbound_requests = create_ldns_rbtree(result, transaction_id_cmp);
|
||||
result->local_hosts = create_ldns_rbtree(result, local_host_cmp);
|
||||
result->mf.mf_arg = userarg;
|
||||
result->mf.mf.ext.malloc = malloc;
|
||||
result->mf.mf.ext.realloc = realloc;
|
||||
result->mf.mf.ext.free = free;
|
||||
|
||||
result->resolution_type_set = 0;
|
||||
|
||||
result->resolution_type = GETDNS_RESOLUTION_RECURSING;
|
||||
if(create_default_namespaces(result) != GETDNS_RETURN_GOOD) {
|
||||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
result->outbound_requests = create_ldns_rbtree(result, transaction_id_cmp);
|
||||
result->local_hosts = create_ldns_rbtree(result, local_host_cmp);
|
||||
|
||||
result->timeout = 5000;
|
||||
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
|
||||
result->dns_root_servers = create_default_root_servers();
|
||||
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
||||
result->suffix = NULL;
|
||||
if (!result->outbound_requests || !result->local_hosts) {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
result->dnssec_trust_anchors = NULL;
|
||||
result->resolution_type = GETDNS_RESOLUTION_RECURSING;
|
||||
if ((r = create_default_namespaces(result)))
|
||||
goto error;
|
||||
|
||||
result->edns_extended_rcode = 0;
|
||||
result->edns_version = 0;
|
||||
result->edns_do_bit = 1;
|
||||
result->timeout = 5000;
|
||||
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
|
||||
result->dns_root_servers = create_default_root_servers();
|
||||
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
|
||||
result->suffix = NULL;
|
||||
|
||||
result->extension = &result->mini_event_extension.ext;
|
||||
result->extension_data = (void *)&result->mini_event_extension;
|
||||
if (getdns_mini_event_extension_init(&result->mini_event_extension))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
result->dnssec_trust_anchors = NULL;
|
||||
|
||||
result->edns_extended_rcode = 0;
|
||||
result->edns_version = 0;
|
||||
result->edns_do_bit = 1;
|
||||
|
||||
result->extension = &result->mini_event.loop;
|
||||
if ((r = getdns_mini_event_init(result, &result->mini_event)))
|
||||
goto error;
|
||||
|
||||
result->fchg_resolvconf = NULL;
|
||||
result->fchg_hosts = NULL;
|
||||
if (set_from_os) {
|
||||
if (GETDNS_RETURN_GOOD != set_os_defaults(result)) {
|
||||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
result->dnssec_allowed_skew = 0;
|
||||
result->edns_maximum_udp_payload_size = 512;
|
||||
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
||||
result->limit_outstanding_queries = 0;
|
||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||
if (!result->outbound_requests ||
|
||||
!result->local_hosts) {
|
||||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
}
|
||||
/* unbound context is initialized here */
|
||||
result->unbound_ctx = NULL;
|
||||
if (GETDNS_RETURN_GOOD != rebuild_ub_ctx(result)) {
|
||||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
/* ldns context is initialised to NULL here and rebuilt later if needed */
|
||||
result->ldns_res = NULL;
|
||||
result->fchg_hosts = NULL;
|
||||
|
||||
if(create_local_hosts(result) != GETDNS_RETURN_GOOD) {
|
||||
getdns_context_destroy(result);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
if (set_from_os && (r = set_os_defaults(result)))
|
||||
goto error;
|
||||
|
||||
*context = result;
|
||||
result->dnssec_allowed_skew = 0;
|
||||
result->edns_maximum_udp_payload_size = 512;
|
||||
result->dns_transport = GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
||||
result->limit_outstanding_queries = 0;
|
||||
result->has_ta = priv_getdns_parse_ta_file(NULL, NULL);
|
||||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
/* unbound context is initialized here */
|
||||
result->unbound_ctx = NULL;
|
||||
if ((r = rebuild_ub_ctx(result)))
|
||||
goto error;
|
||||
|
||||
/* ldns context is initialised to NULL here and rebuilt later if needed */
|
||||
result->ldns_res = NULL;
|
||||
|
||||
if ((r = create_local_hosts(result)))
|
||||
goto error;
|
||||
|
||||
*context = result;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
error:
|
||||
getdns_context_destroy(result);
|
||||
return r;
|
||||
} /* getdns_context_create_with_extended_memory_functions */
|
||||
|
||||
/*
|
||||
|
@ -805,7 +678,7 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
}
|
||||
context->destroying = 1;
|
||||
cancel_outstanding_requests(context, 1);
|
||||
getdns_extension_detach_eventloop(context);
|
||||
getdns_context_detach_eventloop(context);
|
||||
|
||||
if (context->namespaces)
|
||||
GETDNS_FREE(context->my_mf, context->namespaces);
|
||||
|
@ -878,6 +751,33 @@ set_ub_number_opt(struct getdns_context *ctx, char *opt, uint16_t value)
|
|||
set_ub_string_opt(ctx, opt, buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_context_request_count_changed(getdns_context *context, uint32_t prev_rc)
|
||||
{
|
||||
if ((!prev_rc && !context->outbound_requests->count) ||
|
||||
( prev_rc && context->outbound_requests->count))
|
||||
return;
|
||||
|
||||
if (context->outbound_requests->count)
|
||||
context->extension->functions->schedule_read(
|
||||
context->extension, ub_fd(context->unbound_ctx),
|
||||
TIMEOUT_FOREVER, &context->ub_event);
|
||||
else
|
||||
context->extension->functions->clear_read(
|
||||
context->extension, &context->ub_event);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_context_ub_read_cb(void *userarg)
|
||||
{
|
||||
getdns_context *context = (getdns_context *)userarg;
|
||||
int32_t prev_rc = context->outbound_requests->count;
|
||||
|
||||
if (getdns_context_process_async(context)) return;
|
||||
(void) getdns_context_get_num_pending_requests(context, NULL);
|
||||
getdns_context_request_count_changed(context, prev_rc);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
rebuild_ub_ctx(struct getdns_context* context) {
|
||||
if (context->unbound_ctx != NULL) {
|
||||
|
@ -903,14 +803,11 @@ rebuild_ub_ctx(struct getdns_context* context) {
|
|||
(void) ub_ctx_add_ta_file(
|
||||
context->unbound_ctx, TRUST_ANCHOR_FILE);
|
||||
}
|
||||
if (context->extension == (void *)&context->mini_event_extension.ext) {
|
||||
getdns_mini_event_extension *e =&context->mini_event_extension;
|
||||
|
||||
getdns_event_set(&e->ub_event, getdns_context_fd(context),
|
||||
EV_READ, getdns_mini_event_cb, context);
|
||||
(void) getdns_event_base_set(e->base, &e->ub_event);
|
||||
(void) getdns_event_add(&e->ub_event, NULL);
|
||||
}
|
||||
context->ub_event.userarg = context;
|
||||
context->ub_event.read_cb = getdns_context_ub_read_cb;
|
||||
context->ub_event.timeout_cb = NULL;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
@ -1597,25 +1494,6 @@ getdns_context_cancel_request(struct getdns_context *context,
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_cancel_callback
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_cancel_callback(struct getdns_context *context,
|
||||
getdns_transaction_t transaction_id)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
context->processing = 1;
|
||||
getdns_return_t r = getdns_context_cancel_request(context, transaction_id, 1);
|
||||
if (context->extension) {
|
||||
context->extension->request_count_changed(context,
|
||||
context->outbound_requests->count, context->extension_data);
|
||||
}
|
||||
context->processing = 0;
|
||||
return r;
|
||||
} /* getdns_cancel_callback */
|
||||
|
||||
static getdns_return_t
|
||||
ub_setup_stub(struct ub_ctx *ctx, getdns_upstreams *upstreams)
|
||||
{
|
||||
|
@ -1815,47 +1693,54 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
|||
getdns_return_t
|
||||
getdns_context_track_outbound_request(getdns_dns_req * req)
|
||||
{
|
||||
if (!req) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
struct getdns_context *context = req->context;
|
||||
ldns_rbnode_t *node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t);
|
||||
if (!node) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
node->key = &(req->trans_id);
|
||||
node->data = req;
|
||||
if (!ldns_rbtree_insert(context->outbound_requests, node)) {
|
||||
/* free the node */
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
if (context->extension) {
|
||||
context->extension->request_count_changed(context,
|
||||
context->outbound_requests->count, context->extension_data);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
uint32_t prev_rc;
|
||||
ldns_rbnode_t *node;
|
||||
|
||||
if (!req)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
prev_rc = req->context->outbound_requests->count;
|
||||
|
||||
if (!(node = GETDNS_MALLOC(req->context->my_mf, ldns_rbnode_t)))
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
node->key = &(req->trans_id);
|
||||
node->data = req;
|
||||
if (! ldns_rbtree_insert(req->context->outbound_requests, node)) {
|
||||
GETDNS_FREE(req->context->my_mf, node);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
getdns_context_request_count_changed(req->context, prev_rc);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_clear_outbound_request(getdns_dns_req * req)
|
||||
{
|
||||
if (!req) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
struct getdns_context *context = req->context;
|
||||
ldns_rbnode_t *node = ldns_rbtree_delete(context->outbound_requests,
|
||||
&(req->trans_id));
|
||||
if (node) {
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
uint32_t prev_rc;
|
||||
ldns_rbnode_t *node;
|
||||
|
||||
if (!req)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
prev_rc = req->context->outbound_requests->count;
|
||||
|
||||
node = ldns_rbtree_delete(
|
||||
req->context->outbound_requests, &req->trans_id);
|
||||
if (!node)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
GETDNS_FREE(req->context->my_mf, node);
|
||||
getdns_context_request_count_changed(req->context, prev_rc);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_request_timed_out(struct getdns_dns_req
|
||||
*req) {
|
||||
/* Don't use req after callback */
|
||||
getdns_context* context = req->context;
|
||||
uint32_t prev_rc = context->outbound_requests->count;
|
||||
getdns_transaction_t trans_id = req->trans_id;
|
||||
getdns_callback_t cb = req->user_callback;
|
||||
void *user_arg = req->user_pointer;
|
||||
|
@ -1866,10 +1751,7 @@ getdns_context_request_timed_out(struct getdns_dns_req
|
|||
context->processing = 1;
|
||||
cb(context, GETDNS_CALLBACK_TIMEOUT, response, user_arg, trans_id);
|
||||
context->processing = 0;
|
||||
if (context->extension) {
|
||||
context->extension->request_count_changed(context,
|
||||
context->outbound_requests->count, context->extension_data);
|
||||
}
|
||||
getdns_context_request_count_changed(context, prev_rc);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
@ -1927,17 +1809,13 @@ uint32_t
|
|||
getdns_context_get_num_pending_requests(struct getdns_context* context,
|
||||
struct timeval* next_timeout)
|
||||
{
|
||||
static struct timeval dummy = { 0, 0 };
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
if (context->outbound_requests->count &&
|
||||
context->extension == (void *)&context->mini_event_extension.ext &&
|
||||
getdns_mini_event_settime(&context->mini_event_extension) == 0)
|
||||
context->extension == &context->mini_event.loop)
|
||||
|
||||
getdns_handle_timeouts(
|
||||
context->mini_event_extension.base,
|
||||
context->mini_event_extension.base->time_tv,
|
||||
next_timeout ? next_timeout : &dummy);
|
||||
getdns_mini_event_handle_timeouts(
|
||||
&context->mini_event, next_timeout);
|
||||
|
||||
return context->outbound_requests->count;
|
||||
}
|
||||
|
@ -1945,7 +1823,6 @@ getdns_context_get_num_pending_requests(struct getdns_context* context,
|
|||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(struct getdns_context* context)
|
||||
{
|
||||
struct timeval immediately = { 0, 0 };
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
context->processing = 1;
|
||||
|
@ -1954,9 +1831,8 @@ getdns_return_t getdns_context_process_async(struct getdns_context* context)
|
|||
context->processing = 0;
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
if (context->extension == (void *)&context->mini_event_extension.ext
|
||||
&& getdns_handle_select(context->mini_event_extension.base,
|
||||
&immediately)) {
|
||||
if (context->extension == &context->mini_event.loop
|
||||
&& getdns_mini_event_handle_select(&context->mini_event, NULL)) {
|
||||
|
||||
context->processing = 0;
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
@ -1994,7 +1870,7 @@ cancel_outstanding_requests(struct getdns_context* context, int fire_callback) {
|
|||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_extension_detach_eventloop(struct getdns_context* context)
|
||||
getdns_context_detach_eventloop(struct getdns_context* context)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
|
||||
|
@ -2010,73 +1886,64 @@ getdns_extension_detach_eventloop(struct getdns_context* context)
|
|||
context->processing = 1;
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
r = context->extension->cleanup_data(context,
|
||||
context->extension_data);
|
||||
r = context->extension->functions->cleanup(context->extension);
|
||||
if (r == GETDNS_RETURN_GOOD) {
|
||||
context->extension = &context->mini_event_extension.ext;
|
||||
context->extension_data =(void*)&context->mini_event_extension;
|
||||
r = getdns_mini_event_extension_init(
|
||||
&context->mini_event_extension);
|
||||
context->extension = &context->mini_event.loop;
|
||||
r = getdns_mini_event_init(context, &context->mini_event);
|
||||
}
|
||||
context->processing = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_extension_set_eventloop(struct getdns_context* context,
|
||||
getdns_eventloop_extension* extension, void* extension_data)
|
||||
getdns_context_set_eventloop(struct getdns_context* context, getdns_eventloop* loop)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(extension, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
getdns_return_t r = getdns_extension_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
context->extension = extension;
|
||||
context->extension_data = extension_data;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(loop , GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
getdns_return_t r = getdns_context_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD)
|
||||
return r;
|
||||
|
||||
context->extension = loop;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_schedule_timeout(getdns_context* context, uint64_t timeout,
|
||||
getdns_timeout_callback callback, void* userarg,
|
||||
getdns_timeout_data_t *timeout_data)
|
||||
getdns_context_schedule_timeout(getdns_context *context, uint64_t timeout,
|
||||
getdns_eventloop_callback callback, void *userarg,
|
||||
getdns_eventloop_event *el_ev)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(context , GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(callback, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(timeout_data, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(el_ev , GETDNS_RETURN_INVALID_PARAMETER);
|
||||
|
||||
/* Initialize timeout_data struct */
|
||||
timeout_data->context = context;
|
||||
timeout_data->callback = callback;
|
||||
timeout_data->userarg = userarg;
|
||||
timeout_data->extension_timer = NULL;
|
||||
/* Initialize eev_data struct */
|
||||
el_ev->userarg = userarg;
|
||||
el_ev->read_cb = NULL;
|
||||
el_ev->timeout_cb = callback;
|
||||
el_ev->ev = NULL;
|
||||
|
||||
return context->extension->schedule_timeout(context,
|
||||
context->extension_data, timeout, timeout_data);
|
||||
return context->extension->functions->schedule_timeout(
|
||||
context->extension, timeout, el_ev);
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_clear_timeout(getdns_context* context,
|
||||
getdns_timeout_data_t *timeout_data)
|
||||
getdns_eventloop_event *el_ev)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(timeout_data, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(timeout_data->context, GETDNS_RETURN_GOOD);
|
||||
|
||||
context->extension->clear_timeout(context,
|
||||
context->extension_data, timeout_data->extension_timer);
|
||||
timeout_data->context = NULL;
|
||||
RETURN_IF_NULL(el_ev, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
RETURN_IF_NULL(el_ev->timeout_cb, GETDNS_RETURN_GOOD);
|
||||
|
||||
if (el_ev->timeout_cb) {
|
||||
context->extension->functions->clear_timeout(
|
||||
context->extension, el_ev);
|
||||
el_ev->timeout_cb = NULL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
void*
|
||||
getdns_context_get_extension_data(struct getdns_context* context) {
|
||||
RETURN_IF_NULL(context, NULL);
|
||||
return context->extension_data;
|
||||
}
|
||||
|
||||
static inline getdns_return_t
|
||||
priv_dict_set_list_if_not_null(getdns_dict* dict,
|
||||
const char* name, getdns_list* list) {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "getdns/getdns_extra.h"
|
||||
#include "config.h"
|
||||
#include "types-internal.h"
|
||||
#include "util/mini_event.h"
|
||||
#include "extension/libmini_event.h"
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct ldns_rbtree_t;
|
||||
|
@ -82,14 +82,6 @@ typedef struct getdns_upstreams {
|
|||
struct getdns_upstream upstreams[];
|
||||
} getdns_upstreams;
|
||||
|
||||
typedef struct getdns_mini_event_extention {
|
||||
getdns_eventloop_extension ext;
|
||||
time_t time_secs;
|
||||
struct timeval time_tv;
|
||||
struct getdns_event_base *base;
|
||||
struct getdns_event ub_event;
|
||||
} getdns_mini_event_extension;
|
||||
|
||||
struct getdns_context {
|
||||
/* Context values */
|
||||
getdns_resolution_t resolution_type;
|
||||
|
@ -137,20 +129,12 @@ struct getdns_context {
|
|||
*/
|
||||
struct ldns_rbtree_t *outbound_requests;
|
||||
|
||||
/*
|
||||
* Event loop extension functions
|
||||
* These structs are static and should never be freed
|
||||
* since they are just a collection of function pointers
|
||||
*/
|
||||
getdns_eventloop_extension* extension;
|
||||
/*
|
||||
* Extension data that will be freed by the functions
|
||||
* in the extension struct
|
||||
*/
|
||||
void* extension_data;
|
||||
/* Event loop extension. */
|
||||
getdns_eventloop *extension;
|
||||
getdns_eventloop_event ub_event;
|
||||
|
||||
/* The default extension */
|
||||
getdns_mini_event_extension mini_event_extension;
|
||||
getdns_mini_event mini_event;
|
||||
|
||||
/*
|
||||
* state data used to detect changes to the system config files
|
||||
|
@ -197,11 +181,11 @@ void getdns_bindata_destroy(
|
|||
|
||||
/* timeout scheduling */
|
||||
getdns_return_t getdns_context_schedule_timeout(getdns_context* context,
|
||||
uint64_t timeout, getdns_timeout_callback callback, void* userarg,
|
||||
getdns_timeout_data_t *init_to_track);
|
||||
uint64_t timeout, getdns_eventloop_callback callback, void* userarg,
|
||||
getdns_eventloop_event *init_to_track);
|
||||
|
||||
getdns_return_t getdns_context_clear_timeout(getdns_context* context,
|
||||
getdns_timeout_data_t *timeout_data);
|
||||
getdns_eventloop_event *timeout_data);
|
||||
|
||||
/* perform name resolution in /etc/hosts */
|
||||
getdns_return_t getdns_context_local_namespace_resolve(getdns_dns_req* req,
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/**
|
||||
*
|
||||
* \file libmini_event.c
|
||||
* @brief Build in default eventloop extension that uses select.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "extension/libmini_event.h"
|
||||
#include "util/mini_event.h"
|
||||
#include "context.h"
|
||||
|
||||
void getdns_handle_timeouts(struct getdns_event_base* base,
|
||||
struct timeval* now, struct timeval* wait);
|
||||
int getdns_handle_select(struct getdns_event_base* base, struct timeval* wait);
|
||||
|
||||
static getdns_return_t getdns_mini_event_cleanup(getdns_eventloop *loop);
|
||||
static getdns_return_t getdns_mini_event_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_mini_event_schedule_timeout
|
||||
(getdns_eventloop *loop, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
static getdns_return_t getdns_mini_event_clear_event
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
static getdns_eventloop_functions getdns_mini_event_functions = {
|
||||
getdns_mini_event_cleanup,
|
||||
getdns_mini_event_schedule_read,
|
||||
getdns_mini_event_clear_event,
|
||||
getdns_mini_event_schedule_timeout,
|
||||
getdns_mini_event_clear_event,
|
||||
};
|
||||
|
||||
getdns_return_t
|
||||
getdns_mini_event_init(getdns_context *context, getdns_mini_event *ext)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!ext) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
ext->loop.functions = &getdns_mini_event_functions;
|
||||
ext->base = getdns_event_init(&ext->time_secs, &ext->time_tv);
|
||||
if (!ext->base)
|
||||
return GETDNS_RETURN_MEMORY_ERROR;
|
||||
|
||||
ext->mf = context->mf;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_mini_event_create(getdns_context *context, getdns_mini_event **ext)
|
||||
{
|
||||
if (!context) return GETDNS_RETURN_BAD_CONTEXT;
|
||||
if (!ext) return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
*ext = GETDNS_MALLOC(context->mf, getdns_mini_event);
|
||||
return getdns_mini_event_init(context, *ext);
|
||||
}
|
||||
|
||||
void
|
||||
getdns_mini_event_destroy(getdns_mini_event *ext)
|
||||
{
|
||||
if (ext) {
|
||||
ext->loop.functions->cleanup(&ext->loop);
|
||||
GETDNS_FREE(ext->mf, ext);
|
||||
}
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_cleanup(getdns_eventloop *loop)
|
||||
{
|
||||
getdns_mini_event *ext = (getdns_mini_event *)loop;
|
||||
|
||||
getdns_event_base_free(ext->base);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static int
|
||||
getdns_mini_event_settime(getdns_mini_event *ext)
|
||||
{
|
||||
if (gettimeofday(&ext->time_tv, NULL) < 0)
|
||||
return -1;
|
||||
ext->time_secs = (time_t)ext->time_tv.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Call timeouts handlers, and return how long to wait for next one or -1 */
|
||||
void
|
||||
getdns_mini_event_handle_timeouts(getdns_mini_event *ext, struct timeval *wait)
|
||||
{
|
||||
struct timeval dispose = { 0, 0 };
|
||||
|
||||
if (getdns_mini_event_settime(ext) == 0)
|
||||
getdns_handle_timeouts(
|
||||
ext->base, &ext->time_tv, wait ? wait : &dispose);
|
||||
}
|
||||
|
||||
/** Call select and callbacks for that */
|
||||
getdns_return_t
|
||||
getdns_mini_event_handle_select(getdns_mini_event *ext, struct timeval* wait)
|
||||
{
|
||||
static struct timeval immediately = { 0, 0 };
|
||||
|
||||
return getdns_handle_select(ext->base, wait ? wait : &immediately)
|
||||
? GETDNS_RETURN_GENERIC_ERROR : GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_mini_event_callback(int fd, short bits, void *arg)
|
||||
{
|
||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)arg;
|
||||
if (bits & EV_READ) {
|
||||
assert(el_ev->read_cb);
|
||||
el_ev->read_cb(el_ev->userarg);
|
||||
} else if (bits & EV_TIMEOUT) {
|
||||
assert(el_ev->timeout_cb);
|
||||
el_ev->timeout_cb(el_ev->userarg);
|
||||
} else
|
||||
assert(ASSERT_UNREACHABLE);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_schedule_read(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_mini_event *ext = (getdns_mini_event *)loop;
|
||||
struct getdns_event *my_ev;
|
||||
struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
|
||||
short bits =
|
||||
((fd >= 0 && el_ev->read_cb ? EV_READ : 0) |
|
||||
(timeout!=TIMEOUT_FOREVER && el_ev->timeout_cb ? EV_TIMEOUT : 0));
|
||||
|
||||
if (!bits)
|
||||
return GETDNS_RETURN_GOOD; /* Nothing to schedule */
|
||||
|
||||
my_ev = GETDNS_MALLOC(ext->mf, struct getdns_event);
|
||||
el_ev->ev = my_ev;
|
||||
getdns_event_set(my_ev, fd, bits, getdns_mini_event_callback, el_ev);
|
||||
|
||||
if (getdns_mini_event_settime(ext))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
(void) getdns_event_base_set(ext->base, my_ev);
|
||||
if (getdns_event_add(my_ev, &tv))
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_schedule_timeout(getdns_eventloop *loop,
|
||||
uint64_t timeout, getdns_eventloop_event *el_ev)
|
||||
{
|
||||
return getdns_mini_event_schedule_read(loop, -1, timeout, el_ev);
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_mini_event_clear_event(getdns_eventloop *loop,
|
||||
getdns_eventloop_event *el_ev)
|
||||
{
|
||||
getdns_mini_event *ext = (getdns_mini_event *)loop;
|
||||
|
||||
assert(el_ev->ev);
|
||||
|
||||
if (getdns_event_del(el_ev->ev) != 0)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
GETDNS_FREE(ext->mf, el_ev->ev);
|
||||
el_ev->ev = NULL;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
/* libmini_event.c */
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
*
|
||||
* \file libmini_event.h
|
||||
* @brief Build in default eventloop extension that uses select.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _GETDNS_LIBMINI_EVENT_H_
|
||||
#define _GETDNS_LIBMINI_EVENT_H_
|
||||
|
||||
#include "util/mini_event.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
typedef struct getdns_mini_event {
|
||||
getdns_eventloop loop;
|
||||
time_t time_secs;
|
||||
struct timeval time_tv;
|
||||
struct getdns_event_base *base;
|
||||
struct mem_funcs mf;
|
||||
} getdns_mini_event;
|
||||
|
||||
getdns_return_t
|
||||
getdns_mini_event_init(getdns_context *context, getdns_mini_event *mini_event);
|
||||
|
||||
getdns_return_t
|
||||
getdns_mini_event_create(getdns_context *ctxt, getdns_mini_event **mini_event);
|
||||
|
||||
void
|
||||
getdns_mini_event_destroy(getdns_mini_event *mini_event);
|
||||
|
||||
/** Call timeouts handlers, and return how long to wait for next one or -1 */
|
||||
void
|
||||
getdns_mini_event_handle_timeouts(getdns_mini_event *ext, struct timeval *wait);
|
||||
|
||||
/** Call select and callbacks for that */
|
||||
getdns_return_t
|
||||
getdns_mini_event_handle_select(getdns_mini_event *ext, struct timeval* wait);
|
||||
|
||||
#endif /* _GETDNS_LIBMINI_EVENT_H_ */
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
/* declarations */
|
||||
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
|
||||
static getdns_return_t ub_resolve_timeout(void *arg);
|
||||
static void ub_resolve_timeout(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);
|
||||
|
@ -64,11 +64,11 @@ typedef struct netreq_cb_data
|
|||
} netreq_cb_data;
|
||||
|
||||
/* cancel, cleanup and send timeout to callback */
|
||||
static getdns_return_t
|
||||
static void
|
||||
ub_resolve_timeout(void *arg)
|
||||
{
|
||||
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||
return getdns_context_request_timed_out(dns_req);
|
||||
(void) getdns_context_request_timed_out(dns_req);
|
||||
}
|
||||
|
||||
void priv_getdns_call_user_callback(getdns_dns_req *dns_req,
|
||||
|
|
|
@ -39,85 +39,105 @@ extern "C" {
|
|||
value is either GETDNS_EXTENSION_TRUE or GETDNS_EXTENSION_FALSE
|
||||
returns GETDNS_RETURN_GOOD on success or GETDNS_RETURN_INVALID_PARAMETER
|
||||
if context or value is invalid */
|
||||
getdns_return_t getdns_context_set_return_dnssec_status(getdns_context* context, int enabled);
|
||||
getdns_return_t getdns_context_set_return_dnssec_status(
|
||||
getdns_context *context, int enabled);
|
||||
|
||||
/* dict util */
|
||||
/* set a string as bindata */
|
||||
getdns_return_t getdns_dict_util_set_string(struct getdns_dict * dict, char *name,
|
||||
const char *value);
|
||||
getdns_return_t getdns_dict_util_set_string(struct getdns_dict * dict,
|
||||
char *name, const char *value);
|
||||
|
||||
/* get a string from a dict. the result must be freed if valid */
|
||||
getdns_return_t getdns_dict_util_get_string(struct getdns_dict * dict, char *name,
|
||||
char **result);
|
||||
|
||||
/* Async support */
|
||||
uint32_t getdns_context_get_num_pending_requests(getdns_context* context, struct timeval* next_timeout);
|
||||
getdns_return_t getdns_dict_util_get_string(struct getdns_dict * dict,
|
||||
char *name, char **result);
|
||||
|
||||
/* get the fd */
|
||||
int getdns_context_fd(getdns_context* context);
|
||||
|
||||
/* tells underlying unbound to use background threads or fork */
|
||||
getdns_return_t getdns_context_set_use_threads(getdns_context* context,
|
||||
int use_threads);
|
||||
|
||||
/* Async support */
|
||||
uint32_t getdns_context_get_num_pending_requests(getdns_context* context,
|
||||
struct timeval* next_timeout);
|
||||
|
||||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(getdns_context* context);
|
||||
|
||||
/* tells underlying unbound to use background threads or fork */
|
||||
getdns_return_t getdns_context_set_use_threads(getdns_context* context, int use_threads);
|
||||
/***************** functions for eventloop extensions ******************/
|
||||
|
||||
/* extensions */
|
||||
typedef getdns_return_t (*getdns_timeout_callback) (void* userarg);
|
||||
typedef void (*getdns_eventloop_callback)(void *userarg);
|
||||
|
||||
/* context timeout data */
|
||||
typedef struct getdns_timeout_data {
|
||||
/* the timeout callback to fire */
|
||||
getdns_timeout_callback callback;
|
||||
/* timeout callback user arg */
|
||||
void* userarg;
|
||||
/* pointer to the underlying extension pointer that the extension
|
||||
will create and free */
|
||||
void* extension_timer;
|
||||
/* context */
|
||||
struct getdns_context* context;
|
||||
} getdns_timeout_data_t;
|
||||
/* context extension event data */
|
||||
typedef struct getdns_eventloop_event {
|
||||
void *userarg;
|
||||
getdns_eventloop_callback read_cb;
|
||||
getdns_eventloop_callback timeout_cb;
|
||||
|
||||
/* call the extension when the data needs to be cleaned up */
|
||||
typedef getdns_return_t (*getdns_eventloop_cleanup_t)(struct getdns_context* context, void* eventloop_data);
|
||||
/* Pointer to the underlying event
|
||||
* that the eventloop extension will create and free.
|
||||
*/
|
||||
void *ev;
|
||||
} getdns_eventloop_event;
|
||||
|
||||
/* call the extension to schedule a timer. Any timer data that needs to be tracked should be
|
||||
stored in eventloop_timer */
|
||||
typedef getdns_return_t (*getdns_eventloop_schedule_timeout_t)(struct getdns_context* context,
|
||||
void* eventloop_data, uint64_t timeout,
|
||||
getdns_timeout_data_t* timeout_data);
|
||||
typedef struct getdns_eventloop_functions getdns_eventloop_functions;
|
||||
typedef struct getdns_eventloop {
|
||||
getdns_eventloop_functions *functions;
|
||||
} getdns_eventloop;
|
||||
|
||||
/* call the extension to free a timer. The timer passed in is the same as that returned in
|
||||
the schedule timeout */
|
||||
typedef getdns_return_t (*getdns_eventloop_clear_timeout_t)(struct getdns_context* context,
|
||||
void* eventloop_data, void* eventloop_timer);
|
||||
/* Call the extension to clean up data allocated on initialization. */
|
||||
typedef getdns_return_t (*getdns_eventloop_cleanup)(getdns_eventloop *loop);
|
||||
|
||||
/* call the extension to tell it that the number of outbound requests changed. This is called
|
||||
when an async request is submitted or canceled by the user */
|
||||
typedef getdns_return_t (*getdns_eventloop_request_count_changed_t)(struct getdns_context* context,
|
||||
uint32_t request_count, void* eventloop_data);
|
||||
/* Call the extension to schedule an event that will trigger when
|
||||
* file descriptor fd will become readble.
|
||||
*
|
||||
* The getdns_eventloop_event must be provided by the caller with the callbacks
|
||||
* and userarg therein already supplied (by the caller). This function must set
|
||||
* the ev pointer (in the getdns_eventloop_event) to refer to the underlying
|
||||
* (extension) event.
|
||||
*/
|
||||
typedef getdns_return_t (*getdns_eventloop_schedule_read)(getdns_eventloop *loop,
|
||||
int fd, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
|
||||
typedef struct getdns_eventloop_extension {
|
||||
getdns_eventloop_cleanup_t cleanup_data;
|
||||
getdns_eventloop_schedule_timeout_t schedule_timeout;
|
||||
getdns_eventloop_clear_timeout_t clear_timeout;
|
||||
getdns_eventloop_request_count_changed_t request_count_changed;
|
||||
} getdns_eventloop_extension;
|
||||
/* Call the extension to free a read event. */
|
||||
typedef getdns_return_t (*getdns_eventloop_clear_read)
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
/* Call the extension to schedule a timer.
|
||||
*
|
||||
* The getdns_eventloop_event must be provided by the caller with the timeout
|
||||
* callback and userarg therein already supplied (by the caller).
|
||||
* This function must set the ev pointer (in the getdns_eventloop_event)
|
||||
* to refer to the underlying (extension) event.
|
||||
*/
|
||||
typedef getdns_return_t (*getdns_eventloop_schedule_timeout)
|
||||
(getdns_eventloop *loop, uint64_t timeout, getdns_eventloop_event *ev);
|
||||
|
||||
/* Call the extension to free a timer. */
|
||||
typedef getdns_return_t (*getdns_eventloop_clear_timeout)
|
||||
(getdns_eventloop *loop, getdns_eventloop_event *ev);
|
||||
|
||||
struct getdns_eventloop_functions {
|
||||
getdns_eventloop_cleanup cleanup;
|
||||
getdns_eventloop_schedule_read schedule_read;
|
||||
getdns_eventloop_clear_read clear_read;
|
||||
getdns_eventloop_schedule_timeout schedule_timeout;
|
||||
getdns_eventloop_clear_timeout clear_timeout;
|
||||
};
|
||||
|
||||
/* set an event loop extension on the context */
|
||||
getdns_return_t
|
||||
getdns_extension_set_eventloop(struct getdns_context* context,
|
||||
getdns_eventloop_extension* extension, void* extension_data);
|
||||
|
||||
void*
|
||||
getdns_context_get_extension_data(struct getdns_context* context);
|
||||
getdns_context_set_eventloop(getdns_context* context,
|
||||
getdns_eventloop *eventloop);
|
||||
|
||||
/* detach the eventloop from the context */
|
||||
getdns_return_t
|
||||
getdns_extension_detach_eventloop(struct getdns_context* context);
|
||||
getdns_context_detach_eventloop(getdns_context *context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ dns_req_new(struct getdns_context *context,
|
|||
/* will be set by caller */
|
||||
result->user_pointer = NULL;
|
||||
result->user_callback = NULL;
|
||||
memset(&result->timeout, 0, sizeof(getdns_timeout_data_t));
|
||||
memset(&result->timeout, 0, sizeof(result->timeout));
|
||||
|
||||
/* check the specify_class extension */
|
||||
(void) getdns_dict_get_int(extensions, "specify_class", &klass);
|
||||
|
|
|
@ -93,6 +93,8 @@ struct getdns_context;
|
|||
#define GETDNS_STR_KEY_NSCOUNT "nscount"
|
||||
#define GETDNS_STR_KEY_ARCOUNT "arcount"
|
||||
|
||||
#define TIMEOUT_FOREVER ((int64_t)-1)
|
||||
#define ASSERT_UNREACHABLE 0
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
@ -198,7 +200,7 @@ typedef struct getdns_dns_req
|
|||
/* the transaction id */
|
||||
getdns_transaction_t trans_id;
|
||||
|
||||
getdns_timeout_data_t timeout;
|
||||
getdns_eventloop_event timeout;
|
||||
|
||||
/* dnssec status */
|
||||
int return_dnssec_status;
|
||||
|
|
Loading…
Reference in New Issue