Ejemplo n.º 1
0
/** do the status command */
static void
do_forward(SSL* ssl, struct worker* worker, char* args)
{
	struct iter_forwards* fwd = worker->env.fwds;
	uint8_t* root = (uint8_t*)"\000";
	if(!fwd) {
		(void)ssl_printf(ssl, "error: structure not allocated\n");
		return;
	}
	if(args == NULL || args[0] == 0) {
		(void)print_root_fwds(ssl, fwd, root);
		return;
	}
	/* set root forwards for this thread. since we are in remote control
	 * the actual mesh is not running, so we can freely edit it. */
	/* delete all the existing queries first */
	mesh_delete_all(worker->env.mesh);
	/* reset the fwd structure ; the cfg is unchanged (shared by threads)*/
	/* this reset frees up memory */
	forwards_apply_cfg(fwd, worker->env.cfg);
	if(strcmp(args, "off") == 0) {
		forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root);
	} else {
		struct delegpt* dp;
		if(!(dp = parse_delegpt(ssl, fwd->region, args, root)))
			return;
		if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) {
			(void)ssl_printf(ssl, "error out of memory\n");
			return;
		}
	}
	send_ok(ssl);
}
Ejemplo n.º 2
0
/** check forwards */
static void
check_fwd(struct config_file* cfg)
{
	struct iter_forwards* fwd = forwards_create();
	if(!fwd || !forwards_apply_cfg(fwd, cfg)) {
		fatal_exit("Could not set forward zones");
	}
	forwards_delete(fwd);
}
Ejemplo n.º 3
0
/** setup fresh libworker struct */
static struct libworker*
libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
{
	unsigned int seed;
	struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
	struct config_file* cfg = ctx->env->cfg;
	int* ports;
	int numports;
	if(!w) return NULL;
	w->is_bg = is_bg;
	w->ctx = ctx;
	w->env = (struct module_env*)malloc(sizeof(*w->env));
	if(!w->env) {
		free(w);
		return NULL;
	}
	*w->env = *ctx->env;
	w->env->alloc = context_obtain_alloc(ctx, !w->is_bg || w->is_bg_thread);
	if(!w->env->alloc) {
		libworker_delete(w);
		return NULL;
	}
	w->thread_num = w->env->alloc->thread_num;
	alloc_set_id_cleanup(w->env->alloc, &libworker_alloc_cleanup, w);
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_lock(&ctx->cfglock);
	}
	w->env->scratch = regional_create_custom(cfg->msg_buffer_size);
	w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
	w->env->fwds = forwards_create();
	if(w->env->fwds && !forwards_apply_cfg(w->env->fwds, cfg)) { 
		forwards_delete(w->env->fwds);
		w->env->fwds = NULL;
	}
	w->env->hints = hints_create();
	if(w->env->hints && !hints_apply_cfg(w->env->hints, cfg)) { 
		hints_delete(w->env->hints);
		w->env->hints = NULL;
	}
	if(cfg->ssl_upstream) {
		w->sslctx = connect_sslctx_create(NULL, NULL,
			cfg->tls_cert_bundle);
		if(!w->sslctx) {
			/* to make the setup fail after unlock */
			hints_delete(w->env->hints);
			w->env->hints = NULL;
		}
	}
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_unlock(&ctx->cfglock);
	}
	if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds ||
		!w->env->hints) {
		libworker_delete(w);
		return NULL;
	}
	w->env->worker = (struct worker*)w;
	w->env->probe_timer = NULL;
	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
		(((unsigned int)w->thread_num)<<17);
	seed ^= (unsigned int)w->env->alloc->next_id;
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_lock(&ctx->cfglock);
	}
	if(!(w->env->rnd = ub_initstate(seed, ctx->seed_rnd))) {
		if(!w->is_bg || w->is_bg_thread) {
			lock_basic_unlock(&ctx->cfglock);
		}
		seed = 0;
		libworker_delete(w);
		return NULL;
	}
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_unlock(&ctx->cfglock);
	}
	if(1) {
		/* primitive lockout for threading: if it overwrites another
		 * thread it is like wiping the cache (which is likely empty
		 * at the start) */
		/* note we are holding the ctx lock in normal threaded
		 * cases so that is solved properly, it is only for many ctx
		 * in different threads that this may clash */
		static int done_raninit = 0;
		if(!done_raninit) {
			done_raninit = 1;
			hash_set_raninit((uint32_t)ub_random(w->env->rnd));
		}
	}
	seed = 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;
	}
	w->env->worker_base = w->base;
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_lock(&ctx->cfglock);
	}
	numports = cfg_condense_ports(cfg, &ports);
	if(numports == 0) {
		int locked = !w->is_bg || w->is_bg_thread;
		libworker_delete(w);
		if(locked) {
			lock_basic_unlock(&ctx->cfglock);
		}
		return NULL;
	}
	w->back = outside_network_create(w->base, cfg->msg_buffer_size,
		(size_t)cfg->outgoing_num_ports, cfg->out_ifs,
		cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, 
		cfg->do_tcp?cfg->outgoing_num_tcp:0,
		w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
		ports, numports, cfg->unwanted_threshold,
		cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
		cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
		cfg->delay_close, NULL);
	w->env->outnet = w->back;
	if(!w->is_bg || w->is_bg_thread) {
		lock_basic_unlock(&ctx->cfglock);
	}
	free(ports);
	if(!w->back) {
		libworker_delete(w);
		return NULL;
	}
	w->env->mesh = mesh_create(&ctx->mods, w->env);
	if(!w->env->mesh) {
		libworker_delete(w);
		return NULL;
	}
	w->env->send_query = &libworker_send_query;
	w->env->detach_subs = &mesh_detach_subs;
	w->env->attach_sub = &mesh_attach_sub;
	w->env->add_sub = &mesh_add_sub;
	w->env->kill_sub = &mesh_state_delete;
	w->env->detect_cycle = &mesh_detect_cycle;
	comm_base_timept(w->base, &w->env->now, &w->env->now_tv);
	return w;
}