Home | History | Annotate | Line # | Download | only in libunbound
      1 /*
      2  * libunbound/worker.c - worker thread or process that resolves
      3  *
      4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
      5  *
      6  * This software is open source.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * Redistributions of source code must retain the above copyright notice,
     13  * this list of conditions and the following disclaimer.
     14  *
     15  * Redistributions in binary form must reproduce the above copyright notice,
     16  * this list of conditions and the following disclaimer in the documentation
     17  * and/or other materials provided with the distribution.
     18  *
     19  * Neither the name of the NLNET LABS nor the names of its contributors may
     20  * be used to endorse or promote products derived from this software without
     21  * specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34  */
     35 
     36 /**
     37  * \file
     38  *
     39  * This file contains the worker process or thread that performs
     40  * the DNS resolving and validation. The worker is called by a procedure
     41  * and if in the background continues until exit, if in the foreground
     42  * returns from the procedure when done.
     43  */
     44 #include "config.h"
     45 #ifdef HAVE_SSL
     46 #include <openssl/ssl.h>
     47 #endif
     48 #include "libunbound/libworker.h"
     49 #include "libunbound/context.h"
     50 #include "libunbound/unbound.h"
     51 #include "libunbound/worker.h"
     52 #include "libunbound/unbound-event.h"
     53 #include "services/outside_network.h"
     54 #include "services/mesh.h"
     55 #include "services/localzone.h"
     56 #include "services/cache/rrset.h"
     57 #include "services/outbound_list.h"
     58 #include "services/authzone.h"
     59 #include "util/fptr_wlist.h"
     60 #include "util/module.h"
     61 #include "util/regional.h"
     62 #include "util/random.h"
     63 #include "util/config_file.h"
     64 #include "util/netevent.h"
     65 #include "util/proxy_protocol.h"
     66 #include "util/storage/lookup3.h"
     67 #include "util/storage/slabhash.h"
     68 #include "util/net_help.h"
     69 #include "util/data/dname.h"
     70 #include "util/data/msgreply.h"
     71 #include "util/data/msgencode.h"
     72 #include "util/tube.h"
     73 #include "sldns/sbuffer.h"
     74 #include "sldns/str2wire.h"
     75 #ifdef USE_DNSTAP
     76 #include "dnstap/dtstream.h"
     77 #endif
     78 
     79 #ifdef HAVE_TARGETCONDITIONALS_H
     80 #include <TargetConditionals.h>
     81 #endif
     82 
     83 #if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
     84 #undef HAVE_FORK
     85 #endif
     86 
     87 /** handle new query command for bg worker */
     88 static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
     89 
     90 /** delete libworker env */
     91 static void
     92 libworker_delete_env(struct libworker* w)
     93 {
     94 	if(w->env) {
     95 		outside_network_quit_prepare(w->back);
     96 		mesh_delete(w->env->mesh);
     97 		context_release_alloc(w->ctx, w->env->alloc,
     98 			!w->is_bg || w->is_bg_thread);
     99 		sldns_buffer_free(w->env->scratch_buffer);
    100 		regional_destroy(w->env->scratch);
    101 		ub_randfree(w->env->rnd);
    102 		free(w->env);
    103 	}
    104 #ifdef HAVE_SSL
    105 	SSL_CTX_free(w->sslctx);
    106 #endif
    107 	outside_network_delete(w->back);
    108 	shared_ports_delete(w->shared_ports);
    109 }
    110 
    111 /** delete libworker struct */
    112 static void
    113 libworker_delete(struct libworker* w)
    114 {
    115 	if(!w) return;
    116 	libworker_delete_env(w);
    117 	comm_base_delete(w->base);
    118 	free(w);
    119 }
    120 
    121 void
    122 libworker_delete_event(struct libworker* w)
    123 {
    124 	if(!w) return;
    125 	libworker_delete_env(w);
    126 	comm_base_delete_no_base(w->base);
    127 	free(w);
    128 }
    129 
    130 /** setup fresh libworker struct */
    131 static struct libworker*
    132 libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
    133 {
    134 	struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
    135 	struct config_file* cfg = ctx->env->cfg;
    136 	int* ports;
    137 	int numports;
    138 	if(!w) return NULL;
    139 	w->is_bg = is_bg;
    140 	w->ctx = ctx;
    141 	w->env = (struct module_env*)malloc(sizeof(*w->env));
    142 	if(!w->env) {
    143 		free(w);
    144 		return NULL;
    145 	}
    146 	*w->env = *ctx->env;
    147 	w->env->alloc = context_obtain_alloc(ctx, !w->is_bg || w->is_bg_thread);
    148 	if(!w->env->alloc) {
    149 		libworker_delete(w);
    150 		return NULL;
    151 	}
    152 	w->thread_num = w->env->alloc->thread_num;
    153 	alloc_set_id_cleanup(w->env->alloc, &libworker_alloc_cleanup, w);
    154 	if(!w->is_bg || w->is_bg_thread) {
    155 		lock_basic_lock(&ctx->cfglock);
    156 	}
    157 	w->env->scratch = regional_create_custom(cfg->msg_buffer_size);
    158 	w->env->scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
    159 #ifdef HAVE_SSL
    160 	w->sslctx = connect_sslctx_create(NULL, NULL,
    161 		cfg->tls_cert_bundle, cfg->tls_win_cert);
    162 	if(!w->sslctx) {
    163 		/* to make the setup fail after unlock */
    164 		sldns_buffer_free(w->env->scratch_buffer);
    165 		w->env->scratch_buffer = NULL;
    166 	}
    167 #endif
    168 	if(!w->is_bg || w->is_bg_thread) {
    169 		lock_basic_unlock(&ctx->cfglock);
    170 	}
    171 	if(!w->env->scratch || !w->env->scratch_buffer) {
    172 		libworker_delete(w);
    173 		return NULL;
    174 	}
    175 	w->env->worker = (struct worker*)w;
    176 	w->env->probe_timer = NULL;
    177 	if(!w->is_bg || w->is_bg_thread) {
    178 		lock_basic_lock(&ctx->cfglock);
    179 	}
    180 	if(!(w->env->rnd = ub_initstate(ctx->seed_rnd))) {
    181 		if(!w->is_bg || w->is_bg_thread) {
    182 			lock_basic_unlock(&ctx->cfglock);
    183 		}
    184 		libworker_delete(w);
    185 		return NULL;
    186 	}
    187 	if(!w->is_bg || w->is_bg_thread) {
    188 		lock_basic_unlock(&ctx->cfglock);
    189 	}
    190 	if(1) {
    191 		/* primitive lockout for threading: if it overwrites another
    192 		 * thread it is like wiping the cache (which is likely empty
    193 		 * at the start) */
    194 		/* note we are holding the ctx lock in normal threaded
    195 		 * cases so that is solved properly, it is only for many ctx
    196 		 * in different threads that this may clash */
    197 		static int done_raninit = 0;
    198 		if(!done_raninit) {
    199 			done_raninit = 1;
    200 			hash_set_raninit((uint32_t)ub_random(w->env->rnd));
    201 		}
    202 	}
    203 
    204 	if(eb)
    205 		w->base = comm_base_create_event(eb);
    206 	else	w->base = comm_base_create(0);
    207 	if(!w->base) {
    208 		libworker_delete(w);
    209 		return NULL;
    210 	}
    211 	w->env->worker_base = w->base;
    212 	if(!w->is_bg || w->is_bg_thread) {
    213 		lock_basic_lock(&ctx->cfglock);
    214 	}
    215 	numports = cfg_condense_ports(cfg, &ports);
    216 	if(numports == 0) {
    217 		if(!w->is_bg || w->is_bg_thread) {
    218 			lock_basic_unlock(&ctx->cfglock);
    219 		}
    220 		libworker_delete(w);
    221 		return NULL;
    222 	}
    223 	if(!(w->shared_ports = shared_ports_create(cfg->out_ifs,
    224 		cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, ports, numports))) {
    225 		if(!w->is_bg || w->is_bg_thread) {
    226 			lock_basic_unlock(&ctx->cfglock);
    227 		}
    228 		libworker_delete(w);
    229 		return NULL;
    230 	}
    231 	w->back = outside_network_create(w->base, cfg->msg_buffer_size,
    232 		(size_t)cfg->outgoing_num_ports, cfg->out_ifs,
    233 		cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
    234 		cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
    235 		w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
    236 		cfg->unwanted_threshold,
    237 		cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
    238 		cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
    239 		cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
    240 		cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
    241 		cfg->tcp_auth_query_timeout, w->shared_ports);
    242 	w->env->outnet = w->back;
    243 	if(!w->is_bg || w->is_bg_thread) {
    244 		lock_basic_unlock(&ctx->cfglock);
    245 	}
    246 	free(ports);
    247 	if(!w->back) {
    248 		libworker_delete(w);
    249 		return NULL;
    250 	}
    251 	w->env->mesh = mesh_create(&ctx->mods, w->env);
    252 	if(!w->env->mesh) {
    253 		libworker_delete(w);
    254 		return NULL;
    255 	}
    256 	w->env->send_query = &libworker_send_query;
    257 	w->env->detach_subs = &mesh_detach_subs;
    258 	w->env->attach_sub = &mesh_attach_sub;
    259 	w->env->add_sub = &mesh_add_sub;
    260 	w->env->kill_sub = &mesh_state_delete;
    261 	w->env->detect_cycle = &mesh_detect_cycle;
    262 	comm_base_timept(w->base, &w->env->now, &w->env->now_tv);
    263 	pp_init(&sldns_write_uint16, &sldns_write_uint32);
    264 	return w;
    265 }
    266 
    267 struct libworker* libworker_create_event(struct ub_ctx* ctx,
    268 	struct ub_event_base* eb)
    269 {
    270 	return libworker_setup(ctx, 0, eb);
    271 }
    272 
    273 /** handle cancel command for bg worker */
    274 static void
    275 handle_cancel(struct libworker* w, uint8_t* buf, uint32_t len)
    276 {
    277 	struct ctx_query* q;
    278 	if(w->is_bg_thread) {
    279 		lock_basic_lock(&w->ctx->cfglock);
    280 		q = context_deserialize_cancel(w->ctx, buf, len);
    281 		lock_basic_unlock(&w->ctx->cfglock);
    282 	} else {
    283 		q = context_deserialize_cancel(w->ctx, buf, len);
    284 	}
    285 	if(!q) {
    286 		/* probably simply lookup failed, i.e. the message had been
    287 		 * processed and answered before the cancel arrived */
    288 		return;
    289 	}
    290 	q->cancelled = 1;
    291 	free(buf);
    292 }
    293 
    294 /** do control command coming into bg server */
    295 static void
    296 libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len)
    297 {
    298 	switch(context_serial_getcmd(msg, len)) {
    299 		default:
    300 		case UB_LIBCMD_ANSWER:
    301 			log_err("unknown command for bg worker %d",
    302 				(int)context_serial_getcmd(msg, len));
    303 			/* and fall through to quit */
    304 			ATTR_FALLTHROUGH
    305 			/* fallthrough */
    306 		case UB_LIBCMD_QUIT:
    307 			free(msg);
    308 			comm_base_exit(w->base);
    309 			break;
    310 		case UB_LIBCMD_NEWQUERY:
    311 			handle_newq(w, msg, len);
    312 			break;
    313 		case UB_LIBCMD_CANCEL:
    314 			handle_cancel(w, msg, len);
    315 			break;
    316 	}
    317 }
    318 
    319 /** handle control command coming into server */
    320 void
    321 libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
    322 	uint8_t* msg, size_t len, int err, void* arg)
    323 {
    324 	struct libworker* w = (struct libworker*)arg;
    325 
    326 	if(err != 0) {
    327 		free(msg);
    328 		/* it is of no use to go on, exit */
    329 		comm_base_exit(w->base);
    330 		return;
    331 	}
    332 	libworker_do_cmd(w, msg, len); /* also frees the buf */
    333 }
    334 
    335 /** the background thread func */
    336 static void*
    337 libworker_dobg(void* arg)
    338 {
    339 	/* setup */
    340 	uint32_t m;
    341 	struct libworker* w = (struct libworker*)arg;
    342 	struct ub_ctx* ctx;
    343 	if(!w) {
    344 		log_err("libunbound bg worker init failed, nomem");
    345 		return NULL;
    346 	}
    347 	ctx = w->ctx;
    348 	log_thread_set(&w->thread_num);
    349 #ifdef THREADS_DISABLED
    350 	/* we are forked */
    351 	w->is_bg_thread = 0;
    352 	/* close non-used parts of the pipes */
    353 	tube_close_write(ctx->qq_pipe);
    354 	tube_close_read(ctx->rr_pipe);
    355 #endif
    356 	if(!tube_setup_bg_listen(ctx->qq_pipe, w->base,
    357 		libworker_handle_control_cmd, w)) {
    358 		log_err("libunbound bg worker init failed, no bglisten");
    359 		return NULL;
    360 	}
    361 	if(!tube_setup_bg_write(ctx->rr_pipe, w->base)) {
    362 		log_err("libunbound bg worker init failed, no bgwrite");
    363 		return NULL;
    364 	}
    365 
    366 	/* do the work */
    367 	comm_base_dispatch(w->base);
    368 
    369 	/* cleanup */
    370 	m = UB_LIBCMD_QUIT;
    371 	w->want_quit = 1;
    372 	tube_remove_bg_listen(w->ctx->qq_pipe);
    373 	tube_remove_bg_write(w->ctx->rr_pipe);
    374 	libworker_delete(w);
    375 	(void)tube_write_msg(ctx->rr_pipe, (uint8_t*)&m,
    376 		(uint32_t)sizeof(m), 0);
    377 #ifdef THREADS_DISABLED
    378 	/* close pipes from forked process before exit */
    379 	tube_close_read(ctx->qq_pipe);
    380 	tube_close_write(ctx->rr_pipe);
    381 #endif
    382 	return NULL;
    383 }
    384 
    385 int libworker_bg(struct ub_ctx* ctx)
    386 {
    387 	struct libworker* w;
    388 	/* fork or threadcreate */
    389 	lock_basic_lock(&ctx->cfglock);
    390 	if(ctx->dothread) {
    391 		lock_basic_unlock(&ctx->cfglock);
    392 		w = libworker_setup(ctx, 1, NULL);
    393 		if(!w) return UB_NOMEM;
    394 		w->is_bg_thread = 1;
    395 		ctx->thread_worker = w;
    396 #ifdef ENABLE_LOCK_CHECKS
    397 		w->thread_num = 1; /* for nicer DEBUG checklocks */
    398 #endif
    399 		ub_thread_create(&ctx->bg_tid, libworker_dobg, w);
    400 	} else {
    401 		lock_basic_unlock(&ctx->cfglock);
    402 #ifndef HAVE_FORK
    403 		/* no fork on windows */
    404 		return UB_FORKFAIL;
    405 #else /* HAVE_FORK */
    406 		switch((ctx->bg_pid=fork())) {
    407 			case 0:
    408 				w = libworker_setup(ctx, 1, NULL);
    409 				if(!w) fatal_exit("out of memory");
    410 				/* close non-used parts of the pipes */
    411 				tube_close_write(ctx->qq_pipe);
    412 				tube_close_read(ctx->rr_pipe);
    413 				(void)libworker_dobg(w);
    414 				exit(0);
    415 				break;
    416 			case -1:
    417 				return UB_FORKFAIL;
    418 			default:
    419 				/* close non-used parts, so that the worker
    420 				 * bgprocess gets 'pipe closed' when the
    421 				 * main process exits */
    422 				tube_close_read(ctx->qq_pipe);
    423 				tube_close_write(ctx->rr_pipe);
    424 				break;
    425 		}
    426 #endif /* HAVE_FORK */
    427 	}
    428 	return UB_NOERROR;
    429 }
    430 
    431 /** insert canonname */
    432 static int
    433 fill_canon(struct ub_result* res, uint8_t* s)
    434 {
    435 	char buf[LDNS_MAX_DOMAINLEN];
    436 	dname_str(s, buf);
    437 	res->canonname = strdup(buf);
    438 	return res->canonname != 0;
    439 }
    440 
    441 /** fill data into result */
    442 static int
    443 fill_res(struct ub_result* res, struct ub_packed_rrset_key* answer,
    444 	uint8_t* finalcname, struct query_info* rq, struct reply_info* rep)
    445 {
    446 	size_t i;
    447 	struct packed_rrset_data* data;
    448 	res->ttl = 0;
    449 	if(!answer) {
    450 		if(finalcname) {
    451 			if(!fill_canon(res, finalcname))
    452 				return 0; /* out of memory */
    453 		}
    454 		if(rep->rrset_count != 0)
    455 			res->ttl = (int)rep->ttl;
    456 		res->data = (char**)calloc(1, sizeof(char*));
    457 		if(!res->data)
    458 			return 0; /* out of memory */
    459 		res->len = (int*)calloc(1, sizeof(int));
    460 		if(!res->len) {
    461 			free(res->data);
    462 			res->data = NULL;
    463 			return 0; /* out of memory */
    464 		}
    465 		return 1;
    466 	}
    467 	data = (struct packed_rrset_data*)answer->entry.data;
    468 	if(query_dname_compare(rq->qname, answer->rk.dname) != 0) {
    469 		if(!fill_canon(res, answer->rk.dname))
    470 			return 0; /* out of memory */
    471 	} else	res->canonname = NULL;
    472 	res->data = (char**)calloc(data->count+1, sizeof(char*));
    473 	if(!res->data)
    474 		return 0; /* out of memory */
    475 	res->len = (int*)calloc(data->count+1, sizeof(int));
    476 	if(!res->len) {
    477 		free(res->data);
    478 		res->data = NULL;
    479 		return 0; /* out of memory */
    480 	}
    481 	for(i=0; i<data->count; i++) {
    482 		/* remove rdlength from rdata */
    483 		res->len[i] = (int)(data->rr_len[i] - 2);
    484 		res->data[i] = memdup(data->rr_data[i]+2, (size_t)res->len[i]);
    485 		if(!res->data[i]) {
    486 			size_t j;
    487 			for(j=0; j<i; j++) {
    488 				free(res->data[j]);
    489 				res->data[j] = NULL;
    490 			}
    491 			free(res->data);
    492 			res->data = NULL;
    493 			free(res->len);
    494 			res->len = NULL;
    495 			return 0; /* out of memory */
    496 		}
    497 	}
    498 	/* ttl for positive answers, from CNAME and answer RRs */
    499 	if(data->count != 0) {
    500 		size_t j;
    501 		res->ttl = (int)data->ttl;
    502 		for(j=0; j<rep->an_numrrsets; j++) {
    503 			struct packed_rrset_data* d =
    504 				(struct packed_rrset_data*)rep->rrsets[j]->
    505 				entry.data;
    506 			if((int)d->ttl < res->ttl)
    507 				res->ttl = (int)d->ttl;
    508 		}
    509 	}
    510 	/* ttl for negative answers */
    511 	if(data->count == 0 && rep->rrset_count != 0)
    512 		res->ttl = (int)rep->ttl;
    513 	res->data[data->count] = NULL;
    514 	res->len[data->count] = 0;
    515 	return 1;
    516 }
    517 
    518 /** fill result from parsed message, on error fills servfail */
    519 void
    520 libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
    521 	struct regional* temp, enum sec_status msg_security)
    522 {
    523 	struct query_info rq;
    524 	struct reply_info* rep;
    525 	res->rcode = LDNS_RCODE_SERVFAIL;
    526 	rep = parse_reply_in_temp_region(buf, temp, &rq);
    527 	if(!rep) {
    528 		log_err("cannot parse buf");
    529 		return; /* error parsing buf, or out of memory */
    530 	}
    531 	if(!fill_res(res, reply_find_answer_rrset(&rq, rep),
    532 		reply_find_final_cname_target(&rq, rep), &rq, rep))
    533 		return; /* out of memory */
    534 	/* rcode, havedata, nxdomain, secure, bogus */
    535 	res->rcode = (int)FLAGS_GET_RCODE(rep->flags);
    536 	if(res->data && res->data[0])
    537 		res->havedata = 1;
    538 	if(res->rcode == LDNS_RCODE_NXDOMAIN)
    539 		res->nxdomain = 1;
    540 	if(msg_security == sec_status_secure)
    541 		res->secure = 1;
    542 	if(msg_security == sec_status_bogus ||
    543 		msg_security == sec_status_secure_sentinel_fail)
    544 		res->bogus = 1;
    545 }
    546 
    547 /** fillup fg results */
    548 static void
    549 libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
    550 	enum sec_status s, char* why_bogus, int was_ratelimited)
    551 {
    552 	q->res->was_ratelimited = was_ratelimited;
    553 	if(why_bogus)
    554 		q->res->why_bogus = strdup(why_bogus);
    555 	if(rcode != 0) {
    556 		q->res->rcode = rcode;
    557 		q->msg_security = s;
    558 		return;
    559 	}
    560 
    561 	q->res->rcode = LDNS_RCODE_SERVFAIL;
    562 	q->msg_security = sec_status_unchecked;
    563 	q->msg = memdup(sldns_buffer_begin(buf), sldns_buffer_limit(buf));
    564 	q->msg_len = sldns_buffer_limit(buf);
    565 	if(!q->msg) {
    566 		return; /* the error is in the rcode */
    567 	}
    568 
    569 	/* canonname and results */
    570 	q->msg_security = s;
    571 	libworker_enter_result(q->res, buf, q->w->env->scratch, s);
    572 }
    573 
    574 void
    575 libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
    576 	char* why_bogus, int was_ratelimited)
    577 {
    578 	struct ctx_query* q = (struct ctx_query*)arg;
    579 	/* fg query is done; exit comm base */
    580 	comm_base_exit(q->w->base);
    581 
    582 	libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited);
    583 }
    584 
    585 /** setup qinfo and edns */
    586 static int
    587 setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
    588 	struct query_info* qinfo, struct edns_data* edns)
    589 {
    590 	qinfo->qtype = (uint16_t)q->res->qtype;
    591 	qinfo->qclass = (uint16_t)q->res->qclass;
    592 	qinfo->local_alias = NULL;
    593 	qinfo->qname = sldns_str2wire_dname(q->res->qname, &qinfo->qname_len);
    594 	if(!qinfo->qname) {
    595 		return 0;
    596 	}
    597 	edns->edns_present = 1;
    598 	edns->ext_rcode = 0;
    599 	edns->edns_version = 0;
    600 	edns->bits = EDNS_DO;
    601 	edns->opt_list_in = NULL;
    602 	edns->opt_list_out = NULL;
    603 	edns->opt_list_inplace_cb_out = NULL;
    604 	edns->padding_block_size = 0;
    605 	edns->cookie_present = 0;
    606 	edns->cookie_valid = 0;
    607 	if(sldns_buffer_capacity(w->back->udp_buff) < 65535)
    608 		edns->udp_size = (uint16_t)sldns_buffer_capacity(
    609 			w->back->udp_buff);
    610 	else	edns->udp_size = 65535;
    611 	return 1;
    612 }
    613 
    614 int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
    615 {
    616 	struct libworker* w = libworker_setup(ctx, 0, NULL);
    617 	uint16_t qflags, qid;
    618 	struct query_info qinfo;
    619 	struct edns_data edns;
    620 	if(!w)
    621 		return UB_INITFAIL;
    622 	if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
    623 		libworker_delete(w);
    624 		return UB_SYNTAX;
    625 	}
    626 	qid = 0;
    627 	qflags = BIT_RD;
    628 	q->w = w;
    629 	/* see if there is a fixed answer */
    630 	sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
    631 	sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
    632 	if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns,
    633 		w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
    634 		NULL, 0, NULL, 0, NULL)) {
    635 		regional_free_all(w->env->scratch);
    636 		libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
    637 			w->back->udp_buff, sec_status_insecure, NULL, 0);
    638 		libworker_delete(w);
    639 		free(qinfo.qname);
    640 		return UB_NOERROR;
    641 	}
    642 	if(ctx->env->auth_zones && auth_zones_downstream_answer(
    643 		ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
    644 		w->back->udp_buff, w->env->scratch)) {
    645 		regional_free_all(w->env->scratch);
    646 		libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
    647 			w->back->udp_buff, sec_status_insecure, NULL, 0);
    648 		libworker_delete(w);
    649 		free(qinfo.qname);
    650 		return UB_NOERROR;
    651 	}
    652 	/* process new query */
    653 	if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
    654 		w->back->udp_buff, qid, libworker_fg_done_cb, q, 0,
    655 		&q->unique_info)) {
    656 		free(qinfo.qname);
    657 		return UB_NOMEM;
    658 	}
    659 	free(qinfo.qname);
    660 
    661 	/* wait for reply */
    662 	comm_base_dispatch(w->base);
    663 
    664 	libworker_delete(w);
    665 	return UB_NOERROR;
    666 }
    667 
    668 void
    669 libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
    670 	enum sec_status s, char* why_bogus, int was_ratelimited)
    671 {
    672 	struct ctx_query* q = (struct ctx_query*)arg;
    673 	ub_event_callback_type cb = q->cb_event;
    674 	void* cb_arg = q->cb_arg;
    675 	int cancelled = q->cancelled;
    676 
    677 	/* delete it now */
    678 	struct ub_ctx* ctx = q->w->ctx;
    679 	lock_basic_lock(&ctx->cfglock);
    680 	(void)rbtree_delete(&ctx->queries, q->node.key);
    681 	ctx->num_async--;
    682 	context_query_delete(q);
    683 	lock_basic_unlock(&ctx->cfglock);
    684 
    685 	if(!cancelled) {
    686 		/* call callback */
    687 		int sec = 0;
    688 		if(s == sec_status_bogus)
    689 			sec = 1;
    690 		else if(s == sec_status_secure)
    691 			sec = 2;
    692 		(*cb)(cb_arg, rcode, (buf?(void*)sldns_buffer_begin(buf):NULL),
    693 			(buf?(int)sldns_buffer_limit(buf):0), sec, why_bogus, was_ratelimited);
    694 	}
    695 }
    696 
    697 int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
    698 	int* async_id)
    699 {
    700 	struct libworker* w = ctx->event_worker;
    701 	uint16_t qflags, qid;
    702 	struct query_info qinfo;
    703 	struct edns_data edns;
    704 	if(!w)
    705 		return UB_INITFAIL;
    706 	if(!setup_qinfo_edns(w, q, &qinfo, &edns))
    707 		return UB_SYNTAX;
    708 	qid = 0;
    709 	qflags = BIT_RD;
    710 	q->w = w;
    711 	/* see if there is a fixed answer */
    712 	sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
    713 	sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
    714 	if(local_zones_answer(ctx->local_zones, w->env, &qinfo, &edns,
    715 		w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
    716 		NULL, 0, NULL, 0, NULL)) {
    717 		regional_free_all(w->env->scratch);
    718 		free(qinfo.qname);
    719 		libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
    720 			w->back->udp_buff, sec_status_insecure, NULL, 0);
    721 		return UB_NOERROR;
    722 	}
    723 	if(ctx->env->auth_zones && auth_zones_downstream_answer(
    724 		ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
    725 		w->back->udp_buff, w->env->scratch)) {
    726 		regional_free_all(w->env->scratch);
    727 		free(qinfo.qname);
    728 		libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
    729 			w->back->udp_buff, sec_status_insecure, NULL, 0);
    730 		return UB_NOERROR;
    731 	}
    732 	/* process new query */
    733 	if(async_id)
    734 		*async_id = q->querynum;
    735 	if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
    736 		w->back->udp_buff, qid, libworker_event_done_cb, q, 0,
    737 		&q->unique_info)) {
    738 		free(qinfo.qname);
    739 		return UB_NOMEM;
    740 	}
    741 	free(qinfo.qname);
    742 	return UB_NOERROR;
    743 }
    744 
    745 /** add result to the bg worker result queue */
    746 static void
    747 add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
    748 	int err, char* reason, int was_ratelimited)
    749 {
    750 	uint8_t* msg = NULL;
    751 	uint32_t len = 0;
    752 
    753 	if(w->want_quit) {
    754 		context_query_delete(q);
    755 		return;
    756 	}
    757 	/* serialize and delete unneeded q */
    758 	if(w->is_bg_thread) {
    759 		lock_basic_lock(&w->ctx->cfglock);
    760 		if(reason)
    761 			q->res->why_bogus = strdup(reason);
    762 		q->res->was_ratelimited = was_ratelimited;
    763 		if(pkt) {
    764 			q->msg_len = sldns_buffer_remaining(pkt);
    765 			q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len);
    766 			if(!q->msg) {
    767 				msg = context_serialize_answer(q, UB_NOMEM, NULL, &len);
    768 			} else {
    769 				msg = context_serialize_answer(q, err, NULL, &len);
    770 			}
    771 		} else {
    772 			msg = context_serialize_answer(q, err, NULL, &len);
    773 		}
    774 		lock_basic_unlock(&w->ctx->cfglock);
    775 	} else {
    776 		if(reason)
    777 			q->res->why_bogus = strdup(reason);
    778 		q->res->was_ratelimited = was_ratelimited;
    779 		msg = context_serialize_answer(q, err, pkt, &len);
    780 		(void)rbtree_delete(&w->ctx->queries, q->node.key);
    781 		w->ctx->num_async--;
    782 		context_query_delete(q);
    783 	}
    784 
    785 	if(!msg) {
    786 		log_err("out of memory for async answer");
    787 		return;
    788 	}
    789 	if(!tube_queue_item(w->ctx->rr_pipe, msg, len)) {
    790 		log_err("out of memory for async answer");
    791 		return;
    792 	}
    793 }
    794 
    795 void
    796 libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
    797 	char* why_bogus, int was_ratelimited)
    798 {
    799 	struct ctx_query* q = (struct ctx_query*)arg;
    800 
    801 	if(q->cancelled || q->w->back->want_to_quit) {
    802 		if(q->w->is_bg_thread) {
    803 			/* delete it now */
    804 			struct ub_ctx* ctx = q->w->ctx;
    805 			lock_basic_lock(&ctx->cfglock);
    806 			(void)rbtree_delete(&ctx->queries, q->node.key);
    807 			ctx->num_async--;
    808 			context_query_delete(q);
    809 			lock_basic_unlock(&ctx->cfglock);
    810 		}
    811 		/* cancelled, do not give answer */
    812 		return;
    813 	}
    814 	q->msg_security = s;
    815 	if(!buf) {
    816 		buf = q->w->env->scratch_buffer;
    817 	}
    818 	if(rcode != 0) {
    819 		error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
    820 	}
    821 	add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus, was_ratelimited);
    822 }
    823 
    824 
    825 /** handle new query command for bg worker */
    826 static void
    827 handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
    828 {
    829 	uint16_t qflags, qid;
    830 	struct query_info qinfo;
    831 	struct edns_data edns;
    832 	struct ctx_query* q;
    833 	if(w->is_bg_thread) {
    834 		lock_basic_lock(&w->ctx->cfglock);
    835 		q = context_lookup_new_query(w->ctx, buf, len);
    836 		lock_basic_unlock(&w->ctx->cfglock);
    837 	} else {
    838 		q = context_deserialize_new_query(w->ctx, buf, len);
    839 	}
    840 	free(buf);
    841 	if(!q) {
    842 		log_err("failed to deserialize newq");
    843 		return;
    844 	}
    845 	if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
    846 		add_bg_result(w, q, NULL, UB_SYNTAX, NULL, 0);
    847 		return;
    848 	}
    849 	qid = 0;
    850 	qflags = BIT_RD;
    851 	/* see if there is a fixed answer */
    852 	sldns_buffer_write_u16_at(w->back->udp_buff, 0, qid);
    853 	sldns_buffer_write_u16_at(w->back->udp_buff, 2, qflags);
    854 	if(local_zones_answer(w->ctx->local_zones, w->env, &qinfo, &edns,
    855 		w->back->udp_buff, w->env->scratch, NULL, NULL, 0, NULL, 0,
    856 		NULL, 0, NULL, 0, NULL)) {
    857 		regional_free_all(w->env->scratch);
    858 		q->msg_security = sec_status_insecure;
    859 		add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
    860 		free(qinfo.qname);
    861 		return;
    862 	}
    863 	if(w->ctx->env->auth_zones && auth_zones_downstream_answer(
    864 		w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
    865 		w->back->udp_buff, w->env->scratch)) {
    866 		regional_free_all(w->env->scratch);
    867 		q->msg_security = sec_status_insecure;
    868 		add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
    869 		free(qinfo.qname);
    870 		return;
    871 	}
    872 	q->w = w;
    873 	/* process new query */
    874 	if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
    875 		w->back->udp_buff, qid, libworker_bg_done_cb, q, 0,
    876 		&q->unique_info)) {
    877 		add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
    878 	}
    879 	free(qinfo.qname);
    880 }
    881 
    882 void libworker_alloc_cleanup(void* arg)
    883 {
    884 	struct libworker* w = (struct libworker*)arg;
    885 	slabhash_clear(&w->env->rrset_cache->table);
    886         slabhash_clear(w->env->msg_cache);
    887 }
    888 
    889 struct outbound_entry* libworker_send_query(struct query_info* qinfo,
    890 	uint16_t flags, int dnssec, int want_dnssec, int nocaps,
    891 	int check_ratelimit,
    892 	struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
    893 	size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
    894 	struct module_qstate* q, int* was_ratelimited,
    895 	int* ratelimit_incremented)
    896 {
    897 	struct libworker* w = (struct libworker*)q->env->worker;
    898 	struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
    899 		q->region, sizeof(*e));
    900 	if(!e)
    901 		return NULL;
    902 	e->qstate = q;
    903 	e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
    904 		want_dnssec, nocaps, check_ratelimit, tcp_upstream, ssl_upstream,
    905 		tls_auth_name, addr, addrlen, zone, zonelen, q,
    906 		libworker_handle_service_reply, e, w->back->udp_buff, q->env,
    907 		was_ratelimited, ratelimit_incremented);
    908 	if(!e->qsent) {
    909 		return NULL;
    910 	}
    911 	return e;
    912 }
    913 
    914 int
    915 libworker_handle_service_reply(struct comm_point* c, void* arg, int error,
    916         struct comm_reply* reply_info)
    917 {
    918 	struct outbound_entry* e = (struct outbound_entry*)arg;
    919 	struct libworker* lw = (struct libworker*)e->qstate->env->worker;
    920 
    921 	if(error != 0) {
    922 		mesh_report_reply(lw->env->mesh, e, reply_info, error);
    923 		return 0;
    924 	}
    925 	/* sanity check. */
    926 	if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
    927 		|| LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
    928 			LDNS_PACKET_QUERY
    929 		|| LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
    930 		/* error becomes timeout for the module as if this reply
    931 		 * never arrived. */
    932 		mesh_report_reply(lw->env->mesh, e, reply_info,
    933 			NETEVENT_TIMEOUT);
    934 		return 0;
    935 	}
    936 	mesh_report_reply(lw->env->mesh,  e, reply_info, NETEVENT_NOERROR);
    937 	return 0;
    938 }
    939 
    940 /* --- fake callbacks for fptr_wlist to work --- */
    941 void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
    942 	uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
    943 	int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
    944 {
    945 	log_assert(0);
    946 }
    947 
    948 int worker_handle_request(struct comm_point* ATTR_UNUSED(c),
    949 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
    950         struct comm_reply* ATTR_UNUSED(repinfo))
    951 {
    952 	log_assert(0);
    953 	return 0;
    954 }
    955 
    956 int worker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
    957 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
    958         struct comm_reply* ATTR_UNUSED(reply_info))
    959 {
    960 	log_assert(0);
    961 	return 0;
    962 }
    963 
    964 int remote_accept_callback(struct comm_point* ATTR_UNUSED(c),
    965 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
    966         struct comm_reply* ATTR_UNUSED(repinfo))
    967 {
    968 	log_assert(0);
    969 	return 0;
    970 }
    971 
    972 int remote_control_callback(struct comm_point* ATTR_UNUSED(c),
    973 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
    974         struct comm_reply* ATTR_UNUSED(repinfo))
    975 {
    976 	log_assert(0);
    977 	return 0;
    978 }
    979 
    980 void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
    981 {
    982 	log_assert(0);
    983 }
    984 
    985 struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
    986 	uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
    987 	int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
    988 	int ATTR_UNUSED(check_ratelimit),
    989 	struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
    990 	uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
    991 	int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
    992 	struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited),
    993 	int* ATTR_UNUSED(ratelimit_incremented))
    994 {
    995 	log_assert(0);
    996 	return 0;
    997 }
    998 
    999 void
   1000 worker_alloc_cleanup(void* ATTR_UNUSED(arg))
   1001 {
   1002 	log_assert(0);
   1003 }
   1004 
   1005 void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
   1006 {
   1007 	log_assert(0);
   1008 }
   1009 
   1010 void worker_probe_timer_cb(void* ATTR_UNUSED(arg))
   1011 {
   1012 	log_assert(0);
   1013 }
   1014 
   1015 void worker_start_accept(void* ATTR_UNUSED(arg))
   1016 {
   1017 	log_assert(0);
   1018 }
   1019 
   1020 void worker_stop_accept(void* ATTR_UNUSED(arg))
   1021 {
   1022 	log_assert(0);
   1023 }
   1024 
   1025 int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
   1026 {
   1027 	log_assert(0);
   1028 	return 0;
   1029 }
   1030 
   1031 int
   1032 codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
   1033 {
   1034 	log_assert(0);
   1035 	return 0;
   1036 }
   1037 
   1038 int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
   1039 {
   1040         log_assert(0);
   1041         return 0;
   1042 }
   1043 
   1044 void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
   1045 {
   1046         log_assert(0);
   1047 }
   1048 
   1049 #ifdef UB_ON_WINDOWS
   1050 void
   1051 worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void*
   1052         ATTR_UNUSED(arg)) {
   1053         log_assert(0);
   1054 }
   1055 
   1056 void
   1057 wsvc_cron_cb(void* ATTR_UNUSED(arg))
   1058 {
   1059         log_assert(0);
   1060 }
   1061 #endif /* UB_ON_WINDOWS */
   1062 
   1063 #ifdef USE_DNSTAP
   1064 void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
   1065 	void* ATTR_UNUSED(arg))
   1066 {
   1067 	log_assert(0);
   1068 }
   1069 #endif
   1070 
   1071 #ifdef USE_DNSTAP
   1072 void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
   1073 	void* ATTR_UNUSED(arg))
   1074 {
   1075 	log_assert(0);
   1076 }
   1077 #endif
   1078 
   1079 void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
   1080 	void* ATTR_UNUSED(arg))
   1081 {
   1082 	log_assert(0);
   1083 }
   1084 
   1085 int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c),
   1086 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
   1087         struct comm_reply* ATTR_UNUSED(repinfo))
   1088 {
   1089 	log_assert(0);
   1090 	return 0;
   1091 }
   1092 
   1093 #ifdef HAVE_NGTCP2
   1094 void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
   1095 	void* ATTR_UNUSED(arg))
   1096 {
   1097 	log_assert(0);
   1098 }
   1099 #endif
   1100 
   1101 #ifdef HAVE_NGTCP2
   1102 void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
   1103 	void* ATTR_UNUSED(arg))
   1104 {
   1105 	log_assert(0);
   1106 }
   1107 #endif
   1108