예제 #1
0
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;
	while(a) {
		na = a->super;
		a->super = &ctx->superalloc;
		alloc_clear(a);
		free(a);
		a = na;
	}
	local_zones_delete(ctx->local_zones);
	lock_basic_destroy(&ctx->qqpipe_lock);
	lock_basic_destroy(&ctx->rrpipe_lock);
	lock_basic_destroy(&ctx->cfglock);
	tube_delete(ctx->qq_pipe);
	tube_delete(ctx->rr_pipe);
	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);
		edns_known_options_delete(ctx->env);
		auth_zones_delete(ctx->env->auth_zones);
		free(ctx->env);
	}
	ub_randfree(ctx->seed_rnd);
	alloc_clear(&ctx->superalloc);
	traverse_postorder(&ctx->queries, delq, NULL);
	free(ctx);
#ifdef USE_WINSOCK
	WSACleanup();
#endif
}
예제 #2
0
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;
}
예제 #3
0
파일: tube.c 프로젝트: 2asoft/freebsd
struct tube* tube_create(void)
{
	struct tube* tube = (struct tube*)calloc(1, sizeof(*tube));
	int sv[2];
	if(!tube) {
		int err = errno;
		log_err("tube_create: out of memory");
		errno = err;
		return NULL;
	}
	tube->sr = -1;
	tube->sw = -1;
	if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
		int err = errno;
		log_err("socketpair: %s", strerror(errno));
		free(tube);
		errno = err;
		return NULL;
	}
	tube->sr = sv[0];
	tube->sw = sv[1];
	if(!fd_set_nonblock(tube->sr) || !fd_set_nonblock(tube->sw)) {
		int err = errno;
		log_err("tube: cannot set nonblocking");
		tube_delete(tube);
		errno = err;
		return NULL;
	}
	return tube;
}
예제 #4
0
/**
 * Close all pipes except for the numbered thread.
 * @param daemon: daemon to close pipes in.
 * @param thr: thread number 0..num-1 of thread to skip.
 */
static void close_other_pipes(struct daemon* daemon, int thr)
{
	int i;
	for(i=0; i<daemon->num; i++)
		if(i!=thr) {
			if(i==0) {
				/* only close read part, need to write stats */
				tube_close_read(daemon->workers[i]->cmd);
			} else {
				/* complete close channel to others */
				tube_delete(daemon->workers[i]->cmd);
				daemon->workers[i]->cmd = NULL;
			}
		}
}
예제 #5
0
struct ub_ctx*
ub_ctx_create(void)
{
    struct ub_ctx* ctx;
    unsigned int seed;
#ifdef USE_WINSOCK
    int r;
    WSADATA wsa_data;
#endif

    log_init(NULL, 0, NULL); /* logs to stderr */
    log_ident_set("libunbound");
#ifdef USE_WINSOCK
    if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
        log_err("could not init winsock. WSAStartup: %s",
                wsa_strerror(r));
        return NULL;
    }
#endif
    verbosity = 0; /* errors only */
    checklock_start();
    ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
    if(!ctx) {
        errno = ENOMEM;
        return NULL;
    }
    alloc_init(&ctx->superalloc, NULL, 0);
    seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
    if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
        seed = 0;
        ub_randfree(ctx->seed_rnd);
        free(ctx);
        errno = ENOMEM;
        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;
        return NULL;
    }
    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);
        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;
}
예제 #6
0
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) {
        uint8_t* msg;
        uint32_t len;
        uint32_t cmd = UB_LIBCMD_QUIT;
        lock_basic_unlock(&ctx->cfglock);
        lock_basic_lock(&ctx->qqpipe_lock);
        (void)tube_write_msg(ctx->qq_pipe, (uint8_t*)&cmd,
                             (uint32_t)sizeof(cmd), 0);
        lock_basic_unlock(&ctx->qqpipe_lock);
        lock_basic_lock(&ctx->rrpipe_lock);
        while(tube_read_msg(ctx->rr_pipe, &msg, &len, 0)) {
            /* discard all results except a quit confirm */
            if(context_serial_getcmd(msg, len) == UB_LIBCMD_QUIT) {
                free(msg);
                break;
            }
            free(msg);
        }
        lock_basic_unlock(&ctx->rrpipe_lock);

        /* if bg worker is a thread, wait for it to exit, so that all
         * resources are really gone. */
        lock_basic_lock(&ctx->cfglock);
        if(ctx->dothread) {
            lock_basic_unlock(&ctx->cfglock);
            ub_thread_join(ctx->bg_tid);
        } else {
            lock_basic_unlock(&ctx->cfglock);
        }
    }
    else {
        lock_basic_unlock(&ctx->cfglock);
    }


    modstack_desetup(&ctx->mods, ctx->env);
    a = ctx->alloc_list;
    while(a) {
        na = a->super;
        a->super = &ctx->superalloc;
        alloc_clear(a);
        free(a);
        a = na;
    }
    local_zones_delete(ctx->local_zones);
    lock_basic_destroy(&ctx->qqpipe_lock);
    lock_basic_destroy(&ctx->rrpipe_lock);
    lock_basic_destroy(&ctx->cfglock);
    tube_delete(ctx->qq_pipe);
    tube_delete(ctx->rr_pipe);
    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);
    }
    ub_randfree(ctx->seed_rnd);
    alloc_clear(&ctx->superalloc);
    traverse_postorder(&ctx->queries, delq, NULL);
    free(ctx);
#ifdef USE_WINSOCK
    WSACleanup();
#endif
}