- unbound-event.h is installed if configured --with-libevent. It

contains low-level library calls, that use libevent's event_base
  and an ldns_buffer for the wire return packet to perform async
  resolution in the client's eventloop.


git-svn-id: file:///svn/unbound/trunk@2970 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2013-09-26 08:34:14 +00:00
parent cc7dbe6d9a
commit 253d425ca8
15 changed files with 434 additions and 31 deletions

View file

@ -30,6 +30,8 @@ PYTHONMOD_INSTALL=@PYTHONMOD_INSTALL@
PYTHONMOD_UNINSTALL=@PYTHONMOD_UNINSTALL@
PYUNBOUND_INSTALL=@PYUNBOUND_INSTALL@
PYUNBOUND_UNINSTALL=@PYUNBOUND_UNINSTALL@
UNBOUND_EVENT_INSTALL=@UNBOUND_EVENT_INSTALL@
UNBOUND_EVENT_UNINSTALL=@UNBOUND_EVENT_UNINSTALL@
UNBOUND_VERSION_MAJOR=@UNBOUND_VERSION_MAJOR@
UNBOUND_VERSION_MINOR=@UNBOUND_VERSION_MINOR@
UNBOUND_VERSION_MICRO=@UNBOUND_VERSION_MICRO@
@ -455,7 +457,11 @@ pyunbound-install:
$(LIBTOOL) --mode=install cp _unbound.la $(DESTDIR)$(PYTHON_SITE_PKG)
$(LIBTOOL) --mode=finish $(DESTDIR)$(PYTHON_SITE_PKG)
install: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL)
unbound-event-install:
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
$(LIBTOOL) --mode=install cp $(srcdir)/libunbound/unbound-event.h $(DESTDIR)$(includedir)/unbound-event.h
install: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL) $(UNBOUND_EVENT_INSTALL)
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
@ -500,7 +506,10 @@ pyunbound-uninstall:
rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(PYTHON_SITE_PKG)/_unbound.la
uninstall: $(PYTHONMOD_UNINSTALL) $(PYUNBOUND_UNINSTALL)
unbound-event-uninstall:
rm -f -- $(DESTDIR)$(includedir)/unbound-event.h
uninstall: $(PYTHONMOD_UNINSTALL) $(PYUNBOUND_UNINSTALL) $(UNBOUND_EVENT_UNINSTALL)
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8 $(DESTDIR)$(mandir)/man8/unbound-anchor.8 $(DESTDIR)$(mandir)/man8/unbound-control-setup.8
rm -f -- $(DESTDIR)$(mandir)/man1/unbound-host.1 $(DESTDIR)$(mandir)/man3/libunbound.3

6
configure vendored
View file

@ -651,6 +651,8 @@ WINAPPS
WINDRES
CHECKLOCK_OBJ
staticexe
UNBOUND_EVENT_UNINSTALL
UNBOUND_EVENT_INSTALL
HAVE_SSL
CONFIG_DATE
NETBSD_LINTFLAGS
@ -17245,6 +17247,10 @@ done
if test -n "$BAK_LDFLAGS_SET"; then
LDFLAGS="$BAK_LDFLAGS"
fi
UNBOUND_EVENT_INSTALL=unbound-event-install
UNBOUND_EVENT_UNINSTALL=unbound-event-uninstall
else
$as_echo "#define USE_MINI_EVENT 1" >>confdefs.h

View file

@ -802,6 +802,8 @@ large outgoing port ranges. ])
if test -n "$BAK_LDFLAGS_SET"; then
LDFLAGS="$BAK_LDFLAGS"
fi
AC_SUBST(UNBOUND_EVENT_INSTALL, [unbound-event-install])
AC_SUBST(UNBOUND_EVENT_UNINSTALL, [unbound-event-uninstall])
else
AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events])
fi

View file

@ -1354,6 +1354,13 @@ void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
log_assert(0);
}
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
{
log_assert(0);
}
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);

View file

@ -1,3 +1,9 @@
26 Sep 2013: Wouter
- unbound-event.h is installed if configured --with-libevent. It
contains low-level library calls, that use libevent's event_base
and an ldns_buffer for the wire return packet to perform async
resolution in the client's eventloop.
19 Sep 2013: Wouter
- 1.4.21 tag created.
- trunk has 1.4.22 number inside it.

View file

@ -48,6 +48,7 @@
#include "util/data/packed_rrset.h"
struct libworker;
struct tube;
struct event_base;
/**
* The context structure
@ -111,6 +112,11 @@ struct ub_ctx {
/** random state used to seed new random state structures */
struct ub_randstate* seed_rnd;
/** event base for event oriented interface */
struct event_base* event_base;
/** libworker for event based interface */
struct libworker* event_worker;
/** next query number (to try) to use */
int next_querynum;
/** number of async queries outstanding */

View file

@ -43,6 +43,7 @@
/* include the public api first, it should be able to stand alone */
#include "libunbound/unbound.h"
#include "libunbound/unbound-event.h"
#include "config.h"
#include <ctype.h>
#include "libunbound/context.h"
@ -69,8 +70,8 @@
#include <iphlpapi.h>
#endif /* UB_ON_WINDOWS */
struct ub_ctx*
ub_ctx_create(void)
/** create context functionality, but no pipes */
static struct ub_ctx* ub_ctx_create_nopipe(void)
{
struct ub_ctx* ctx;
unsigned int seed;
@ -105,28 +106,11 @@ ub_ctx_create(void)
return NULL;
}
seed = 0;
if((ctx->qq_pipe = tube_create()) == NULL) {
int e = errno;
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = e;
return NULL;
}
if((ctx->rr_pipe = tube_create()) == NULL) {
int e = errno;
tube_delete(ctx->qq_pipe);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = e;
return NULL;
}
lock_basic_init(&ctx->qqpipe_lock);
lock_basic_init(&ctx->rrpipe_lock);
lock_basic_init(&ctx->cfglock);
ctx->env = (struct module_env*)calloc(1, sizeof(*ctx->env));
if(!ctx->env) {
tube_delete(ctx->qq_pipe);
tube_delete(ctx->rr_pipe);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
@ -134,8 +118,6 @@ ub_ctx_create(void)
}
ctx->env->cfg = config_create_forlib();
if(!ctx->env->cfg) {
tube_delete(ctx->qq_pipe);
tube_delete(ctx->rr_pipe);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
@ -150,6 +132,50 @@ ub_ctx_create(void)
return ctx;
}
struct ub_ctx*
ub_ctx_create(void)
{
struct ub_ctx* ctx = ub_ctx_create_nopipe();
if(!ctx)
return NULL;
if((ctx->qq_pipe = tube_create()) == NULL) {
int e = errno;
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
free(ctx->env);
free(ctx);
errno = e;
return NULL;
}
if((ctx->rr_pipe = tube_create()) == NULL) {
int e = errno;
tube_delete(ctx->qq_pipe);
ub_randfree(ctx->seed_rnd);
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
free(ctx->env);
free(ctx);
errno = e;
return NULL;
}
return ctx;
}
struct ub_ctx*
ub_ctx_create_event(struct event_base* eb)
{
struct ub_ctx* ctx = ub_ctx_create_nopipe();
if(!ctx)
return NULL;
/* no pipes, but we have the locks to make sure everything works */
ctx->created_bg = 0;
ctx->dothread = 1; /* the processing is in the same process,
makes ub_cancel and ub_ctx_delete do the right thing */
ctx->event_base = eb;
return ctx;
}
/** delete q */
static void
delq(rbnode_t* n, void* ATTR_UNUSED(arg))
@ -218,6 +244,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
#endif /* HAVE_PTHREAD */
if(do_stop)
ub_stop_bg(ctx);
libworker_delete_event(ctx->event_worker);
modstack_desetup(&ctx->mods, ctx->env);
a = ctx->alloc_list;
@ -612,6 +639,46 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
return UB_NOERROR;
}
int
ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id)
{
struct ctx_query* q;
int r;
if(async_id)
*async_id = 0;
lock_basic_lock(&ctx->cfglock);
if(!ctx->finalized) {
int r = context_finalize(ctx);
if(r) {
lock_basic_unlock(&ctx->cfglock);
return r;
}
}
if(!ctx->event_worker) {
ctx->event_worker = libworker_create_event(ctx,
ctx->event_base);
if(!ctx->event_worker) {
lock_basic_unlock(&ctx->cfglock);
return UB_INITFAIL;
}
}
lock_basic_unlock(&ctx->cfglock);
/* create new ctx_query and attempt to add to the list */
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
mydata);
if(!q)
return UB_NOMEM;
/* attach to mesh */
if((r=libworker_attach_mesh(ctx, q, async_id)) != 0)
return r;
return UB_NOERROR;
}
int
ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_callback_t callback, int* async_id)

View file

@ -50,6 +50,7 @@
#include "libunbound/libworker.h"
#include "libunbound/context.h"
#include "libunbound/unbound.h"
#include "libunbound/unbound-event.h"
#include "services/outside_network.h"
#include "services/mesh.h"
#include "services/localzone.h"
@ -73,11 +74,10 @@
/** handle new query command for bg worker */
static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
/** delete libworker struct */
/** delete libworker env */
static void
libworker_delete(struct libworker* w)
libworker_delete_env(struct libworker* w)
{
if(!w) return;
if(w->env) {
outside_network_quit_prepare(w->back);
mesh_delete(w->env->mesh);
@ -94,13 +94,30 @@ libworker_delete(struct libworker* w)
SSL_CTX_free(w->sslctx);
#endif
outside_network_delete(w->back);
}
/** delete libworker struct */
static void
libworker_delete(struct libworker* w)
{
if(!w) return;
libworker_delete_env(w);
comm_base_delete(w->base);
free(w);
}
void
libworker_delete_event(struct libworker* w)
{
if(!w) return;
libworker_delete_env(w);
comm_base_delete_no_base(w->base);
free(w);
}
/** setup fresh libworker struct */
static struct libworker*
libworker_setup(struct ub_ctx* ctx, int is_bg)
libworker_setup(struct ub_ctx* ctx, int is_bg, struct event_base* eb)
{
unsigned int seed;
struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
@ -188,7 +205,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
}
seed = 0;
w->base = comm_base_create(0);
if(eb)
w->base = comm_base_create_event(eb);
else w->base = comm_base_create(0);
if(!w->base) {
libworker_delete(w);
return NULL;
@ -233,6 +252,12 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
return w;
}
struct libworker* libworker_create_event(struct ub_ctx* ctx,
struct event_base* eb)
{
return libworker_setup(ctx, 0, eb);
}
/** handle cancel command for bg worker */
static void
handle_cancel(struct libworker* w, uint8_t* buf, uint32_t len)
@ -349,7 +374,7 @@ int libworker_bg(struct ub_ctx* ctx)
lock_basic_lock(&ctx->cfglock);
if(ctx->dothread) {
lock_basic_unlock(&ctx->cfglock);
w = libworker_setup(ctx, 1);
w = libworker_setup(ctx, 1, NULL);
if(!w) return UB_NOMEM;
w->is_bg_thread = 1;
#ifdef ENABLE_LOCK_CHECKS
@ -364,7 +389,7 @@ int libworker_bg(struct ub_ctx* ctx)
#else /* HAVE_FORK */
switch((ctx->bg_pid=fork())) {
case 0:
w = libworker_setup(ctx, 1);
w = libworker_setup(ctx, 1, NULL);
if(!w) fatal_exit("out of memory");
/* close non-used parts of the pipes */
tube_close_write(ctx->qq_pipe);
@ -571,7 +596,7 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
{
struct libworker* w = libworker_setup(ctx, 0);
struct libworker* w = libworker_setup(ctx, 0, NULL);
uint16_t qflags, qid;
struct query_info qinfo;
struct edns_data edns;
@ -611,6 +636,70 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
return UB_NOERROR;
}
void
libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
enum sec_status s, char* why_bogus)
{
struct ctx_query* q = (struct ctx_query*)arg;
ub_event_callback_t cb = (ub_event_callback_t)q->cb;
void* cb_arg = q->cb_arg;
/* delete it now */
struct ub_ctx* ctx = q->w->ctx;
lock_basic_lock(&ctx->cfglock);
(void)rbtree_delete(&ctx->queries, q->node.key);
ctx->num_async--;
context_query_delete(q);
lock_basic_unlock(&ctx->cfglock);
if(!q->cancelled) {
/* call callback */
int sec = 0;
if(s == sec_status_bogus)
sec = 1;
else if(s == sec_status_secure)
sec = 2;
(*cb)(cb_arg, rcode, (void*)buf, sec, why_bogus);
}
}
int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
int* async_id)
{
struct libworker* w = ctx->event_worker;
uint16_t qflags, qid;
struct query_info qinfo;
struct edns_data edns;
if(!w)
return UB_INITFAIL;
if(!setup_qinfo_edns(w, q, &qinfo, &edns))
return UB_SYNTAX;
qid = 0;
qflags = BIT_RD;
q->w = w;
/* see if there is a fixed answer */
ldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
ldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
if(local_zones_answer(ctx->local_zones, &qinfo, &edns,
w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL);
return UB_NOERROR;
}
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_event_done_cb, q)) {
free(qinfo.qname);
return UB_NOMEM;
}
free(qinfo.qname);
if(async_id)
*async_id = q->querynum;
return UB_NOERROR;
}
/** add result to the bg worker result queue */
static void
add_bg_result(struct libworker* w, struct ctx_query* q, ldns_buffer* pkt,

View file

@ -57,6 +57,7 @@ struct comm_point;
struct comm_reply;
struct regional;
struct tube;
struct event_base;
/**
* The library-worker status structure
@ -106,6 +107,31 @@ int libworker_bg(struct ub_ctx* ctx);
*/
int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q);
/**
* create worker for event-based interface.
* @param ctx: context with config.
* @param eb: event base.
* @return new worker or NULL.
*/
struct libworker* libworker_create_event(struct ub_ctx* ctx,
struct event_base* eb);
/**
* Attach context_query to mesh for callback in event-driven setup.
* @param ctx: context
* @param q: context query entry
* @param async_id: store query num if query takes long.
* @return 0 if finished OK, else error.
*/
int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
int* async_id);
/**
* delete worker for event-based interface. does not free the event_base.
* @param w: event-based worker to delete.
*/
void libworker_delete_event(struct libworker* w);
/** cleanup the cache to remove all rrset IDs from it, arg is libworker */
void libworker_alloc_cleanup(void* arg);
@ -155,6 +181,10 @@ void libworker_fg_done_cb(void* arg, int rcode, ldns_buffer* buf,
void libworker_bg_done_cb(void* arg, int rcode, ldns_buffer* buf,
enum sec_status s, char* why_bogus);
/** mesh callback with event results */
void libworker_event_done_cb(void* arg, int rcode, ldns_buffer* buf,
enum sec_status s, char* why_bogus);
/**
* fill result from parsed message, on error fills servfail
* @param res: is clear at start, filled in at end.

View file

@ -1,4 +1,5 @@
ub_ctx_create
ub_ctx_create_event
ub_ctx_delete
ub_ctx_get_option
ub_ctx_set_option
@ -18,6 +19,7 @@ ub_fd
ub_process
ub_resolve
ub_resolve_async
ub_resolve_event
ub_cancel
ub_resolve_free
ub_strerror

125
libunbound/unbound-event.h Normal file
View file

@ -0,0 +1,125 @@
/*
* unbound-event.h - unbound validating resolver public API with events
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* 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 name of the NLNET LABS 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 THE REGENTS OR CONTRIBUTORS 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.
*/
/**
* \file
*
* This file contains the unbound interface for use with libevent.
* You have to use the same libevent that unbound was compiled with,
* otherwise it wouldn't work, the event and event_base structures would
* be different. If unbound is compiled without libevent support then
* this header file is not supposed to be installed on the system.
*
* TODO
* Use ub_ctx_create_event_base() to create an unbound context that uses
* the event base that you have made. Then, use the ub_resolve_event call
* to add DNS resolve queries to the context. Those then run when you
* call event_dispatch() on your event_base, and when they are done you
* get a function callback.
*
* This method does not fork another process or create a thread, the effort
* is done by the unbound state machines that are connected to the event_base.
*/
#ifndef _UB_UNBOUND_EVENT_H
#define _UB_UNBOUND_EVENT_H
#ifdef __cplusplus
extern "C" {
#endif
struct ub_ctx;
struct ub_result;
struct event_base;
struct ldns_buffer;
typedef void (*ub_event_callback_t)(void*, int, struct ldns_buffer*, int, char*);
/**
* Create a resolving and validation context.
* The information from /etc/resolv.conf and /etc/hosts is not utilised by
* default. Use ub_ctx_resolvconf and ub_ctx_hosts to read them.
* @param base: the event base that the caller has created. The unbound
* context uses this event base.
* @return a new context. default initialisation.
* returns NULL on error.
* You must use ub_resolve_event with this context.
* Do not call ub_ctx_async, ub_poll, ub_wait, ub_process, this is all done
* with the event_base. Setup the options you like with the other functions.
*/
struct ub_ctx* ub_ctx_create_event(struct event_base* base);
/**
* Perform resolution and validation of the target name.
* Asynchronous, after a while, the callback will be called with your
* data and the result. Uses the event_base user installed by creating the
* context with ub_ctx_create_event().
* @param ctx: context with event_base in it.
* The context is finalized, and can no longer accept all config changes.
* @param name: domain name in text format (a string).
* @param rrtype: type of RR in host order, 1 is A.
* @param rrclass: class of RR in host order, 1 is IN (for internet).
* @param mydata: this data is your own data (you can pass NULL),
* and is passed on to the callback function.
* @param callback: this is called on completion of the resolution.
* It is called as:
* void callback(void* mydata, int rcode, ldns_buffer* packet, int sec,
* char* why_bogus)
* with mydata: the same as passed here, you may pass NULL,
* with rcode: 0 on no error, nonzero for mostly SERVFAIL situations,
* this is a DNS rcode.
* with packet: ldns_buffer of a DNS wireformat packet with the answer.
* do not inspect if rcode != 0.
* with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure.
* with why_bogus: text string explaining why it is bogus (or NULL).
* These point to buffers inside unbound; do not deallocate the packet or
* error string.
*
* If an error happens during processing, your callback will be called
* with error set to a nonzero value (and result==NULL).
* For localdata (etc/hosts) the callback is called immediately, before
* resolve_event returns, async_id=0 is returned.
* @param async_id: if you pass a non-NULL value, an identifier number is
* returned for the query as it is in progress. It can be used to
* cancel the query.
* @return 0 if OK, else error.
*/
int ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
int rrclass, void* mydata, ub_event_callback_t callback, int* async_id);
#ifdef __cplusplus
}
#endif
#endif /* _UB_UNBOUND_H */

View file

@ -179,6 +179,13 @@ void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
log_assert(0);
}
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
char* ATTR_UNUSED(why_bogus))
{
log_assert(0);
}
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
{
log_assert(0);

View file

@ -388,6 +388,7 @@ int fptr_whitelist_mesh_cb(mesh_cb_func_t fptr)
{
if(fptr == &libworker_fg_done_cb) return 1;
else if(fptr == &libworker_bg_done_cb) return 1;
else if(fptr == &libworker_event_done_cb) return 1;
else if(fptr == &probe_answer_cb) return 1;
return 0;
}

View file

@ -234,6 +234,22 @@ comm_base_create(int sigs)
return b;
}
struct comm_base* comm_base_create_event(struct event_base* base)
{
struct comm_base* b = (struct comm_base*)calloc(1,
sizeof(struct comm_base));
if(!b)
return NULL;
b->eb = (struct internal_base*)calloc(1, sizeof(struct internal_base));
if(!b->eb) {
free(b);
return NULL;
}
b->eb->base = base;
comm_base_now(b);
return b;
}
void
comm_base_delete(struct comm_base* b)
{
@ -257,6 +273,21 @@ comm_base_delete(struct comm_base* b)
free(b);
}
void
comm_base_delete_no_base(struct comm_base* b)
{
if(!b)
return;
if(b->eb->slow_accept_enabled) {
if(event_del(&b->eb->slow_accept) != 0) {
log_err("could not event_del slow_accept");
}
}
b->eb->base = NULL;
free(b->eb);
free(b);
}
void
comm_base_timept(struct comm_base* b, time_t** tt, struct timeval** tv)
{

View file

@ -294,6 +294,21 @@ struct comm_signal {
*/
struct comm_base* comm_base_create(int sigs);
/**
* Create comm base that uses the given event_base (underlying event
* mechanism pointer).
* @param base: underlying lib event base.
* @return: the new comm base. NULL on error.
*/
struct comm_base* comm_base_create_event(struct event_base* base);
/**
* Delete comm base structure but not the underlying lib event base.
* All comm points must have been deleted.
* @param b: the base to delete.
*/
void comm_base_delete_no_base(struct comm_base* b);
/**
* Destroy a comm base.
* All comm points must have been deleted.