mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-02-01 19:29:27 -05:00
- 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:
parent
cc7dbe6d9a
commit
253d425ca8
15 changed files with 434 additions and 31 deletions
13
Makefile.in
13
Makefile.in
|
|
@ -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
6
configure
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
125
libunbound/unbound-event.h
Normal 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 */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue