diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2012-03-26 18:05:46 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2012-03-26 18:05:46 +0000 |
commit | 93ab453ac3fdb7231f0e8d9d4e94aa74d0333a88 (patch) | |
tree | 63779677d6b5cb474a3029a7d5c52d7fe27a3fc9 /usr.sbin/unbound | |
parent | 35f261e3375c04b694ce2a58876c1cb0a2273003 (diff) |
Import Unbound 1.4.16 to work on in-tree (not yet linked to the build).
These are the direct sources from NLnet Labs upstream, minus these:
compat contrib libunbound/python pythonmod testcode testdata winrc
ok deraadt@ jakob@
Diffstat (limited to 'usr.sbin/unbound')
-rw-r--r-- | usr.sbin/unbound/libunbound/libunbound.c | 273 |
1 files changed, 74 insertions, 199 deletions
diff --git a/usr.sbin/unbound/libunbound/libunbound.c b/usr.sbin/unbound/libunbound/libunbound.c index b3a4c2ba77f..10d00ddc521 100644 --- a/usr.sbin/unbound/libunbound/libunbound.c +++ b/usr.sbin/unbound/libunbound/libunbound.c @@ -21,16 +21,16 @@ * 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 COPYRIGHT - * HOLDER 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. + * "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. */ /** @@ -43,7 +43,6 @@ /* 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" @@ -61,18 +60,14 @@ #include "services/localzone.h" #include "services/cache/infra.h" #include "services/cache/rrset.h" -#include "sldns/sbuffer.h" -#ifdef HAVE_PTHREAD -#include <signal.h> -#endif #if defined(UB_ON_WINDOWS) && defined (HAVE_WINDOWS_H) #include <windows.h> #include <iphlpapi.h> #endif /* UB_ON_WINDOWS */ -/** create context functionality, but no pipes */ -static struct ub_ctx* ub_ctx_create_nopipe(void) +struct ub_ctx* +ub_ctx_create(void) { struct ub_ctx* ctx; unsigned int seed; @@ -107,11 +102,28 @@ static struct ub_ctx* ub_ctx_create_nopipe(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; @@ -119,6 +131,8 @@ static struct ub_ctx* ub_ctx_create_nopipe(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); @@ -133,50 +147,6 @@ static struct ub_ctx* ub_ctx_create_nopipe(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)) @@ -185,9 +155,11 @@ delq(rbnode_t* n, void* ATTR_UNUSED(arg)) context_query_delete(q); } -/** stop the bg thread */ -static void ub_stop_bg(struct ub_ctx* ctx) +void +ub_ctx_delete(struct ub_ctx* ctx) { + struct alloc_cache* a, *na; + if(!ctx) return; /* stop the bg thread */ lock_basic_lock(&ctx->cfglock); if(ctx->created_bg) { @@ -223,29 +195,7 @@ static void ub_stop_bg(struct ub_ctx* ctx) else { lock_basic_unlock(&ctx->cfglock); } -} -void -ub_ctx_delete(struct ub_ctx* ctx) -{ - struct alloc_cache* a, *na; - int do_stop = 1; - if(!ctx) return; - - /* see if bg thread is created and if threads have been killed */ - /* no locks, because those may be held by terminated threads */ - /* for processes the read pipe is closed and we see that on read */ -#ifdef HAVE_PTHREAD - if(ctx->created_bg && ctx->dothread) { - if(pthread_kill(ctx->bg_tid, 0) == ESRCH) { - /* thread has been killed */ - do_stop = 0; - } - } -#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; @@ -279,7 +229,7 @@ ub_ctx_delete(struct ub_ctx* ctx) } int -ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val) +ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val) { lock_basic_lock(&ctx->cfglock); if(ctx->finalized) { @@ -295,7 +245,7 @@ ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val) } int -ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str) +ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str) { int r; lock_basic_lock(&ctx->cfglock); @@ -308,7 +258,7 @@ ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str) } int -ub_ctx_config(struct ub_ctx* ctx, const char* fname) +ub_ctx_config(struct ub_ctx* ctx, char* fname) { lock_basic_lock(&ctx->cfglock); if(ctx->finalized) { @@ -324,7 +274,7 @@ ub_ctx_config(struct ub_ctx* ctx, const char* fname) } int -ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta) +ub_ctx_add_ta(struct ub_ctx* ctx, char* ta) { char* dup = strdup(ta); if(!dup) return UB_NOMEM; @@ -344,7 +294,7 @@ ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta) } int -ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname) +ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname) { char* dup = strdup(fname); if(!dup) return UB_NOMEM; @@ -363,28 +313,8 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname) return UB_NOERROR; } -int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname) -{ - char* dup = strdup(fname); - if(!dup) return UB_NOMEM; - lock_basic_lock(&ctx->cfglock); - if(ctx->finalized) { - lock_basic_unlock(&ctx->cfglock); - free(dup); - return UB_AFTERFINAL; - } - if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list, - dup)) { - lock_basic_unlock(&ctx->cfglock); - free(dup); - return UB_NOMEM; - } - lock_basic_unlock(&ctx->cfglock); - return UB_NOERROR; -} - int -ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname) +ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname) { char* dup = strdup(fname); if(!dup) return UB_NOMEM; @@ -489,21 +419,21 @@ process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len, ub_resolve_free(q->res); } else { /* parse the message, extract rcode, fill result */ - sldns_buffer* buf = sldns_buffer_new(q->msg_len); + ldns_buffer* buf = ldns_buffer_new(q->msg_len); struct regional* region = regional_create(); *res = q->res; (*res)->rcode = LDNS_RCODE_SERVFAIL; if(region && buf) { - sldns_buffer_clear(buf); - sldns_buffer_write(buf, q->msg, q->msg_len); - sldns_buffer_flip(buf); + ldns_buffer_clear(buf); + ldns_buffer_write(buf, q->msg, q->msg_len); + ldns_buffer_flip(buf); libworker_enter_result(*res, buf, region, q->msg_security); } (*res)->answer_packet = q->msg; (*res)->answer_len = (int)q->msg_len; q->msg = NULL; - sldns_buffer_free(buf); + ldns_buffer_free(buf); regional_destroy(region); } q->res = NULL; @@ -617,7 +547,7 @@ ub_wait(struct ub_ctx* ctx) } int -ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, +ub_resolve(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, struct ub_result** result) { struct ctx_query* q; @@ -661,46 +591,7 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, } 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; - } - } - lock_basic_unlock(&ctx->cfglock); - if(!ctx->event_worker) { - ctx->event_worker = libworker_create_event(ctx, - ctx->event_base); - if(!ctx->event_worker) { - return UB_INITFAIL; - } - } - - /* 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, +ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, void* mydata, ub_callback_t callback, int* async_id) { struct ctx_query* q; @@ -841,7 +732,7 @@ ub_strerror(int err) } int -ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) +ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr) { struct sockaddr_storage storage; socklen_t stlen; @@ -913,7 +804,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr) } int -ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) +ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname) { FILE* in; int numserv = 0; @@ -979,7 +870,7 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) parse++; addr = parse; /* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */ - while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':') + while(isxdigit(*parse) || *parse=='.' || *parse==':') parse++; /* terminate after the address, remove newline */ *parse = 0; @@ -999,7 +890,7 @@ ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname) } int -ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) +ub_ctx_hosts(struct ub_ctx* ctx, char* fname) { FILE* in; char buf[1024], ldata[1024]; @@ -1028,6 +919,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) "\\hosts"); retval=ub_ctx_hosts(ctx, buf); } + free(name); return retval; } return UB_READFILE; @@ -1050,9 +942,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) /* format: <addr> spaces <name> spaces <name> ... */ addr = parse; /* skip addr */ - while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':') - parse++; - if(*parse == '\r') + while(isxdigit(*parse) || *parse == '.' || *parse == ':') parse++; if(*parse == '\n' || *parse == 0) continue; @@ -1067,8 +957,7 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname) *parse++ = 0; /* end delimiter for addr ... */ /* go to names and add them */ while(*parse) { - while(*parse == ' ' || *parse == '\t' || *parse=='\n' - || *parse=='\r') + while(*parse == ' ' || *parse == '\t' || *parse=='\n') parse++; if(*parse == 0 || *parse == '#') break; @@ -1127,8 +1016,7 @@ int ub_ctx_print_local_zones(struct ub_ctx* ctx) } /* Add a new zone */ -int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, - const char *zone_type) +int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type) { enum localzone_type t; struct local_zone* z; @@ -1147,28 +1035,28 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, return UB_SYNTAX; } - lock_rw_wrlock(&ctx->local_zones->lock); + lock_quick_lock(&ctx->local_zones->lock); if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* already present in tree */ lock_rw_wrlock(&z->lock); z->type = t; /* update type anyway */ lock_rw_unlock(&z->lock); - lock_rw_unlock(&ctx->local_zones->lock); + lock_quick_unlock(&ctx->local_zones->lock); free(nm); return UB_NOERROR; } if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN, t)) { - lock_rw_unlock(&ctx->local_zones->lock); + lock_quick_unlock(&ctx->local_zones->lock); return UB_NOMEM; } - lock_rw_unlock(&ctx->local_zones->lock); + lock_quick_unlock(&ctx->local_zones->lock); return UB_NOERROR; } /* Remove zone */ -int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name) +int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name) { struct local_zone* z; uint8_t* nm; @@ -1182,29 +1070,37 @@ int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name) return UB_SYNTAX; } - lock_rw_wrlock(&ctx->local_zones->lock); + lock_quick_lock(&ctx->local_zones->lock); if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN))) { /* present in tree */ local_zones_del_zone(ctx->local_zones, z); } - lock_rw_unlock(&ctx->local_zones->lock); + lock_quick_unlock(&ctx->local_zones->lock); free(nm); return UB_NOERROR; } /* Add new RR data */ -int ub_ctx_data_add(struct ub_ctx* ctx, const char *data) +int ub_ctx_data_add(struct ub_ctx* ctx, char *data) { + ldns_buffer* buf; int res = ub_ctx_finalize(ctx); if (res) return res; - res = local_zones_add_RR(ctx->local_zones, data); + lock_basic_lock(&ctx->cfglock); + buf = ldns_buffer_new(ctx->env->cfg->msg_buffer_size); + lock_basic_unlock(&ctx->cfglock); + if(!buf) return UB_NOMEM; + + res = local_zones_add_RR(ctx->local_zones, data, buf); + + ldns_buffer_free(buf); return (!res) ? UB_NOMEM : UB_NOERROR; } /* Remove RR data */ -int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data) +int ub_ctx_data_remove(struct ub_ctx* ctx, char *data) { uint8_t* nm; int nmlabs; @@ -1226,24 +1122,3 @@ const char* ub_version(void) { 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; -} |