mirror of https://github.com/getdnsapi/getdns.git
Initial integration of unbound.
This commit is contained in:
parent
b33952dc65
commit
d608d3b670
|
@ -40,6 +40,8 @@ External dependencies are linked outside the getdns API build tree (we rely on c
|
||||||
|
|
||||||
The project relies on [libldns from NL](https://www.nlnetlabs.nl/projects/ldns/) for parsing and constructing DNS packets. Version 1.6.16 (note that building ldns may require openssl headers and libraries)
|
The project relies on [libldns from NL](https://www.nlnetlabs.nl/projects/ldns/) for parsing and constructing DNS packets. Version 1.6.16 (note that building ldns may require openssl headers and libraries)
|
||||||
|
|
||||||
|
The project also relies on [libunbound from NL](http://www.nlnetlabs.nl/projects/unbound/). Currently it relies on svn revision 2985. The unbound.2985.patch must be applied to the source tree as well. The ./configure must be run with the --with-libevent option (recommended to also use --with-libunbound-only)
|
||||||
|
|
||||||
Although [libevent](http://libevent.org) is used initially to implement the asynchronous model, future work may include a move to other mechanisms (epoll based etc.). Version 2.0.21 stable
|
Although [libevent](http://libevent.org) is used initially to implement the asynchronous model, future work may include a move to other mechanisms (epoll based etc.). Version 2.0.21 stable
|
||||||
|
|
||||||
Doxygen is used to generate documentation, while this is not technically necessary for the build it makes things a lot more pleasant.
|
Doxygen is used to generate documentation, while this is not technically necessary for the build it makes things a lot more pleasant.
|
||||||
|
|
|
@ -26,10 +26,11 @@ AC_PROG_CPP
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
found_all_libs=1
|
found_all_libs=1
|
||||||
AC_MSG_NOTICE([Checking for dependencies ldns and libevent])
|
AC_MSG_NOTICE([Checking for dependencies libevent, ldns, pthread, and unbound])
|
||||||
AC_CHECK_LIB([event_core], [event_base_new], [], [found_all_libs=0])
|
AC_CHECK_LIB([event_core], [event_base_new], [], [found_all_libs=0])
|
||||||
AC_CHECK_LIB([ldns], [ldns_dname_new_frm_str], [], [found_all_libs=0])
|
AC_CHECK_LIB([ldns], [ldns_dname_new_frm_str], [], [found_all_libs=0])
|
||||||
AC_CHECK_LIB([pthread], [pthread_create], [], [found_all_libs=0])
|
AC_CHECK_LIB([pthread], [pthread_create], [], [found_all_libs=0])
|
||||||
|
AC_CHECK_LIB([unbound], [ub_ctx_set_event], [], [found_all_libs=0])
|
||||||
if test $found_all_libs == 0
|
if test $found_all_libs == 0
|
||||||
then
|
then
|
||||||
AC_MSG_ERROR([One more dependencies is missing])
|
AC_MSG_ERROR([One more dependencies is missing])
|
||||||
|
|
|
@ -17,8 +17,7 @@ VPATH = @srcdir@
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-Wall -g -fPIC -I$(srcdir)/ -I /usr/local/include -std=c99
|
CFLAGS=-Wall -g -fPIC -I$(srcdir)/ -I /usr/local/include -std=c99
|
||||||
# LDFLAGS=-L. -L/usr/local/lib
|
LDFLAGS=-levent_core -lldns -lunbound
|
||||||
# LDLIBS=-levent_core -lldns -lgetdns
|
|
||||||
# PROGRAMS=example-simple-answers example-tree example-all-functions example-synchronous
|
# PROGRAMS=example-simple-answers example-tree example-all-functions example-synchronous
|
||||||
|
|
||||||
.SUFFIXES: .c .o .a .lo .h
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
@ -33,8 +32,8 @@ all: libgetdns
|
||||||
cd example && $(MAKE) $@
|
cd example && $(MAKE) $@
|
||||||
|
|
||||||
libgetdns: sync.o context.o list.o dict.o convert.o general.o hostname.o service.o \
|
libgetdns: sync.o context.o list.o dict.o convert.o general.o hostname.o service.o \
|
||||||
validate_dnssec.o nameserver-internal.o request-internal.o util-internal.o getdns_error.o
|
validate_dnssec.o util-internal.o getdns_error.o
|
||||||
$(CC) $(CFLAGS) -shared -o libgetdns.so $?
|
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o libgetdns.so $?
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o $(PROGRAMS) libgetdns.so
|
rm -f *.o $(PROGRAMS) libgetdns.so
|
||||||
|
|
111
src/context.c
111
src/context.c
|
@ -29,9 +29,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
#include <ldns/ldns.h>
|
#include <ldns/ldns.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <unbound.h>
|
||||||
|
#include <unbound-event.h>
|
||||||
|
|
||||||
/* stuff to make it compile pedantically */
|
/* stuff to make it compile pedantically */
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
|
@ -143,17 +148,26 @@ getdns_return_t getdns_context_create(
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
getdns_dict *outbound_reqs = getdns_dict_create();
|
/** default init **/
|
||||||
if (outbound_reqs == NULL) {
|
result = malloc(sizeof(struct getdns_context_t));
|
||||||
|
if (!result) {
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** default init **/
|
result->update_callback = NULL;
|
||||||
result = malloc(sizeof(struct getdns_context_t));
|
result->memory_allocator = malloc;
|
||||||
|
result->memory_deallocator = free;
|
||||||
|
result->memory_reallocator = realloc;
|
||||||
|
|
||||||
|
result->event_base_sync = event_base_new();
|
||||||
|
result->unbound_sync = ub_ctx_create_event(result->event_base_sync);
|
||||||
|
/* create the async one also so options are kept up to date */
|
||||||
|
result->unbound_async = ub_ctx_create_event(result->event_base_sync);
|
||||||
|
result->async_set = 0;
|
||||||
|
|
||||||
result->resolution_type = GETDNS_CONTEXT_RECURSING;
|
result->resolution_type = GETDNS_CONTEXT_RECURSING;
|
||||||
result->namespaces = create_default_namespaces();
|
result->namespaces = create_default_namespaces();
|
||||||
result->dns_transport = GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP;
|
|
||||||
result->limit_outstanding_queries = 0;
|
|
||||||
result->timeout = 5000;
|
result->timeout = 5000;
|
||||||
result->follow_redirects = GETDNS_CONTEXT_FOLLOW_REDIRECTS;
|
result->follow_redirects = GETDNS_CONTEXT_FOLLOW_REDIRECTS;
|
||||||
result->dns_root_servers = create_default_root_servers();
|
result->dns_root_servers = create_default_root_servers();
|
||||||
|
@ -161,22 +175,12 @@ getdns_return_t getdns_context_create(
|
||||||
result->suffix = NULL;
|
result->suffix = NULL;
|
||||||
|
|
||||||
result->dnssec_trust_anchors = NULL;
|
result->dnssec_trust_anchors = NULL;
|
||||||
result->dnssec_allow_skew = 0;
|
|
||||||
result->upstream_list = NULL;
|
result->upstream_list = NULL;
|
||||||
result->edns_maximum_udp_payload_size = 512;
|
|
||||||
result->edns_extended_rcode = 0;
|
result->edns_extended_rcode = 0;
|
||||||
result->edns_version = 0;
|
result->edns_version = 0;
|
||||||
result->edns_do_bit = 0;
|
result->edns_do_bit = 0;
|
||||||
|
|
||||||
result->event_base = NULL;
|
|
||||||
result->resolver_socket = 0;
|
|
||||||
result->outbound_reqs = outbound_reqs;
|
|
||||||
|
|
||||||
result->update_callback = NULL;
|
|
||||||
result->memory_allocator = malloc;
|
|
||||||
result->memory_deallocator = free;
|
|
||||||
result->memory_reallocator = realloc;
|
|
||||||
|
|
||||||
if (set_from_os) {
|
if (set_from_os) {
|
||||||
if (GETDNS_RETURN_GOOD != set_os_defaults(result)) {
|
if (GETDNS_RETURN_GOOD != set_os_defaults(result)) {
|
||||||
getdns_context_destroy(result);
|
getdns_context_destroy(result);
|
||||||
|
@ -186,6 +190,12 @@ getdns_return_t getdns_context_create(
|
||||||
|
|
||||||
*context = result;
|
*context = result;
|
||||||
|
|
||||||
|
/* other opts */
|
||||||
|
getdns_context_set_dnssec_allowed_skew(result, 0);
|
||||||
|
getdns_context_set_edns_maximum_udp_payload_size(result, 512);
|
||||||
|
getdns_context_set_dns_transport(result, GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
|
||||||
|
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_context_create */
|
} /* getdns_context_create */
|
||||||
|
|
||||||
|
@ -211,13 +221,12 @@ getdns_context_destroy(
|
||||||
getdns_list_destroy(context->dnssec_trust_anchors);
|
getdns_list_destroy(context->dnssec_trust_anchors);
|
||||||
getdns_list_destroy(context->upstream_list);
|
getdns_list_destroy(context->upstream_list);
|
||||||
|
|
||||||
getdns_dict_destroy(context->outbound_reqs);
|
/* destroy the ub context */
|
||||||
|
ub_ctx_delete(context->unbound_async);
|
||||||
|
ub_ctx_delete(context->unbound_sync);
|
||||||
|
|
||||||
/* TODO: cancel all events */
|
event_base_free(context->event_base_sync);
|
||||||
|
|
||||||
if (context->resolver_socket != 0) {
|
|
||||||
evutil_closesocket(context->resolver_socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(context);
|
free(context);
|
||||||
return;
|
return;
|
||||||
|
@ -237,6 +246,21 @@ getdns_context_set_context_update_callback(
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_context_set_context_update_callback */
|
} /* getdns_context_set_context_update_callback */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers to set options on the unbound ctx
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void set_ub_string_opt(getdns_context_t ctx, char* opt, char* value) {
|
||||||
|
ub_ctx_set_option(ctx->unbound_sync, opt, value);
|
||||||
|
ub_ctx_set_option(ctx->unbound_async, opt, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_ub_number_opt(getdns_context_t ctx, char* opt, uint16_t value) {
|
||||||
|
char buffer[64];
|
||||||
|
snprintf(buffer, 64, "%hu", value);
|
||||||
|
set_ub_string_opt(ctx, opt, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getdns_context_set_context_update
|
* getdns_context_set_context_update
|
||||||
*
|
*
|
||||||
|
@ -323,15 +347,25 @@ getdns_context_set_dns_transport(
|
||||||
uint16_t value
|
uint16_t value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (value != GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP &&
|
|
||||||
value != GETDNS_CONTEXT_UDP_ONLY &&
|
switch (value) {
|
||||||
value != GETDNS_CONTEXT_TCP_ONLY &&
|
case GETDNS_CONTEXT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||||
value != GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN) {
|
set_ub_string_opt(context, "do-udp", "yes");
|
||||||
|
set_ub_string_opt(context, "do-tcp", "yes");
|
||||||
|
break;
|
||||||
|
case GETDNS_CONTEXT_UDP_ONLY:
|
||||||
|
set_ub_string_opt(context, "do-udp", "yes");
|
||||||
|
set_ub_string_opt(context, "do-tcp", "no");
|
||||||
|
break;
|
||||||
|
case GETDNS_CONTEXT_TCP_ONLY:
|
||||||
|
set_ub_string_opt(context, "do-udp", "no");
|
||||||
|
set_ub_string_opt(context, "do-tcp", "yes");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* TODO GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN */
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->dns_transport = value;
|
|
||||||
|
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_TRANSPORT);
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -347,7 +381,8 @@ getdns_context_set_limit_outstanding_queries(
|
||||||
uint16_t limit
|
uint16_t limit
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
context->limit_outstanding_queries = limit;
|
/* num-queries-per-thread */
|
||||||
|
set_ub_number_opt(context, "num-queries-per-thread", limit);
|
||||||
|
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES);
|
||||||
|
|
||||||
|
@ -427,7 +462,6 @@ getdns_context_set_append_name(
|
||||||
value != GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE &&
|
value != GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE &&
|
||||||
value != GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE &&
|
value != GETDNS_CONTEXT_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE &&
|
||||||
value != GETDNS_CONTEXT_DO_NOT_APPEND_NAMES) {
|
value != GETDNS_CONTEXT_DO_NOT_APPEND_NAMES) {
|
||||||
|
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,8 +532,8 @@ getdns_context_set_dnssec_allowed_skew(
|
||||||
uint16_t value
|
uint16_t value
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
context->dnssec_allow_skew = value;
|
set_ub_number_opt(context, "val-sig-skew-min", value);
|
||||||
|
set_ub_number_opt(context, "val-sig-skew-max", value);
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW);
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
|
@ -549,7 +583,8 @@ getdns_context_set_edns_maximum_udp_payload_size(
|
||||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->edns_maximum_udp_payload_size = value;
|
/* max-udp-size */
|
||||||
|
set_ub_number_opt(context, "max-udp-size", value);
|
||||||
|
|
||||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE);
|
dispatch_updated(context, GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE);
|
||||||
|
|
||||||
|
@ -667,9 +702,13 @@ getdns_extension_set_libevent_base(
|
||||||
struct event_base *this_event_base
|
struct event_base *this_event_base
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* TODO: cancel anything on an existing event base */
|
if (this_event_base) {
|
||||||
context->event_base = this_event_base;
|
ub_ctx_set_event(context->unbound_async, this_event_base);
|
||||||
|
context->async_set = 1;
|
||||||
|
} else {
|
||||||
|
context->async_set = 0;
|
||||||
|
ub_ctx_set_event(context->unbound_async, context->event_base_sync);
|
||||||
|
}
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
} /* getdns_extension_set_libevent_base */
|
} /* getdns_extension_set_libevent_base */
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
|
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
|
|
||||||
|
struct event_base;
|
||||||
|
struct ub_ctx;
|
||||||
|
|
||||||
/** function pointer typedefs */
|
/** function pointer typedefs */
|
||||||
typedef void (*getdns_update_callback)(getdns_context_t context, uint16_t changed_item);
|
typedef void (*getdns_update_callback)(getdns_context_t context, uint16_t changed_item);
|
||||||
typedef void* (*getdns_memory_allocator)(size_t size);
|
typedef void* (*getdns_memory_allocator)(size_t size);
|
||||||
|
@ -43,17 +46,14 @@ struct getdns_context_t {
|
||||||
/* Context values */
|
/* Context values */
|
||||||
uint16_t resolution_type;
|
uint16_t resolution_type;
|
||||||
uint16_t *namespaces;
|
uint16_t *namespaces;
|
||||||
uint16_t dns_transport;
|
|
||||||
uint16_t limit_outstanding_queries;
|
|
||||||
uint16_t timeout;
|
uint16_t timeout;
|
||||||
uint16_t follow_redirects;
|
uint16_t follow_redirects;
|
||||||
struct getdns_list *dns_root_servers;
|
struct getdns_list *dns_root_servers;
|
||||||
uint16_t append_name;
|
uint16_t append_name;
|
||||||
struct getdns_list *suffix;
|
struct getdns_list *suffix;
|
||||||
struct getdns_list *dnssec_trust_anchors;
|
struct getdns_list *dnssec_trust_anchors;
|
||||||
uint16_t dnssec_allow_skew;
|
|
||||||
struct getdns_list *upstream_list;
|
struct getdns_list *upstream_list;
|
||||||
uint16_t edns_maximum_udp_payload_size;
|
|
||||||
uint8_t edns_extended_rcode;
|
uint8_t edns_extended_rcode;
|
||||||
uint8_t edns_version;
|
uint8_t edns_version;
|
||||||
uint8_t edns_do_bit;
|
uint8_t edns_do_bit;
|
||||||
|
@ -63,14 +63,15 @@ struct getdns_context_t {
|
||||||
getdns_memory_deallocator memory_deallocator;
|
getdns_memory_deallocator memory_deallocator;
|
||||||
getdns_memory_reallocator memory_reallocator;
|
getdns_memory_reallocator memory_reallocator;
|
||||||
|
|
||||||
/* Event loop */
|
/* Event loop for sync requests */
|
||||||
struct event_base* event_base;
|
struct event_base* event_base_sync;
|
||||||
|
|
||||||
/* outbound request dict (transaction -> req struct) */
|
/* The underlying unbound contexts that do
|
||||||
getdns_dict *outbound_reqs;
|
the real work */
|
||||||
|
struct ub_ctx *unbound_sync;
|
||||||
|
struct ub_ctx *unbound_async;
|
||||||
|
uint8_t async_set;
|
||||||
|
|
||||||
/* socket */
|
|
||||||
evutil_socket_t resolver_socket;
|
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,7 @@ VPATH = @srcdir@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-Wall -g -fPIC -I$(srcdir)/ -I$(srcdir)/../ -I/usr/local/include -std=c99
|
CFLAGS=-Wall -g -fPIC -I$(srcdir)/ -I$(srcdir)/../ -I/usr/local/include -std=c99
|
||||||
LDFLAGS=-L. -L$(srcdir)/.. -L/usr/local/lib
|
LDFLAGS=-L. -L$(srcdir)/.. -L/usr/local/lib
|
||||||
LDLIBS=-lgetdns -lldns -levent_core
|
LDLIBS=-lgetdns -lldns -levent_core -lunbound
|
||||||
PROGRAMS=example_simple_answers example_tree example_all_functions example_synchronous
|
PROGRAMS=example_simple_answers example_tree example_all_functions example_synchronous
|
||||||
|
|
||||||
.SUFFIXES: .c .o .a .lo .h
|
.SUFFIXES: .c .o .a .lo .h
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
|
|
||||||
|
|
182
src/general.c
182
src/general.c
|
@ -58,94 +58,108 @@
|
||||||
* Version: 0.1b
|
* Version: 0.1b
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "types-internal.h"
|
#include <string.h>
|
||||||
|
#include <unbound.h>
|
||||||
|
#include <unbound-event.h>
|
||||||
|
#include <ldns/ldns.h>
|
||||||
|
#include "context.h"
|
||||||
#include "util-internal.h"
|
#include "util-internal.h"
|
||||||
|
|
||||||
/* stuff to make it compile pedantically */
|
/* stuff to make it compile pedantically */
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
|
|
||||||
/* libevent callback for a network request */
|
typedef struct getdns_ub_req {
|
||||||
static void dns_req_callback(int fd, short events, void *arg) {
|
struct ub_ctx *unbound;
|
||||||
getdns_dns_req *request = (getdns_dns_req*) arg;
|
getdns_context_t context;
|
||||||
uint8_t data[1500];
|
char* name;
|
||||||
if (events & EV_READ) {
|
void* userarg;
|
||||||
while (1) {
|
getdns_callback_t callback;
|
||||||
ssize_t r = recv(fd, data, sizeof(data), MSG_DONTWAIT);
|
getdns_transaction_t transaction_id;
|
||||||
if (r < 0) {
|
} getdns_ub_req;
|
||||||
if (errno == EAGAIN) return;
|
|
||||||
/* otherwise failed */
|
static void getdns_ub_req_free(getdns_ub_req* req) {
|
||||||
request->user_callback(request->context,
|
free(req->name);
|
||||||
GETDNS_CALLBACK_ERROR,
|
free(req);
|
||||||
NULL, request->user_pointer,
|
|
||||||
request->trans_id);
|
|
||||||
}
|
}
|
||||||
/* parse a packet */
|
|
||||||
|
void ub_resolve_callback(void* arg, int err, ldns_buffer* result, int sec, char* bogus) {
|
||||||
|
getdns_ub_req* req = (getdns_ub_req*) arg;
|
||||||
ldns_pkt* pkt = NULL;
|
ldns_pkt* pkt = NULL;
|
||||||
ldns_wire2pkt(&pkt, data, r);
|
if (err) {
|
||||||
if (pkt == NULL) {
|
req->callback(req->context,
|
||||||
/* otherwise failed */
|
|
||||||
request->user_callback(request->context,
|
|
||||||
GETDNS_CALLBACK_ERROR,
|
GETDNS_CALLBACK_ERROR,
|
||||||
NULL, request->user_pointer,
|
NULL,
|
||||||
request->trans_id);
|
req->userarg,
|
||||||
|
req->transaction_id);
|
||||||
|
} else {
|
||||||
|
/* parse */
|
||||||
|
ldns_status r = ldns_buffer2pkt_wire(&pkt, result);
|
||||||
|
if (r != LDNS_STATUS_OK) {
|
||||||
|
req->callback(req->context,
|
||||||
|
GETDNS_CALLBACK_ERROR,
|
||||||
|
NULL,
|
||||||
|
req->userarg,
|
||||||
|
req->transaction_id);
|
||||||
} else {
|
} else {
|
||||||
/* success */
|
|
||||||
getdns_dict* response = create_getdns_response(pkt);
|
getdns_dict* response = create_getdns_response(pkt);
|
||||||
ldns_pkt_free(pkt);
|
ldns_pkt_free(pkt);
|
||||||
request->user_callback(request->context, GETDNS_CALLBACK_COMPLETE,
|
req->callback(req->context,
|
||||||
response, request->user_pointer,
|
GETDNS_CALLBACK_COMPLETE,
|
||||||
request->trans_id);
|
response,
|
||||||
|
req->userarg,
|
||||||
|
req->transaction_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (events & EV_TIMEOUT) {
|
/* cleanup */
|
||||||
request->user_callback(request->context, GETDNS_CALLBACK_TIMEOUT,
|
getdns_ub_req_free(req);
|
||||||
NULL, request->user_pointer, request->trans_id);
|
|
||||||
}
|
|
||||||
/* clean up ns since right now it's 1:1 with the request */
|
|
||||||
nameserver_free(request->current_req->ns);
|
|
||||||
/* cleanup the request */
|
|
||||||
dns_req_free(request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* submit a new request to the event loop */
|
getdns_return_t
|
||||||
static getdns_return_t submit_new_dns_req(getdns_dns_req *request) {
|
getdns_general_ub(
|
||||||
getdns_dict *ip_dict = NULL;
|
struct ub_ctx* unbound,
|
||||||
getdns_context_t context = request->context;
|
getdns_context_t context,
|
||||||
uint8_t* data = NULL;
|
const char *name,
|
||||||
size_t data_len = 0;
|
uint16_t request_type,
|
||||||
struct timeval timeout = { 5, 0 };
|
struct getdns_dict *extensions,
|
||||||
|
void *userarg,
|
||||||
|
getdns_transaction_t *transaction_id,
|
||||||
|
getdns_callback_t callbackfn
|
||||||
|
) {
|
||||||
|
|
||||||
/* get first upstream server */
|
int r;
|
||||||
getdns_list_get_dict(context->upstream_list, 0, &ip_dict);
|
int async_id = 0;
|
||||||
if (!ip_dict) {
|
|
||||||
|
/* request state */
|
||||||
|
getdns_ub_req* req = (getdns_ub_req*) malloc(sizeof(getdns_ub_req));
|
||||||
|
req->unbound = unbound;
|
||||||
|
req->context = context;
|
||||||
|
req->name = strdup(name);
|
||||||
|
req->userarg = userarg;
|
||||||
|
req->callback = callbackfn;
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
setup root or stub
|
||||||
|
handle immediate callback
|
||||||
|
A + AAAA
|
||||||
|
*/
|
||||||
|
|
||||||
|
r = ub_resolve_event(unbound, req->name, request_type,
|
||||||
|
LDNS_RR_CLASS_IN, req, ub_resolve_callback,
|
||||||
|
&async_id);
|
||||||
|
|
||||||
|
if (transaction_id) {
|
||||||
|
*transaction_id = async_id;
|
||||||
|
}
|
||||||
|
req->transaction_id = async_id;
|
||||||
|
|
||||||
|
|
||||||
|
if (r != 0) {
|
||||||
|
getdns_ub_req_free(req);
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the nameserver */
|
|
||||||
getdns_nameserver *ns = nameserver_new_from_ip_dict(context, ip_dict);
|
|
||||||
if (!ns) {
|
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
request->current_req->ns = ns;
|
|
||||||
|
|
||||||
/* schedule on the loop */
|
|
||||||
ns->event = event_new(context->event_base, request->current_req->ns->socket,
|
|
||||||
EV_READ | EV_TIMEOUT,
|
|
||||||
dns_req_callback, request);
|
|
||||||
|
|
||||||
event_add(ns->event, &timeout);
|
|
||||||
|
|
||||||
/* send data */
|
|
||||||
ldns_pkt *pkt = request->current_req->pkt;
|
|
||||||
ldns_pkt2wire(&data, pkt, &data_len);
|
|
||||||
send(ns->socket, data, data_len, MSG_DONTWAIT);
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* getdns_general
|
* getdns_general
|
||||||
*/
|
*/
|
||||||
|
@ -160,36 +174,24 @@ getdns_general(
|
||||||
getdns_callback_t callback
|
getdns_callback_t callback
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* Default to zero */
|
|
||||||
if (transaction_id != NULL) {
|
if (!context || context->async_set == 0 ||
|
||||||
*transaction_id = 0;
|
callback == NULL) {
|
||||||
}
|
|
||||||
if (!context || context->event_base == NULL ||
|
|
||||||
callback == NULL ||
|
|
||||||
context->resolution_type != GETDNS_CONTEXT_STUB) {
|
|
||||||
/* Can't do async without an event loop
|
/* Can't do async without an event loop
|
||||||
* or callback
|
* or callback
|
||||||
*
|
|
||||||
* Only supports stub right now.
|
|
||||||
*/
|
*/
|
||||||
return GETDNS_RETURN_BAD_CONTEXT;
|
return GETDNS_RETURN_BAD_CONTEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return getdns_general_ub(context->unbound_async,
|
||||||
|
context,
|
||||||
|
name,
|
||||||
|
request_type,
|
||||||
|
extensions,
|
||||||
|
userarg,
|
||||||
|
transaction_id,
|
||||||
|
callback);
|
||||||
|
|
||||||
/* create a req */
|
|
||||||
getdns_dns_req *dns_req = dns_req_new(context, name, request_type,
|
|
||||||
extensions, transaction_id);
|
|
||||||
if (dns_req == NULL) {
|
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
dns_req->user_callback = callback;
|
|
||||||
dns_req->user_pointer = userarg;
|
|
||||||
|
|
||||||
/* submit it */
|
|
||||||
submit_new_dns_req(dns_req);
|
|
||||||
|
|
||||||
return GETDNS_RETURN_GOOD;
|
|
||||||
} /* getdns_general */
|
} /* getdns_general */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* /brief getdns contect management functions
|
||||||
|
*
|
||||||
|
* This is the meat of the API
|
||||||
|
* Originally taken from the getdns API description pseudo implementation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* The MIT License (MIT)
|
||||||
|
* Copyright (c) 2013 Verisign, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef _GETDNS_GENERAL_H_
|
||||||
|
#define _GETDNS_GENERAL_H_
|
||||||
|
|
||||||
|
#include <getdns/getdns.h>
|
||||||
|
|
||||||
|
struct ub_ctx;
|
||||||
|
|
||||||
|
getdns_return_t
|
||||||
|
getdns_general_ub(
|
||||||
|
struct ub_ctx* unbound,
|
||||||
|
getdns_context_t context,
|
||||||
|
const char *name,
|
||||||
|
uint16_t request_type,
|
||||||
|
struct getdns_dict *extensions,
|
||||||
|
void *userarg,
|
||||||
|
getdns_transaction_t *transaction_id,
|
||||||
|
getdns_callback_t callbackfn
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
|
@ -34,7 +34,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <event2/event.h>
|
|
||||||
|
struct event_base;
|
||||||
|
|
||||||
#define GETDNS_COMPILATION_COMMENT The API implementation should fill in something here, such as a compilation version string and date, and change it each time the API is compiled.
|
#define GETDNS_COMPILATION_COMMENT The API implementation should fill in something here, such as a compilation version string and date, and change it each time the API is compiled.
|
||||||
|
|
||||||
|
|
19
src/sync.c
19
src/sync.c
|
@ -29,7 +29,10 @@
|
||||||
|
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "types-internal.h"
|
#include <event2/event.h>
|
||||||
|
#include <unbound-event.h>
|
||||||
|
#include "context.h"
|
||||||
|
#include "general.h"
|
||||||
|
|
||||||
/* stuff to make it compile pedantically */
|
/* stuff to make it compile pedantically */
|
||||||
#define UNUSED_PARAM(x) ((void)(x))
|
#define UNUSED_PARAM(x) ((void)(x))
|
||||||
|
@ -55,10 +58,9 @@ static void sync_callback_func(getdns_context_t context,
|
||||||
|
|
||||||
static void * request_thread_start(void *arg) {
|
static void * request_thread_start(void *arg) {
|
||||||
struct sync_request_data *req_data = arg;
|
struct sync_request_data *req_data = arg;
|
||||||
struct event_base *event_base = event_base_new();
|
|
||||||
|
|
||||||
getdns_extension_set_libevent_base(req_data->context, event_base);
|
req_data->response_status = getdns_general_ub(req_data->context->unbound_sync,
|
||||||
req_data->response_status = getdns_general(req_data->context,
|
req_data->context,
|
||||||
req_data->name,
|
req_data->name,
|
||||||
req_data->request_type,
|
req_data->request_type,
|
||||||
req_data->extensions,
|
req_data->extensions,
|
||||||
|
@ -66,7 +68,7 @@ static void * request_thread_start(void *arg) {
|
||||||
NULL,
|
NULL,
|
||||||
sync_callback_func);
|
sync_callback_func);
|
||||||
|
|
||||||
event_base_dispatch(event_base);
|
event_base_dispatch(req_data->context->event_base_sync);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +84,8 @@ getdns_general_sync(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* we will cheat and spawn a thread */
|
/* we will cheat and spawn a thread */
|
||||||
/* get the old event base */
|
/* set up for sync resolution */
|
||||||
struct event_base* orig_base = context->event_base;
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
sync_request_data req_data = {
|
sync_request_data req_data = {
|
||||||
|
@ -111,9 +113,6 @@ getdns_general_sync(
|
||||||
return GETDNS_RETURN_GENERIC_ERROR;
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the old event loop */
|
|
||||||
getdns_extension_set_libevent_base(context, orig_base);
|
|
||||||
|
|
||||||
return req_data.response_status;
|
return req_data.response_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "testmessages.h"
|
#include "testmessages.h"
|
||||||
#include <getdns/getdns.h>
|
#include <getdns/getdns.h>
|
||||||
|
#include <event2/event.h>
|
||||||
|
|
||||||
/* Set up the callback function, which will also do the processing of the results */
|
/* Set up the callback function, which will also do the processing of the results */
|
||||||
void this_callbackfn(struct getdns_context_t *this_context,
|
void this_callbackfn(struct getdns_context_t *this_context,
|
||||||
|
|
|
@ -28,7 +28,13 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
#include "types-internal.h"
|
#include "types-internal.h"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ldns/ldns.h>
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
|
||||||
/* convert an ip address dict to a sock storage */
|
/* convert an ip address dict to a sock storage */
|
||||||
getdns_return_t dict_to_sockaddr(getdns_dict* ns, struct sockaddr_storage* output);
|
getdns_return_t dict_to_sockaddr(getdns_dict* ns, struct sockaddr_storage* output);
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
Index: Makefile.in
|
||||||
|
===================================================================
|
||||||
|
--- Makefile.in (revision 2985)
|
||||||
|
+++ Makefile.in (working copy)
|
||||||
|
@@ -280,7 +280,7 @@
|
||||||
|
longtest: tests
|
||||||
|
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||||
|
|
||||||
|
-lib: libunbound.la unbound.h
|
||||||
|
+lib: libunbound.la unbound.h unbound-event.h
|
||||||
|
|
||||||
|
libunbound.la: $(LIBUNBOUND_OBJ_LINK)
|
||||||
|
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) -lssl $(LIBS)
|
||||||
|
@@ -348,6 +348,9 @@
|
||||||
|
unbound.h: $(srcdir)/libunbound/unbound.h
|
||||||
|
sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < $(srcdir)/libunbound/unbound.h > $@
|
||||||
|
|
||||||
|
+unbound-event.h: $(srcdir)/libunbound/unbound-event.h
|
||||||
|
+ sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < $(srcdir)/libunbound/unbound-event.h > $@
|
||||||
|
+
|
||||||
|
unbound-control-setup: $(srcdir)/smallapp/unbound-control-setup.sh
|
||||||
|
sed -e 's:^DESTDIR=.*$$:DESTDIR=$(UNBOUND_RUN_DIR):' < $(srcdir)/smallapp/unbound-control-setup.sh > $@
|
||||||
|
-chmod +x $@
|
||||||
|
@@ -496,6 +499,7 @@
|
||||||
|
$(INSTALL) -c -m 755 unbound-control-setup $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||||
|
if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 doc/example.conf $(DESTDIR)$(configfile); fi
|
||||||
|
$(LIBTOOL) --mode=install cp unbound.h $(DESTDIR)$(includedir)/unbound.h
|
||||||
|
+ $(LIBTOOL) --mode=install cp unbound-event.h $(DESTDIR)$(includedir)/unbound-event.h
|
||||||
|
$(LIBTOOL) --mode=install cp libunbound.la $(DESTDIR)$(libdir)
|
||||||
|
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||||
|
|
||||||
|
Index: libunbound/ubsyms.def
|
||||||
|
===================================================================
|
||||||
|
--- libunbound/ubsyms.def (revision 2985)
|
||||||
|
+++ libunbound/ubsyms.def (working copy)
|
||||||
|
@@ -29,3 +29,4 @@
|
||||||
|
ub_ctx_data_add
|
||||||
|
ub_ctx_data_remove
|
||||||
|
ub_version
|
||||||
|
+ub_ctx_set_event
|
||||||
|
Index: libunbound/unbound-event.h
|
||||||
|
===================================================================
|
||||||
|
--- libunbound/unbound-event.h (revision 2985)
|
||||||
|
+++ libunbound/unbound-event.h (working copy)
|
||||||
|
@@ -63,9 +63,9 @@
|
||||||
|
struct ub_ctx;
|
||||||
|
struct ub_result;
|
||||||
|
struct event_base;
|
||||||
|
-struct ldns_buffer;
|
||||||
|
+struct ldns_struct_buffer;
|
||||||
|
|
||||||
|
-typedef void (*ub_event_callback_t)(void*, int, struct ldns_buffer*, int, char*);
|
||||||
|
+typedef void (*ub_event_callback_t)(void*, int, struct ldns_struct_buffer*, int, char*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a resolving and validation context.
|
||||||
|
@@ -82,6 +82,15 @@
|
||||||
|
struct ub_ctx* ub_ctx_create_event(struct event_base* base);
|
||||||
|
|
||||||
|
/**
|
||||||
|
+ * Set a new event_base on a context created with ub_ctx_create_event.
|
||||||
|
+ * Any outbound queries will be canceled.
|
||||||
|
+ * @param ctx the ub_ctx to update. Must have been created with ub_ctx_create_event
|
||||||
|
+ * @param base the new event_base to attach to the ctx
|
||||||
|
+ * @return 0 if OK, else error
|
||||||
|
+ */
|
||||||
|
+int ub_ctx_set_event(struct ub_ctx* ctx, 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
|
||||||
|
Index: libunbound/libunbound.c
|
||||||
|
===================================================================
|
||||||
|
--- libunbound/libunbound.c (revision 2985)
|
||||||
|
+++ libunbound/libunbound.c (working copy)
|
||||||
|
@@ -656,15 +656,14 @@
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ lock_basic_unlock(&ctx->cfglock);
|
||||||
|
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,
|
||||||
|
@@ -1212,3 +1211,24 @@
|
||||||
|
{
|
||||||
|
return PACKAGE_VERSION;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) {
|
||||||
|
+ if (!ctx || !ctx->event_base || !base) {
|
||||||
|
+ return UB_INITFAIL;
|
||||||
|
+ }
|
||||||
|
+ if (ctx->event_base == base) {
|
||||||
|
+ /* already set */
|
||||||
|
+ return UB_NOERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ lock_basic_lock(&ctx->cfglock);
|
||||||
|
+ /* destroy the current worker - safe to pass in NULL */
|
||||||
|
+ libworker_delete_event(ctx->event_worker);
|
||||||
|
+ ctx->event_worker = NULL;
|
||||||
|
+ ctx->event_base = base;
|
||||||
|
+ ctx->created_bg = 0;
|
||||||
|
+ ctx->dothread = 1;
|
||||||
|
+ lock_basic_unlock(&ctx->cfglock);
|
||||||
|
+ return UB_NOERROR;
|
||||||
|
+}
|
Loading…
Reference in New Issue