mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
libunbound work.
git-svn-id: file:///svn/unbound/trunk@802 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
8892d4b63c
commit
43a2640a9c
4 changed files with 452 additions and 67 deletions
|
|
@ -2,6 +2,8 @@
|
||||||
- minor Makefile fixup.
|
- minor Makefile fixup.
|
||||||
- moved module-stack code out of daemon/daemon into services/modstack,
|
- moved module-stack code out of daemon/daemon into services/modstack,
|
||||||
preparing for code-reuse.
|
preparing for code-reuse.
|
||||||
|
- move context into own header file.
|
||||||
|
- context query structure.
|
||||||
|
|
||||||
3 December 2007: Wouter
|
3 December 2007: Wouter
|
||||||
- changed checkconf/ to smallapp/ to make room for more support tools.
|
- changed checkconf/ to smallapp/ to make room for more support tools.
|
||||||
|
|
|
||||||
146
libunbound/context.c
Normal file
146
libunbound/context.c
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*
|
||||||
|
* libunbound/context.c - validating context for unbound internal use
|
||||||
|
*
|
||||||
|
* 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 validator context structure.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "libunbound/context.h"
|
||||||
|
#include "util/module.h"
|
||||||
|
#include "util/config_file.h"
|
||||||
|
#include "services/modstack.h"
|
||||||
|
#include "services/localzone.h"
|
||||||
|
#include "services/cache/rrset.h"
|
||||||
|
#include "services/cache/infra.h"
|
||||||
|
#include "util/data/msgreply.h"
|
||||||
|
#include "util/storage/slabhash.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
context_finalize(struct ub_val_ctx* ctx)
|
||||||
|
{
|
||||||
|
struct config_file* cfg = ctx->env->cfg;
|
||||||
|
verbosity = cfg->verbosity;
|
||||||
|
log_init(cfg->logfile, cfg->use_syslog, NULL);
|
||||||
|
config_apply(cfg);
|
||||||
|
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||||
|
return UB_INITFAIL;
|
||||||
|
ctx->local_zones = local_zones_create();
|
||||||
|
if(!ctx->local_zones)
|
||||||
|
return UB_NOMEM;
|
||||||
|
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
|
||||||
|
return UB_INITFAIL;
|
||||||
|
if(!ctx->env->msg_cache ||
|
||||||
|
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
|
||||||
|
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {
|
||||||
|
slabhash_delete(ctx->env->msg_cache);
|
||||||
|
ctx->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||||
|
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||||
|
msgreply_sizefunc, query_info_compare,
|
||||||
|
query_entry_delete, reply_info_delete, NULL);
|
||||||
|
if(!ctx->env->msg_cache)
|
||||||
|
return UB_NOMEM;
|
||||||
|
}
|
||||||
|
ctx->env->rrset_cache = rrset_cache_adjust(ctx->env->rrset_cache,
|
||||||
|
ctx->env->cfg, ctx->env->alloc);
|
||||||
|
if(!ctx->env->rrset_cache)
|
||||||
|
return UB_NOMEM;
|
||||||
|
ctx->env->infra_cache = infra_adjust(ctx->env->infra_cache, cfg);
|
||||||
|
if(!ctx->env->infra_cache)
|
||||||
|
return UB_NOMEM;
|
||||||
|
return UB_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int context_query_cmp(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
if( *(int*)a < *(int*)b )
|
||||||
|
return -1;
|
||||||
|
if( *(int*)a > *(int*)b )
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** How many times to try to find an unused query-id-number for async */
|
||||||
|
#define NUM_ID_TRIES 100000
|
||||||
|
/** find next useful id number of 0 on error */
|
||||||
|
static int
|
||||||
|
find_id(struct ub_val_ctx* ctx, int* id)
|
||||||
|
{
|
||||||
|
size_t tries = 0;
|
||||||
|
while(rbtree_search(&ctx->queries, &ctx->next_querynum)) {
|
||||||
|
ctx->next_querynum++; /* numerical wraparound is fine */
|
||||||
|
if(tries++ > NUM_ID_TRIES)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*id = ctx->next_querynum;
|
||||||
|
ctx->next_querynum++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ctx_query*
|
||||||
|
context_new(struct ub_val_ctx* ctx, char* name, int rrtype, int rrclass,
|
||||||
|
ub_val_callback_t cb, void* cbarg)
|
||||||
|
{
|
||||||
|
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||||
|
if(!q) return NULL;
|
||||||
|
if(!find_id(ctx, &q->querynum)) {
|
||||||
|
free(q);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
q->node.key = &q->querynum;
|
||||||
|
q->async = (cb != NULL);
|
||||||
|
q->cb = cb;
|
||||||
|
q->cb_arg = cbarg;
|
||||||
|
q->res = (struct ub_val_result*)calloc(1, sizeof(*q->res));
|
||||||
|
if(!q->res) {
|
||||||
|
free(q);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
q->res->qname = strdup(name);
|
||||||
|
if(!q->res->qname) {
|
||||||
|
free(q->res);
|
||||||
|
free(q);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
q->res->qtype = rrtype;
|
||||||
|
q->res->qclass = rrclass;
|
||||||
|
|
||||||
|
/* add to query list */
|
||||||
|
if(q->async)
|
||||||
|
ctx->num_async ++;
|
||||||
|
(void)rbtree_insert(&ctx->queries, &q->node);
|
||||||
|
return q;
|
||||||
|
}
|
||||||
177
libunbound/context.h
Normal file
177
libunbound/context.h
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* libunbound/context.h - validating context for unbound internal use
|
||||||
|
*
|
||||||
|
* 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 validator context structure.
|
||||||
|
*/
|
||||||
|
#ifndef LIBUNBOUND_CONTEXT_H
|
||||||
|
#define LIBUNBOUND_CONTEXT_H
|
||||||
|
#include "util/locks.h"
|
||||||
|
#include "util/alloc.h"
|
||||||
|
#include "util/rbtree.h"
|
||||||
|
#include "services/modstack.h"
|
||||||
|
#include "libunbound/unbound.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context structure
|
||||||
|
*
|
||||||
|
* Contains two pipes for async service
|
||||||
|
* qq : write queries to the async service pid/tid.
|
||||||
|
* rr : read results from the async service pid/tid.
|
||||||
|
*/
|
||||||
|
struct ub_val_ctx {
|
||||||
|
/* --- pipes --- */
|
||||||
|
/** mutex on query write pipe */
|
||||||
|
lock_basic_t qqpipe_lock;
|
||||||
|
/** the query write pipe, [0] read from, [1] write on */
|
||||||
|
int qqpipe[2];
|
||||||
|
/** mutex on result read pipe */
|
||||||
|
lock_basic_t rrpipe_lock;
|
||||||
|
/** the result read pipe, [0] read from, [1] write on */
|
||||||
|
int rrpipe[2];
|
||||||
|
|
||||||
|
/* --- shared data --- */
|
||||||
|
/** mutex for access to env.cfg, finalized and dothread */
|
||||||
|
lock_basic_t cfglock;
|
||||||
|
/**
|
||||||
|
* The context has been finalized
|
||||||
|
* This is after config when the first resolve is done.
|
||||||
|
* The modules are inited (module-init()) and shared caches created.
|
||||||
|
*/
|
||||||
|
int finalized;
|
||||||
|
|
||||||
|
/** do threading (instead of forking) for async resolution */
|
||||||
|
int dothread;
|
||||||
|
/** next thread number for new threads */
|
||||||
|
int thr_next_num;
|
||||||
|
/**
|
||||||
|
* List of alloc-cache-id points per threadnum for notinuse threads.
|
||||||
|
* Simply the entire struct alloc_cache with the 'super' member used
|
||||||
|
* to link a simply linked list. Reset super member to the superalloc
|
||||||
|
* before use.
|
||||||
|
*/
|
||||||
|
struct alloc_cache* alloc_list;
|
||||||
|
|
||||||
|
/** shared caches, and so on */
|
||||||
|
struct alloc_cache superalloc;
|
||||||
|
/** module env master value */
|
||||||
|
struct module_env* env;
|
||||||
|
/** module stack */
|
||||||
|
struct module_stack mods;
|
||||||
|
/** local authority zones */
|
||||||
|
struct local_zones* local_zones;
|
||||||
|
|
||||||
|
/** next query number (to try) to use */
|
||||||
|
int next_querynum;
|
||||||
|
/** number of async queries outstanding */
|
||||||
|
size_t num_async;
|
||||||
|
/**
|
||||||
|
* Tree of outstanding queries. Indexed by querynum
|
||||||
|
* Used when results come in for async to lookup.
|
||||||
|
* Used when cancel is done for lookup (and delete).
|
||||||
|
* Used to see if querynum is free for use.
|
||||||
|
* Content of type ctx_query.
|
||||||
|
*/
|
||||||
|
rbtree_t queries;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The queries outstanding for the libunbound resolver.
|
||||||
|
* These are outstanding for async resolution.
|
||||||
|
* But also, outstanding for sync resolution by one of the threads that
|
||||||
|
* has joined the threadpool.
|
||||||
|
*/
|
||||||
|
struct ctx_query {
|
||||||
|
/** node in rbtree, must be first entry, key is ptr to the querynum */
|
||||||
|
struct rbnode_t node;
|
||||||
|
/** query id number, key for node */
|
||||||
|
int querynum;
|
||||||
|
/** was this an async query? */
|
||||||
|
int async;
|
||||||
|
|
||||||
|
/** for async query, the callback function */
|
||||||
|
ub_val_callback_t cb;
|
||||||
|
/** for async query, the callback user arg */
|
||||||
|
void* cb_arg;
|
||||||
|
|
||||||
|
/** result structure, also contains original query, type, class.
|
||||||
|
* malloced ptr ready to hand to the client. */
|
||||||
|
struct ub_val_result* res;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error constants
|
||||||
|
*/
|
||||||
|
enum ub_ctx_err {
|
||||||
|
/** no error */
|
||||||
|
UB_NOERROR = 0,
|
||||||
|
/** alloc failure */
|
||||||
|
UB_NOMEM,
|
||||||
|
/** socket operation */
|
||||||
|
UB_SOCKET,
|
||||||
|
/** syntax error */
|
||||||
|
UB_SYNTAX,
|
||||||
|
/** DNS service failed */
|
||||||
|
UB_SERVFAIL,
|
||||||
|
/** initialization failed (bad settings) */
|
||||||
|
UB_INITFAIL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finalize a context.
|
||||||
|
* @param ctx: context to finalize. creates shared data.
|
||||||
|
* @return 0 if OK, or errcode.
|
||||||
|
*/
|
||||||
|
int context_finalize(struct ub_val_ctx* ctx);
|
||||||
|
|
||||||
|
/** compare two ctx_query elements */
|
||||||
|
int context_query_cmp(const void* a, const void* b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new query in context, add to querynum list.
|
||||||
|
* @param ctx: context
|
||||||
|
* @param name: query name
|
||||||
|
* @param rrtype: type
|
||||||
|
* @param rrclass: class
|
||||||
|
* @param cb: callback for async, or NULL for sync.
|
||||||
|
* @param cbarg: user arg for async queries.
|
||||||
|
* @return new ctx_query or NULL for malloc failure.
|
||||||
|
*/
|
||||||
|
struct ctx_query* context_new(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||||
|
int rrclass, ub_val_callback_t cb, void* cbarg);
|
||||||
|
|
||||||
|
#endif /* LIBUNBOUND_CONTEXT_H */
|
||||||
|
|
@ -44,67 +44,16 @@
|
||||||
/* include the public api first, it should be able to stand alone */
|
/* include the public api first, it should be able to stand alone */
|
||||||
#include "libunbound/unbound.h"
|
#include "libunbound/unbound.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "libunbound/context.h"
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/alloc.h"
|
#include "util/alloc.h"
|
||||||
|
#include "util/module.h"
|
||||||
/**
|
#include "util/log.h"
|
||||||
* The context structure
|
#include "services/modstack.h"
|
||||||
*
|
#include "services/localzone.h"
|
||||||
* Contains two pipes for async service
|
#include "services/cache/infra.h"
|
||||||
* qq : write queries to the async service pid/tid.
|
#include "services/cache/rrset.h"
|
||||||
* rr : read results from the async service pid/tid.
|
|
||||||
*/
|
|
||||||
struct ub_val_ctx {
|
|
||||||
/** mutex on query write pipe */
|
|
||||||
lock_basic_t qqpipe_lock;
|
|
||||||
/** the query write pipe, [0] read from, [1] write on */
|
|
||||||
int qqpipe[2];
|
|
||||||
/** mutex on result read pipe */
|
|
||||||
lock_basic_t rrpipe_lock;
|
|
||||||
/** the result read pipe, [0] read from, [1] write on */
|
|
||||||
int rrpipe[2];
|
|
||||||
|
|
||||||
/** configuration options */
|
|
||||||
struct config_file* cfg;
|
|
||||||
/** do threading (instead of forking) for async resolution */
|
|
||||||
int dothread;
|
|
||||||
|
|
||||||
/** shared data */
|
|
||||||
/* list of alloc-cache-id points and nextthreadnum */
|
|
||||||
/*struct shareddata* shared;*/
|
|
||||||
/** outstanding querylist and next querynum (to try) */
|
|
||||||
|
|
||||||
/** shared caches, and so on */
|
|
||||||
struct alloc_cache superalloc;
|
|
||||||
/** module env master value */
|
|
||||||
struct module_env* env;
|
|
||||||
/** number of modules active, ids from 0 to num-1. */
|
|
||||||
int num_modules;
|
|
||||||
/** the module callbacks, array of num_modules length */
|
|
||||||
struct module_func_block** modfunc;
|
|
||||||
/** local authority zones */
|
|
||||||
struct local_zones* local_zones;
|
|
||||||
|
|
||||||
/** TODO list of outstanding queries */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The error constants
|
|
||||||
*/
|
|
||||||
enum ub_ctx_err {
|
|
||||||
/** no error */
|
|
||||||
UB_NOERROR = 0,
|
|
||||||
/** alloc failure */
|
|
||||||
UB_NOMEM,
|
|
||||||
/** socket operation */
|
|
||||||
UB_SOCKET,
|
|
||||||
/** syntax error */
|
|
||||||
UB_SYNTAX,
|
|
||||||
/** DNS service failed */
|
|
||||||
UB_SERVFAIL
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct ub_val_ctx*
|
struct ub_val_ctx*
|
||||||
ub_val_ctx_create()
|
ub_val_ctx_create()
|
||||||
|
|
@ -115,6 +64,10 @@ ub_val_ctx_create()
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
checklock_start();
|
checklock_start();
|
||||||
|
log_ident_set("libunbound");
|
||||||
|
verbosity = 0; /* errors only */
|
||||||
|
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||||
|
alloc_init(&ctx->superalloc, NULL, 0);
|
||||||
if(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx->qqpipe) == -1) {
|
if(socketpair(AF_UNIX, SOCK_STREAM, 0, ctx->qqpipe) == -1) {
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -129,35 +82,80 @@ ub_val_ctx_create()
|
||||||
}
|
}
|
||||||
lock_basic_init(&ctx->qqpipe_lock);
|
lock_basic_init(&ctx->qqpipe_lock);
|
||||||
lock_basic_init(&ctx->rrpipe_lock);
|
lock_basic_init(&ctx->rrpipe_lock);
|
||||||
ctx->cfg = config_create();
|
lock_basic_init(&ctx->cfglock);
|
||||||
if(!ctx->cfg) {
|
ctx->env = (struct module_env*)calloc(1, sizeof(*ctx->env));
|
||||||
|
if(!ctx->env) {
|
||||||
ub_val_ctx_delete(ctx);
|
ub_val_ctx_delete(ctx);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
ctx->env->cfg = config_create();
|
||||||
|
if(!ctx->env->cfg) {
|
||||||
|
ub_val_ctx_delete(ctx);
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ctx->env->alloc = &ctx->superalloc;
|
||||||
|
ctx->env->worker = NULL;
|
||||||
|
ctx->env->need_to_validate = 0;
|
||||||
|
modstack_init(&ctx->mods);
|
||||||
|
rbtree_init(&ctx->queries, &context_query_cmp);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** delete q */
|
||||||
|
static void
|
||||||
|
delq(rbnode_t* n, void* ATTR_UNUSED(arg))
|
||||||
|
{
|
||||||
|
struct ctx_query* q = (struct ctx_query*)n;
|
||||||
|
if(!q) return;
|
||||||
|
ub_val_result_free(q->res);
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ub_val_ctx_delete(struct ub_val_ctx* ctx)
|
ub_val_ctx_delete(struct ub_val_ctx* ctx)
|
||||||
{
|
{
|
||||||
|
struct alloc_cache* a, *na;
|
||||||
if(!ctx) return;
|
if(!ctx) return;
|
||||||
|
modstack_desetup(&ctx->mods, ctx->env);
|
||||||
|
a = ctx->alloc_list;
|
||||||
|
while(a) {
|
||||||
|
na = a->super;
|
||||||
|
a->super = &ctx->superalloc;
|
||||||
|
alloc_clear(a);
|
||||||
|
a = na;
|
||||||
|
}
|
||||||
|
alloc_clear(&ctx->superalloc);
|
||||||
|
local_zones_delete(ctx->local_zones);
|
||||||
lock_basic_destroy(&ctx->qqpipe_lock);
|
lock_basic_destroy(&ctx->qqpipe_lock);
|
||||||
lock_basic_destroy(&ctx->rrpipe_lock);
|
lock_basic_destroy(&ctx->rrpipe_lock);
|
||||||
|
lock_basic_destroy(&ctx->cfglock);
|
||||||
close(ctx->qqpipe[0]);
|
close(ctx->qqpipe[0]);
|
||||||
close(ctx->qqpipe[1]);
|
close(ctx->qqpipe[1]);
|
||||||
close(ctx->rrpipe[0]);
|
close(ctx->rrpipe[0]);
|
||||||
close(ctx->rrpipe[1]);
|
close(ctx->rrpipe[1]);
|
||||||
config_delete(ctx->cfg);
|
if(ctx->env) {
|
||||||
|
slabhash_delete(ctx->env->msg_cache);
|
||||||
|
rrset_cache_delete(ctx->env->rrset_cache);
|
||||||
|
infra_delete(ctx->env->infra_cache);
|
||||||
|
config_delete(ctx->env->cfg);
|
||||||
|
free(ctx->env);
|
||||||
|
}
|
||||||
|
traverse_postorder(&ctx->queries, delq, NULL);
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname)
|
ub_val_ctx_config(struct ub_val_ctx* ctx, char* fname)
|
||||||
{
|
{
|
||||||
if(!config_read(ctx->cfg, fname)) {
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
ctx->finalized = 0;
|
||||||
|
if(!config_read(ctx->env->cfg, fname)) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_SYNTAX;
|
return UB_SYNTAX;
|
||||||
}
|
}
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,10 +164,14 @@ ub_val_ctx_add_ta(struct ub_val_ctx* ctx, char* ta)
|
||||||
{
|
{
|
||||||
char* dup = strdup(ta);
|
char* dup = strdup(ta);
|
||||||
if(!dup) return UB_NOMEM;
|
if(!dup) return UB_NOMEM;
|
||||||
if(!cfg_strlist_insert(&ctx->cfg->trust_anchor_list, dup)) {
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
ctx->finalized = 0;
|
||||||
|
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
free(dup);
|
free(dup);
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
}
|
}
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,17 +180,24 @@ ub_val_ctx_trustedkeys(struct ub_val_ctx* ctx, char* fname)
|
||||||
{
|
{
|
||||||
char* dup = strdup(fname);
|
char* dup = strdup(fname);
|
||||||
if(!dup) return UB_NOMEM;
|
if(!dup) return UB_NOMEM;
|
||||||
if(!cfg_strlist_insert(&ctx->cfg->trusted_keys_file_list, dup)) {
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
ctx->finalized = 0;
|
||||||
|
if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
free(dup);
|
free(dup);
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
}
|
}
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread)
|
ub_val_ctx_async(struct ub_val_ctx* ctx, int dothread)
|
||||||
{
|
{
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
ctx->finalized = 0;
|
||||||
ctx->dothread = dothread;
|
ctx->dothread = dothread;
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,13 +232,17 @@ ub_val_ctx_poll(struct ub_val_ctx* ctx)
|
||||||
int
|
int
|
||||||
ub_val_ctx_wait(struct ub_val_ctx* ctx)
|
ub_val_ctx_wait(struct ub_val_ctx* ctx)
|
||||||
{
|
{
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
/* TODO until no more queries outstanding */
|
/* TODO until no more queries outstanding */
|
||||||
while(1) {
|
while(ctx->num_async > 0) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
lock_basic_lock(&ctx->rrpipe_lock);
|
lock_basic_lock(&ctx->rrpipe_lock);
|
||||||
(void)pollit(ctx, NULL);
|
(void)pollit(ctx, NULL);
|
||||||
lock_basic_unlock(&ctx->rrpipe_lock);
|
lock_basic_unlock(&ctx->rrpipe_lock);
|
||||||
ub_val_ctx_process(ctx);
|
ub_val_ctx_process(ctx);
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
}
|
}
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOERROR;
|
return UB_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,6 +256,7 @@ int
|
||||||
ub_val_ctx_process(struct ub_val_ctx* ctx)
|
ub_val_ctx_process(struct ub_val_ctx* ctx)
|
||||||
{
|
{
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
/* ctx->num_asynx-- when handled; */
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +264,25 @@ int
|
||||||
ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
ub_val_resolve(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||||
int rrclass, int* secure, int* data, struct ub_val_result** result)
|
int rrclass, int* secure, int* data, struct ub_val_result** result)
|
||||||
{
|
{
|
||||||
|
struct ctx_query* q;
|
||||||
|
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
if(!ctx->finalized) {
|
||||||
|
int r = context_finalize(ctx);
|
||||||
|
if(r) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* create new ctx_query and attempt to add to the list */
|
||||||
|
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
if(!q)
|
||||||
|
return UB_NOMEM;
|
||||||
/* become a resolver thread for a bit */
|
/* become a resolver thread for a bit */
|
||||||
|
*secure = 0;
|
||||||
|
*data = 0;
|
||||||
|
*result = NULL;
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
|
|
@ -260,14 +292,41 @@ int
|
||||||
ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
ub_val_resolve_async(struct ub_val_ctx* ctx, char* name, int rrtype,
|
||||||
int rrclass, void* mydata, ub_val_callback_t callback, int* async_id)
|
int rrclass, void* mydata, ub_val_callback_t callback, int* async_id)
|
||||||
{
|
{
|
||||||
/* TODO */
|
struct ctx_query* q;
|
||||||
|
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
if(!ctx->finalized) {
|
||||||
|
int r = context_finalize(ctx);
|
||||||
|
if(r) {
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* create new ctx_query and attempt to add to the list */
|
||||||
|
q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
if(!q)
|
||||||
|
return UB_NOMEM;
|
||||||
|
/* TODO write over pipe to background worker */
|
||||||
|
*async_id = q->querynum;
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ub_val_cancel(struct ub_val_ctx* ctx, int async_id)
|
ub_val_cancel(struct ub_val_ctx* ctx, int async_id)
|
||||||
{
|
{
|
||||||
/* TODO */
|
struct ctx_query* q;
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
q = (struct ctx_query*)rbtree_search(&ctx->queries, &async_id);
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
if(!q || !q->async) /* it is not there, so nothing to do */
|
||||||
|
return UB_NOERROR;
|
||||||
|
/* TODO ; send cancel to background worker */
|
||||||
|
|
||||||
|
lock_basic_lock(&ctx->cfglock);
|
||||||
|
(void)rbtree_delete(&ctx->queries, &async_id);
|
||||||
|
ctx->num_async--;
|
||||||
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
return UB_NOMEM;
|
return UB_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,6 +353,7 @@ ub_val_strerror(int err)
|
||||||
case UB_SOCKET: return "socket io error";
|
case UB_SOCKET: return "socket io error";
|
||||||
case UB_SYNTAX: return "syntax error";
|
case UB_SYNTAX: return "syntax error";
|
||||||
case UB_SERVFAIL: return "server failure";
|
case UB_SERVFAIL: return "server failure";
|
||||||
|
case UB_INITFAIL: return "initialization failure";
|
||||||
default: return "unknown error";
|
default: return "unknown error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue