libunbound.c revision 307729
1/*
2 * unbound.c - unbound validating resolver public API implementation
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 functions to resolve DNS queries and
40 * validate the answers. Synchonously and asynchronously.
41 *
42 */
43
44/* include the public api first, it should be able to stand alone */
45#include "libunbound/unbound.h"
46#include "libunbound/unbound-event.h"
47#include "config.h"
48#include <ctype.h>
49#include "libunbound/context.h"
50#include "libunbound/libworker.h"
51#include "util/locks.h"
52#include "util/config_file.h"
53#include "util/alloc.h"
54#include "util/module.h"
55#include "util/regional.h"
56#include "util/log.h"
57#include "util/random.h"
58#include "util/net_help.h"
59#include "util/tube.h"
60#include "util/ub_event.h"
61#include "services/modstack.h"
62#include "services/localzone.h"
63#include "services/cache/infra.h"
64#include "services/cache/rrset.h"
65#include "sldns/sbuffer.h"
66#ifdef HAVE_PTHREAD
67#include <signal.h>
68#endif
69#ifdef HAVE_SYS_WAIT_H
70#include <sys/wait.h>
71#endif
72#ifdef HAVE_TIME_H
73#include <time.h>
74#endif
75
76#if defined(UB_ON_WINDOWS) && defined (HAVE_WINDOWS_H)
77#include <windows.h>
78#include <iphlpapi.h>
79#endif /* UB_ON_WINDOWS */
80
81/** create context functionality, but no pipes */
82static struct ub_ctx* ub_ctx_create_nopipe(void)
83{
84	struct ub_ctx* ctx;
85	unsigned int seed;
86#ifdef USE_WINSOCK
87	int r;
88	WSADATA wsa_data;
89#endif
90
91	log_init(NULL, 0, NULL); /* logs to stderr */
92	log_ident_set("libunbound");
93#ifdef USE_WINSOCK
94	if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
95		log_err("could not init winsock. WSAStartup: %s",
96			wsa_strerror(r));
97		return NULL;
98	}
99#endif
100	verbosity = 0; /* errors only */
101	checklock_start();
102	ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
103	if(!ctx) {
104		errno = ENOMEM;
105		return NULL;
106	}
107	alloc_init(&ctx->superalloc, NULL, 0);
108	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
109	if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
110		seed = 0;
111		ub_randfree(ctx->seed_rnd);
112		free(ctx);
113		errno = ENOMEM;
114		return NULL;
115	}
116	seed = 0;
117	lock_basic_init(&ctx->qqpipe_lock);
118	lock_basic_init(&ctx->rrpipe_lock);
119	lock_basic_init(&ctx->cfglock);
120	ctx->env = (struct module_env*)calloc(1, sizeof(*ctx->env));
121	if(!ctx->env) {
122		ub_randfree(ctx->seed_rnd);
123		free(ctx);
124		errno = ENOMEM;
125		return NULL;
126	}
127	ctx->env->cfg = config_create_forlib();
128	if(!ctx->env->cfg) {
129		free(ctx->env);
130		ub_randfree(ctx->seed_rnd);
131		free(ctx);
132		errno = ENOMEM;
133		return NULL;
134	}
135	ctx->env->alloc = &ctx->superalloc;
136	ctx->env->worker = NULL;
137	ctx->env->need_to_validate = 0;
138	modstack_init(&ctx->mods);
139	rbtree_init(&ctx->queries, &context_query_cmp);
140	return ctx;
141}
142
143struct ub_ctx*
144ub_ctx_create(void)
145{
146	struct ub_ctx* ctx = ub_ctx_create_nopipe();
147	if(!ctx)
148		return NULL;
149	if((ctx->qq_pipe = tube_create()) == NULL) {
150		int e = errno;
151		ub_randfree(ctx->seed_rnd);
152		config_delete(ctx->env->cfg);
153		modstack_desetup(&ctx->mods, ctx->env);
154		free(ctx->env);
155		free(ctx);
156		errno = e;
157		return NULL;
158	}
159	if((ctx->rr_pipe = tube_create()) == NULL) {
160		int e = errno;
161		tube_delete(ctx->qq_pipe);
162		ub_randfree(ctx->seed_rnd);
163		config_delete(ctx->env->cfg);
164		modstack_desetup(&ctx->mods, ctx->env);
165		free(ctx->env);
166		free(ctx);
167		errno = e;
168		return NULL;
169	}
170	return ctx;
171}
172
173struct ub_ctx*
174ub_ctx_create_ub_event(struct ub_event_base* ueb)
175{
176	struct ub_ctx* ctx = ub_ctx_create_nopipe();
177	if(!ctx)
178		return NULL;
179	/* no pipes, but we have the locks to make sure everything works */
180	ctx->created_bg = 0;
181	ctx->dothread = 1; /* the processing is in the same process,
182		makes ub_cancel and ub_ctx_delete do the right thing */
183	ctx->event_base = ueb;
184	return ctx;
185}
186
187struct ub_ctx*
188ub_ctx_create_event(struct event_base* eb)
189{
190	struct ub_ctx* ctx = ub_ctx_create_nopipe();
191	if(!ctx)
192		return NULL;
193	/* no pipes, but we have the locks to make sure everything works */
194	ctx->created_bg = 0;
195	ctx->dothread = 1; /* the processing is in the same process,
196		makes ub_cancel and ub_ctx_delete do the right thing */
197	ctx->event_base = ub_libevent_event_base(eb);
198	if (!ctx->event_base) {
199		ub_ctx_delete(ctx);
200		return NULL;
201	}
202	return ctx;
203}
204
205/** delete q */
206static void
207delq(rbnode_t* n, void* ATTR_UNUSED(arg))
208{
209	struct ctx_query* q = (struct ctx_query*)n;
210	context_query_delete(q);
211}
212
213/** stop the bg thread */
214static void ub_stop_bg(struct ub_ctx* ctx)
215{
216	/* stop the bg thread */
217	lock_basic_lock(&ctx->cfglock);
218	if(ctx->created_bg) {
219		uint8_t* msg;
220		uint32_t len;
221		uint32_t cmd = UB_LIBCMD_QUIT;
222		lock_basic_unlock(&ctx->cfglock);
223		lock_basic_lock(&ctx->qqpipe_lock);
224		(void)tube_write_msg(ctx->qq_pipe, (uint8_t*)&cmd,
225			(uint32_t)sizeof(cmd), 0);
226		lock_basic_unlock(&ctx->qqpipe_lock);
227		lock_basic_lock(&ctx->rrpipe_lock);
228		while(tube_read_msg(ctx->rr_pipe, &msg, &len, 0)) {
229			/* discard all results except a quit confirm */
230			if(context_serial_getcmd(msg, len) == UB_LIBCMD_QUIT) {
231				free(msg);
232				break;
233			}
234			free(msg);
235		}
236		lock_basic_unlock(&ctx->rrpipe_lock);
237
238		/* if bg worker is a thread, wait for it to exit, so that all
239	 	 * resources are really gone. */
240		lock_basic_lock(&ctx->cfglock);
241		if(ctx->dothread) {
242			lock_basic_unlock(&ctx->cfglock);
243			ub_thread_join(ctx->bg_tid);
244		} else {
245			lock_basic_unlock(&ctx->cfglock);
246#ifndef UB_ON_WINDOWS
247			if(waitpid(ctx->bg_pid, NULL, 0) == -1) {
248				if(verbosity > 2)
249					log_err("waitpid: %s", strerror(errno));
250			}
251#endif
252		}
253	}
254	else {
255		lock_basic_unlock(&ctx->cfglock);
256	}
257}
258
259void
260ub_ctx_delete(struct ub_ctx* ctx)
261{
262	struct alloc_cache* a, *na;
263	int do_stop = 1;
264	if(!ctx) return;
265
266	/* see if bg thread is created and if threads have been killed */
267	/* no locks, because those may be held by terminated threads */
268	/* for processes the read pipe is closed and we see that on read */
269#ifdef HAVE_PTHREAD
270	if(ctx->created_bg && ctx->dothread) {
271		if(pthread_kill(ctx->bg_tid, 0) == ESRCH) {
272			/* thread has been killed */
273			do_stop = 0;
274		}
275	}
276#endif /* HAVE_PTHREAD */
277	if(do_stop)
278		ub_stop_bg(ctx);
279	libworker_delete_event(ctx->event_worker);
280
281	modstack_desetup(&ctx->mods, ctx->env);
282	a = ctx->alloc_list;
283	while(a) {
284		na = a->super;
285		a->super = &ctx->superalloc;
286		alloc_clear(a);
287		free(a);
288		a = na;
289	}
290	local_zones_delete(ctx->local_zones);
291	lock_basic_destroy(&ctx->qqpipe_lock);
292	lock_basic_destroy(&ctx->rrpipe_lock);
293	lock_basic_destroy(&ctx->cfglock);
294	tube_delete(ctx->qq_pipe);
295	tube_delete(ctx->rr_pipe);
296	if(ctx->env) {
297		slabhash_delete(ctx->env->msg_cache);
298		rrset_cache_delete(ctx->env->rrset_cache);
299		infra_delete(ctx->env->infra_cache);
300		config_delete(ctx->env->cfg);
301		free(ctx->env);
302	}
303	ub_randfree(ctx->seed_rnd);
304	alloc_clear(&ctx->superalloc);
305	traverse_postorder(&ctx->queries, delq, NULL);
306	free(ctx);
307#ifdef USE_WINSOCK
308	WSACleanup();
309#endif
310}
311
312int
313ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val)
314{
315	lock_basic_lock(&ctx->cfglock);
316	if(ctx->finalized) {
317		lock_basic_unlock(&ctx->cfglock);
318		return UB_AFTERFINAL;
319	}
320	if(!config_set_option(ctx->env->cfg, opt, val)) {
321		lock_basic_unlock(&ctx->cfglock);
322		return UB_SYNTAX;
323	}
324	lock_basic_unlock(&ctx->cfglock);
325	return UB_NOERROR;
326}
327
328int
329ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str)
330{
331	int r;
332	lock_basic_lock(&ctx->cfglock);
333	r = config_get_option_collate(ctx->env->cfg, opt, str);
334	lock_basic_unlock(&ctx->cfglock);
335	if(r == 0) r = UB_NOERROR;
336	else if(r == 1) r = UB_SYNTAX;
337	else if(r == 2) r = UB_NOMEM;
338	return r;
339}
340
341int
342ub_ctx_config(struct ub_ctx* ctx, const char* fname)
343{
344	lock_basic_lock(&ctx->cfglock);
345	if(ctx->finalized) {
346		lock_basic_unlock(&ctx->cfglock);
347		return UB_AFTERFINAL;
348	}
349	if(!config_read(ctx->env->cfg, fname, NULL)) {
350		lock_basic_unlock(&ctx->cfglock);
351		return UB_SYNTAX;
352	}
353	lock_basic_unlock(&ctx->cfglock);
354	return UB_NOERROR;
355}
356
357int
358ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta)
359{
360	char* dup = strdup(ta);
361	if(!dup) return UB_NOMEM;
362	lock_basic_lock(&ctx->cfglock);
363	if(ctx->finalized) {
364		lock_basic_unlock(&ctx->cfglock);
365		free(dup);
366		return UB_AFTERFINAL;
367	}
368	if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
369		lock_basic_unlock(&ctx->cfglock);
370		free(dup);
371		return UB_NOMEM;
372	}
373	lock_basic_unlock(&ctx->cfglock);
374	return UB_NOERROR;
375}
376
377int
378ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
379{
380	char* dup = strdup(fname);
381	if(!dup) return UB_NOMEM;
382	lock_basic_lock(&ctx->cfglock);
383	if(ctx->finalized) {
384		lock_basic_unlock(&ctx->cfglock);
385		free(dup);
386		return UB_AFTERFINAL;
387	}
388	if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) {
389		lock_basic_unlock(&ctx->cfglock);
390		free(dup);
391		return UB_NOMEM;
392	}
393	lock_basic_unlock(&ctx->cfglock);
394	return UB_NOERROR;
395}
396
397int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
398{
399	char* dup = strdup(fname);
400	if(!dup) return UB_NOMEM;
401	lock_basic_lock(&ctx->cfglock);
402	if(ctx->finalized) {
403		lock_basic_unlock(&ctx->cfglock);
404		free(dup);
405		return UB_AFTERFINAL;
406	}
407	if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
408		dup)) {
409		lock_basic_unlock(&ctx->cfglock);
410		free(dup);
411		return UB_NOMEM;
412	}
413	lock_basic_unlock(&ctx->cfglock);
414	return UB_NOERROR;
415}
416
417int
418ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
419{
420	char* dup = strdup(fname);
421	if(!dup) return UB_NOMEM;
422	lock_basic_lock(&ctx->cfglock);
423	if(ctx->finalized) {
424		lock_basic_unlock(&ctx->cfglock);
425		free(dup);
426		return UB_AFTERFINAL;
427	}
428	if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
429		lock_basic_unlock(&ctx->cfglock);
430		free(dup);
431		return UB_NOMEM;
432	}
433	lock_basic_unlock(&ctx->cfglock);
434	return UB_NOERROR;
435}
436
437int
438ub_ctx_debuglevel(struct ub_ctx* ctx, int d)
439{
440	lock_basic_lock(&ctx->cfglock);
441	verbosity = d;
442	ctx->env->cfg->verbosity = d;
443	lock_basic_unlock(&ctx->cfglock);
444	return UB_NOERROR;
445}
446
447int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
448{
449	lock_basic_lock(&ctx->cfglock);
450	log_file((FILE*)out);
451	ctx->logfile_override = 1;
452	ctx->log_out = out;
453	lock_basic_unlock(&ctx->cfglock);
454	return UB_NOERROR;
455}
456
457int
458ub_ctx_async(struct ub_ctx* ctx, int dothread)
459{
460#ifdef THREADS_DISABLED
461	if(dothread) /* cannot do threading */
462		return UB_NOERROR;
463#endif
464	lock_basic_lock(&ctx->cfglock);
465	if(ctx->finalized) {
466		lock_basic_unlock(&ctx->cfglock);
467		return UB_AFTERFINAL;
468	}
469	ctx->dothread = dothread;
470	lock_basic_unlock(&ctx->cfglock);
471	return UB_NOERROR;
472}
473
474int
475ub_poll(struct ub_ctx* ctx)
476{
477	/* no need to hold lock while testing for readability. */
478	return tube_poll(ctx->rr_pipe);
479}
480
481int
482ub_fd(struct ub_ctx* ctx)
483{
484	return tube_read_fd(ctx->rr_pipe);
485}
486
487/** process answer from bg worker */
488static int
489process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
490	ub_callback_t* cb, void** cbarg, int* err,
491	struct ub_result** res)
492{
493	struct ctx_query* q;
494	if(context_serial_getcmd(msg, len) != UB_LIBCMD_ANSWER) {
495		log_err("error: bad data from bg worker %d",
496			(int)context_serial_getcmd(msg, len));
497		return 0;
498	}
499
500	lock_basic_lock(&ctx->cfglock);
501	q = context_deserialize_answer(ctx, msg, len, err);
502	if(!q) {
503		lock_basic_unlock(&ctx->cfglock);
504		/* probably simply the lookup that failed, i.e.
505		 * response returned before cancel was sent out, so noerror */
506		return 1;
507	}
508	log_assert(q->async);
509
510	/* grab cb while locked */
511	if(q->cancelled) {
512		*cb = NULL;
513		*cbarg = NULL;
514	} else {
515		*cb = q->cb;
516		*cbarg = q->cb_arg;
517	}
518	if(*err) {
519		*res = NULL;
520		ub_resolve_free(q->res);
521	} else {
522		/* parse the message, extract rcode, fill result */
523		sldns_buffer* buf = sldns_buffer_new(q->msg_len);
524		struct regional* region = regional_create();
525		*res = q->res;
526		(*res)->rcode = LDNS_RCODE_SERVFAIL;
527		if(region && buf) {
528			sldns_buffer_clear(buf);
529			sldns_buffer_write(buf, q->msg, q->msg_len);
530			sldns_buffer_flip(buf);
531			libworker_enter_result(*res, buf, region,
532				q->msg_security);
533		}
534		(*res)->answer_packet = q->msg;
535		(*res)->answer_len = (int)q->msg_len;
536		q->msg = NULL;
537		sldns_buffer_free(buf);
538		regional_destroy(region);
539	}
540	q->res = NULL;
541	/* delete the q from list */
542	(void)rbtree_delete(&ctx->queries, q->node.key);
543	ctx->num_async--;
544	context_query_delete(q);
545	lock_basic_unlock(&ctx->cfglock);
546
547	if(*cb) return 2;
548	ub_resolve_free(*res);
549	return 1;
550}
551
552/** process answer from bg worker */
553static int
554process_answer(struct ub_ctx* ctx, uint8_t* msg, uint32_t len)
555{
556	int err;
557	ub_callback_t cb;
558	void* cbarg;
559	struct ub_result* res;
560	int r;
561
562	r = process_answer_detail(ctx, msg, len, &cb, &cbarg, &err, &res);
563
564	/* no locks held while calling callback, so that library is
565	 * re-entrant. */
566	if(r == 2)
567		(*cb)(cbarg, err, res);
568
569	return r;
570}
571
572int
573ub_process(struct ub_ctx* ctx)
574{
575	int r;
576	uint8_t* msg;
577	uint32_t len;
578	while(1) {
579		msg = NULL;
580		lock_basic_lock(&ctx->rrpipe_lock);
581		r = tube_read_msg(ctx->rr_pipe, &msg, &len, 1);
582		lock_basic_unlock(&ctx->rrpipe_lock);
583		if(r == 0)
584			return UB_PIPE;
585		else if(r == -1)
586			break;
587		if(!process_answer(ctx, msg, len)) {
588			free(msg);
589			return UB_PIPE;
590		}
591		free(msg);
592	}
593	return UB_NOERROR;
594}
595
596int
597ub_wait(struct ub_ctx* ctx)
598{
599	int err;
600	ub_callback_t cb;
601	void* cbarg;
602	struct ub_result* res;
603	int r;
604	uint8_t* msg;
605	uint32_t len;
606	/* this is basically the same loop as _process(), but with changes.
607	 * holds the rrpipe lock and waits with tube_wait */
608	while(1) {
609		lock_basic_lock(&ctx->rrpipe_lock);
610		lock_basic_lock(&ctx->cfglock);
611		if(ctx->num_async == 0) {
612			lock_basic_unlock(&ctx->cfglock);
613			lock_basic_unlock(&ctx->rrpipe_lock);
614			break;
615		}
616		lock_basic_unlock(&ctx->cfglock);
617
618		/* keep rrpipe locked, while
619		 * 	o waiting for pipe readable
620		 * 	o parsing message
621		 * 	o possibly decrementing num_async
622		 * do callback without lock
623		 */
624		r = tube_wait(ctx->rr_pipe);
625		if(r) {
626			r = tube_read_msg(ctx->rr_pipe, &msg, &len, 1);
627			if(r == 0) {
628				lock_basic_unlock(&ctx->rrpipe_lock);
629				return UB_PIPE;
630			}
631			if(r == -1) {
632				lock_basic_unlock(&ctx->rrpipe_lock);
633				continue;
634			}
635			r = process_answer_detail(ctx, msg, len,
636				&cb, &cbarg, &err, &res);
637			lock_basic_unlock(&ctx->rrpipe_lock);
638			free(msg);
639			if(r == 0)
640				return UB_PIPE;
641			if(r == 2)
642				(*cb)(cbarg, err, res);
643		} else {
644			lock_basic_unlock(&ctx->rrpipe_lock);
645		}
646	}
647	return UB_NOERROR;
648}
649
650int
651ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
652	int rrclass, struct ub_result** result)
653{
654	struct ctx_query* q;
655	int r;
656	*result = NULL;
657
658	lock_basic_lock(&ctx->cfglock);
659	if(!ctx->finalized) {
660		r = context_finalize(ctx);
661		if(r) {
662			lock_basic_unlock(&ctx->cfglock);
663			return r;
664		}
665	}
666	/* create new ctx_query and attempt to add to the list */
667	lock_basic_unlock(&ctx->cfglock);
668	q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
669	if(!q)
670		return UB_NOMEM;
671	/* become a resolver thread for a bit */
672
673	r = libworker_fg(ctx, q);
674	if(r) {
675		lock_basic_lock(&ctx->cfglock);
676		(void)rbtree_delete(&ctx->queries, q->node.key);
677		context_query_delete(q);
678		lock_basic_unlock(&ctx->cfglock);
679		return r;
680	}
681	q->res->answer_packet = q->msg;
682	q->res->answer_len = (int)q->msg_len;
683	q->msg = NULL;
684	*result = q->res;
685	q->res = NULL;
686
687	lock_basic_lock(&ctx->cfglock);
688	(void)rbtree_delete(&ctx->queries, q->node.key);
689	context_query_delete(q);
690	lock_basic_unlock(&ctx->cfglock);
691	return UB_NOERROR;
692}
693
694int
695ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
696	int rrclass, void* mydata, ub_event_callback_t callback, int* async_id)
697{
698	struct ctx_query* q;
699	int r;
700
701	if(async_id)
702		*async_id = 0;
703	lock_basic_lock(&ctx->cfglock);
704	if(!ctx->finalized) {
705		int r = context_finalize(ctx);
706		if(r) {
707			lock_basic_unlock(&ctx->cfglock);
708			return r;
709		}
710	}
711	lock_basic_unlock(&ctx->cfglock);
712	if(!ctx->event_worker) {
713		ctx->event_worker = libworker_create_event(ctx,
714			ctx->event_base);
715		if(!ctx->event_worker) {
716			return UB_INITFAIL;
717		}
718	}
719
720	/* set time in case answer comes from cache */
721	ub_comm_base_now(ctx->event_worker->base);
722
723	/* create new ctx_query and attempt to add to the list */
724	q = context_new(ctx, name, rrtype, rrclass, (ub_callback_t)callback,
725		mydata);
726	if(!q)
727		return UB_NOMEM;
728
729	/* attach to mesh */
730	if((r=libworker_attach_mesh(ctx, q, async_id)) != 0)
731		return r;
732	return UB_NOERROR;
733}
734
735
736int
737ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
738	int rrclass, void* mydata, ub_callback_t callback, int* async_id)
739{
740	struct ctx_query* q;
741	uint8_t* msg = NULL;
742	uint32_t len = 0;
743
744	if(async_id)
745		*async_id = 0;
746	lock_basic_lock(&ctx->cfglock);
747	if(!ctx->finalized) {
748		int r = context_finalize(ctx);
749		if(r) {
750			lock_basic_unlock(&ctx->cfglock);
751			return r;
752		}
753	}
754	if(!ctx->created_bg) {
755		int r;
756		ctx->created_bg = 1;
757		lock_basic_unlock(&ctx->cfglock);
758		r = libworker_bg(ctx);
759		if(r) {
760			lock_basic_lock(&ctx->cfglock);
761			ctx->created_bg = 0;
762			lock_basic_unlock(&ctx->cfglock);
763			return r;
764		}
765	} else {
766		lock_basic_unlock(&ctx->cfglock);
767	}
768
769	/* create new ctx_query and attempt to add to the list */
770	q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
771	if(!q)
772		return UB_NOMEM;
773
774	/* write over pipe to background worker */
775	lock_basic_lock(&ctx->cfglock);
776	msg = context_serialize_new_query(q, &len);
777	if(!msg) {
778		(void)rbtree_delete(&ctx->queries, q->node.key);
779		ctx->num_async--;
780		context_query_delete(q);
781		lock_basic_unlock(&ctx->cfglock);
782		return UB_NOMEM;
783	}
784	if(async_id)
785		*async_id = q->querynum;
786	lock_basic_unlock(&ctx->cfglock);
787
788	lock_basic_lock(&ctx->qqpipe_lock);
789	if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) {
790		lock_basic_unlock(&ctx->qqpipe_lock);
791		free(msg);
792		return UB_PIPE;
793	}
794	lock_basic_unlock(&ctx->qqpipe_lock);
795	free(msg);
796	return UB_NOERROR;
797}
798
799int
800ub_cancel(struct ub_ctx* ctx, int async_id)
801{
802	struct ctx_query* q;
803	uint8_t* msg = NULL;
804	uint32_t len = 0;
805	lock_basic_lock(&ctx->cfglock);
806	q = (struct ctx_query*)rbtree_search(&ctx->queries, &async_id);
807	if(!q || !q->async) {
808		/* it is not there, so nothing to do */
809		lock_basic_unlock(&ctx->cfglock);
810		return UB_NOID;
811	}
812	log_assert(q->async);
813	q->cancelled = 1;
814
815	/* delete it */
816	if(!ctx->dothread) { /* if forked */
817		(void)rbtree_delete(&ctx->queries, q->node.key);
818		ctx->num_async--;
819		msg = context_serialize_cancel(q, &len);
820		context_query_delete(q);
821		lock_basic_unlock(&ctx->cfglock);
822		if(!msg) {
823			return UB_NOMEM;
824		}
825		/* send cancel to background worker */
826		lock_basic_lock(&ctx->qqpipe_lock);
827		if(!tube_write_msg(ctx->qq_pipe, msg, len, 0)) {
828			lock_basic_unlock(&ctx->qqpipe_lock);
829			free(msg);
830			return UB_PIPE;
831		}
832		lock_basic_unlock(&ctx->qqpipe_lock);
833		free(msg);
834	} else {
835		lock_basic_unlock(&ctx->cfglock);
836	}
837	return UB_NOERROR;
838}
839
840void
841ub_resolve_free(struct ub_result* result)
842{
843	char** p;
844	if(!result) return;
845	free(result->qname);
846	if(result->canonname != result->qname)
847		free(result->canonname);
848	if(result->data)
849		for(p = result->data; *p; p++)
850			free(*p);
851	free(result->data);
852	free(result->len);
853	free(result->answer_packet);
854	free(result->why_bogus);
855	free(result);
856}
857
858const char*
859ub_strerror(int err)
860{
861	switch(err) {
862		case UB_NOERROR: return "no error";
863		case UB_SOCKET: return "socket io error";
864		case UB_NOMEM: return "out of memory";
865		case UB_SYNTAX: return "syntax error";
866		case UB_SERVFAIL: return "server failure";
867		case UB_FORKFAIL: return "could not fork";
868		case UB_INITFAIL: return "initialization failure";
869		case UB_AFTERFINAL: return "setting change after finalize";
870		case UB_PIPE: return "error in pipe communication with async";
871		case UB_READFILE: return "error reading file";
872		case UB_NOID: return "error async_id does not exist";
873		default: return "unknown error";
874	}
875}
876
877int
878ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
879{
880	struct sockaddr_storage storage;
881	socklen_t stlen;
882	struct config_stub* s;
883	char* dupl;
884	lock_basic_lock(&ctx->cfglock);
885	if(ctx->finalized) {
886		lock_basic_unlock(&ctx->cfglock);
887		errno=EINVAL;
888		return UB_AFTERFINAL;
889	}
890	if(!addr) {
891		/* disable fwd mode - the root stub should be first. */
892		if(ctx->env->cfg->forwards &&
893			strcmp(ctx->env->cfg->forwards->name, ".") == 0) {
894			s = ctx->env->cfg->forwards;
895			ctx->env->cfg->forwards = s->next;
896			s->next = NULL;
897			config_delstubs(s);
898		}
899		lock_basic_unlock(&ctx->cfglock);
900		return UB_NOERROR;
901	}
902	lock_basic_unlock(&ctx->cfglock);
903
904	/* check syntax for addr */
905	if(!extstrtoaddr(addr, &storage, &stlen)) {
906		errno=EINVAL;
907		return UB_SYNTAX;
908	}
909
910	/* it parses, add root stub in front of list */
911	lock_basic_lock(&ctx->cfglock);
912	if(!ctx->env->cfg->forwards ||
913		strcmp(ctx->env->cfg->forwards->name, ".") != 0) {
914		s = calloc(1, sizeof(*s));
915		if(!s) {
916			lock_basic_unlock(&ctx->cfglock);
917			errno=ENOMEM;
918			return UB_NOMEM;
919		}
920		s->name = strdup(".");
921		if(!s->name) {
922			free(s);
923			lock_basic_unlock(&ctx->cfglock);
924			errno=ENOMEM;
925			return UB_NOMEM;
926		}
927		s->next = ctx->env->cfg->forwards;
928		ctx->env->cfg->forwards = s;
929	} else {
930		log_assert(ctx->env->cfg->forwards);
931		s = ctx->env->cfg->forwards;
932	}
933	dupl = strdup(addr);
934	if(!dupl) {
935		lock_basic_unlock(&ctx->cfglock);
936		errno=ENOMEM;
937		return UB_NOMEM;
938	}
939	if(!cfg_strlist_insert(&s->addrs, dupl)) {
940		free(dupl);
941		lock_basic_unlock(&ctx->cfglock);
942		errno=ENOMEM;
943		return UB_NOMEM;
944	}
945	lock_basic_unlock(&ctx->cfglock);
946	return UB_NOERROR;
947}
948
949int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
950	int isprime)
951{
952	char* a;
953	struct config_stub **prev, *elem;
954
955	/* check syntax for zone name */
956	if(zone) {
957		uint8_t* nm;
958		int nmlabs;
959		size_t nmlen;
960		if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) {
961			errno=EINVAL;
962			return UB_SYNTAX;
963		}
964		free(nm);
965	} else {
966		zone = ".";
967	}
968
969	/* check syntax for addr (if not NULL) */
970	if(addr) {
971		struct sockaddr_storage storage;
972		socklen_t stlen;
973		if(!extstrtoaddr(addr, &storage, &stlen)) {
974			errno=EINVAL;
975			return UB_SYNTAX;
976		}
977	}
978
979	lock_basic_lock(&ctx->cfglock);
980	if(ctx->finalized) {
981		lock_basic_unlock(&ctx->cfglock);
982		errno=EINVAL;
983		return UB_AFTERFINAL;
984	}
985
986	/* arguments all right, now find or add the stub */
987	prev = &ctx->env->cfg->stubs;
988	elem = cfg_stub_find(&prev, zone);
989	if(!elem && !addr) {
990		/* not found and we want to delete, nothing to do */
991		lock_basic_unlock(&ctx->cfglock);
992		return UB_NOERROR;
993	} else if(elem && !addr) {
994		/* found, and we want to delete */
995		*prev = elem->next;
996		config_delstub(elem);
997		lock_basic_unlock(&ctx->cfglock);
998		return UB_NOERROR;
999	} else if(!elem) {
1000		/* not found, create the stub entry */
1001		elem=(struct config_stub*)calloc(1, sizeof(struct config_stub));
1002		if(elem) elem->name = strdup(zone);
1003		if(!elem || !elem->name) {
1004			free(elem);
1005			lock_basic_unlock(&ctx->cfglock);
1006			errno = ENOMEM;
1007			return UB_NOMEM;
1008		}
1009		elem->next = ctx->env->cfg->stubs;
1010		ctx->env->cfg->stubs = elem;
1011	}
1012
1013	/* add the address to the list and set settings */
1014	elem->isprime = isprime;
1015	a = strdup(addr);
1016	if(!a) {
1017		lock_basic_unlock(&ctx->cfglock);
1018		errno = ENOMEM;
1019		return UB_NOMEM;
1020	}
1021	if(!cfg_strlist_insert(&elem->addrs, a)) {
1022		lock_basic_unlock(&ctx->cfglock);
1023		free(a);
1024		errno = ENOMEM;
1025		return UB_NOMEM;
1026	}
1027	lock_basic_unlock(&ctx->cfglock);
1028	return UB_NOERROR;
1029}
1030
1031int
1032ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname)
1033{
1034	FILE* in;
1035	int numserv = 0;
1036	char buf[1024];
1037	char* parse, *addr;
1038	int r;
1039
1040	if(fname == NULL) {
1041#if !defined(UB_ON_WINDOWS) || !defined(HAVE_WINDOWS_H)
1042		fname = "/etc/resolv.conf";
1043#else
1044		FIXED_INFO *info;
1045		ULONG buflen = sizeof(*info);
1046		IP_ADDR_STRING *ptr;
1047
1048		info = (FIXED_INFO *) malloc(sizeof (FIXED_INFO));
1049		if (info == NULL)
1050			return UB_READFILE;
1051
1052		if (GetNetworkParams(info, &buflen) == ERROR_BUFFER_OVERFLOW) {
1053			free(info);
1054			info = (FIXED_INFO *) malloc(buflen);
1055			if (info == NULL)
1056				return UB_READFILE;
1057		}
1058
1059		if (GetNetworkParams(info, &buflen) == NO_ERROR) {
1060			int retval=0;
1061			ptr = &(info->DnsServerList);
1062			while (ptr) {
1063				numserv++;
1064				if((retval=ub_ctx_set_fwd(ctx,
1065					ptr->IpAddress.String))!=0) {
1066					free(info);
1067					return retval;
1068				}
1069				ptr = ptr->Next;
1070			}
1071			free(info);
1072			if (numserv==0)
1073				return UB_READFILE;
1074			return UB_NOERROR;
1075		}
1076		free(info);
1077		return UB_READFILE;
1078#endif /* WINDOWS */
1079	}
1080	in = fopen(fname, "r");
1081	if(!in) {
1082		/* error in errno! perror(fname) */
1083		return UB_READFILE;
1084	}
1085	while(fgets(buf, (int)sizeof(buf), in)) {
1086		buf[sizeof(buf)-1] = 0;
1087		parse=buf;
1088		while(*parse == ' ' || *parse == '\t')
1089			parse++;
1090		if(strncmp(parse, "nameserver", 10) == 0) {
1091			numserv++;
1092			parse += 10; /* skip 'nameserver' */
1093			/* skip whitespace */
1094			while(*parse == ' ' || *parse == '\t')
1095				parse++;
1096			addr = parse;
1097			/* skip [0-9a-fA-F.:]*, i.e. IP4 and IP6 address */
1098			while(isxdigit((unsigned char)*parse) || *parse=='.' || *parse==':')
1099				parse++;
1100			/* terminate after the address, remove newline */
1101			*parse = 0;
1102
1103			if((r = ub_ctx_set_fwd(ctx, addr)) != UB_NOERROR) {
1104				fclose(in);
1105				return r;
1106			}
1107		}
1108	}
1109	fclose(in);
1110	if(numserv == 0) {
1111		/* from resolv.conf(5) if none given, use localhost */
1112		return ub_ctx_set_fwd(ctx, "127.0.0.1");
1113	}
1114	return UB_NOERROR;
1115}
1116
1117int
1118ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
1119{
1120	FILE* in;
1121	char buf[1024], ldata[1024];
1122	char* parse, *addr, *name, *ins;
1123	lock_basic_lock(&ctx->cfglock);
1124	if(ctx->finalized) {
1125		lock_basic_unlock(&ctx->cfglock);
1126		errno=EINVAL;
1127		return UB_AFTERFINAL;
1128	}
1129	lock_basic_unlock(&ctx->cfglock);
1130	if(fname == NULL) {
1131#if defined(UB_ON_WINDOWS) && defined(HAVE_WINDOWS_H)
1132		/*
1133		 * If this is Windows NT/XP/2K it's in
1134		 * %WINDIR%\system32\drivers\etc\hosts.
1135		 * If this is Windows 95/98/Me it's in %WINDIR%\hosts.
1136		 */
1137		name = getenv("WINDIR");
1138		if (name != NULL) {
1139			int retval=0;
1140			snprintf(buf, sizeof(buf), "%s%s", name,
1141				"\\system32\\drivers\\etc\\hosts");
1142			if((retval=ub_ctx_hosts(ctx, buf)) !=0 ) {
1143				snprintf(buf, sizeof(buf), "%s%s", name,
1144					"\\hosts");
1145				retval=ub_ctx_hosts(ctx, buf);
1146			}
1147			return retval;
1148		}
1149		return UB_READFILE;
1150#else
1151		fname = "/etc/hosts";
1152#endif /* WIN32 */
1153	}
1154	in = fopen(fname, "r");
1155	if(!in) {
1156		/* error in errno! perror(fname) */
1157		return UB_READFILE;
1158	}
1159	while(fgets(buf, (int)sizeof(buf), in)) {
1160		buf[sizeof(buf)-1] = 0;
1161		parse=buf;
1162		while(*parse == ' ' || *parse == '\t')
1163			parse++;
1164		if(*parse == '#')
1165			continue; /* skip comment */
1166		/* format: <addr> spaces <name> spaces <name> ... */
1167		addr = parse;
1168		/* skip addr */
1169		while(isxdigit((unsigned char)*parse) || *parse == '.' || *parse == ':')
1170			parse++;
1171		if(*parse == '\r')
1172			parse++;
1173		if(*parse == '\n' || *parse == 0)
1174			continue;
1175		if(*parse == '%')
1176			continue; /* ignore macOSX fe80::1%lo0 localhost */
1177		if(*parse != ' ' && *parse != '\t') {
1178			/* must have whitespace after address */
1179			fclose(in);
1180			errno=EINVAL;
1181			return UB_SYNTAX;
1182		}
1183		*parse++ = 0; /* end delimiter for addr ... */
1184		/* go to names and add them */
1185		while(*parse) {
1186			while(*parse == ' ' || *parse == '\t' || *parse=='\n'
1187				|| *parse=='\r')
1188				parse++;
1189			if(*parse == 0 || *parse == '#')
1190				break;
1191			/* skip name, allows (too) many printable characters */
1192			name = parse;
1193			while('!' <= *parse && *parse <= '~')
1194				parse++;
1195			if(*parse)
1196				*parse++ = 0; /* end delimiter for name */
1197			snprintf(ldata, sizeof(ldata), "%s %s %s",
1198				name, str_is_ip6(addr)?"AAAA":"A", addr);
1199			ins = strdup(ldata);
1200			if(!ins) {
1201				/* out of memory */
1202				fclose(in);
1203				errno=ENOMEM;
1204				return UB_NOMEM;
1205			}
1206			lock_basic_lock(&ctx->cfglock);
1207			if(!cfg_strlist_insert(&ctx->env->cfg->local_data,
1208				ins)) {
1209				lock_basic_unlock(&ctx->cfglock);
1210				fclose(in);
1211				free(ins);
1212				errno=ENOMEM;
1213				return UB_NOMEM;
1214			}
1215			lock_basic_unlock(&ctx->cfglock);
1216		}
1217	}
1218	fclose(in);
1219	return UB_NOERROR;
1220}
1221
1222/** finalize the context, if not already finalized */
1223static int ub_ctx_finalize(struct ub_ctx* ctx)
1224{
1225	int res = 0;
1226	lock_basic_lock(&ctx->cfglock);
1227	if (!ctx->finalized) {
1228		res = context_finalize(ctx);
1229	}
1230	lock_basic_unlock(&ctx->cfglock);
1231	return res;
1232}
1233
1234/* Print local zones and RR data */
1235int ub_ctx_print_local_zones(struct ub_ctx* ctx)
1236{
1237	int res = ub_ctx_finalize(ctx);
1238	if (res) return res;
1239
1240	local_zones_print(ctx->local_zones);
1241
1242	return UB_NOERROR;
1243}
1244
1245/* Add a new zone */
1246int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
1247	const char *zone_type)
1248{
1249	enum localzone_type t;
1250	struct local_zone* z;
1251	uint8_t* nm;
1252	int nmlabs;
1253	size_t nmlen;
1254
1255	int res = ub_ctx_finalize(ctx);
1256	if (res) return res;
1257
1258	if(!local_zone_str2type(zone_type, &t)) {
1259		return UB_SYNTAX;
1260	}
1261
1262	if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
1263		return UB_SYNTAX;
1264	}
1265
1266	lock_rw_wrlock(&ctx->local_zones->lock);
1267	if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
1268		LDNS_RR_CLASS_IN))) {
1269		/* already present in tree */
1270		lock_rw_wrlock(&z->lock);
1271		z->type = t; /* update type anyway */
1272		lock_rw_unlock(&z->lock);
1273		lock_rw_unlock(&ctx->local_zones->lock);
1274		free(nm);
1275		return UB_NOERROR;
1276	}
1277	if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
1278		LDNS_RR_CLASS_IN, t)) {
1279		lock_rw_unlock(&ctx->local_zones->lock);
1280		return UB_NOMEM;
1281	}
1282	lock_rw_unlock(&ctx->local_zones->lock);
1283	return UB_NOERROR;
1284}
1285
1286/* Remove zone */
1287int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name)
1288{
1289	struct local_zone* z;
1290	uint8_t* nm;
1291	int nmlabs;
1292	size_t nmlen;
1293
1294	int res = ub_ctx_finalize(ctx);
1295	if (res) return res;
1296
1297	if(!parse_dname(zone_name, &nm, &nmlen, &nmlabs)) {
1298		return UB_SYNTAX;
1299	}
1300
1301	lock_rw_wrlock(&ctx->local_zones->lock);
1302	if((z=local_zones_find(ctx->local_zones, nm, nmlen, nmlabs,
1303		LDNS_RR_CLASS_IN))) {
1304		/* present in tree */
1305		local_zones_del_zone(ctx->local_zones, z);
1306	}
1307	lock_rw_unlock(&ctx->local_zones->lock);
1308	free(nm);
1309	return UB_NOERROR;
1310}
1311
1312/* Add new RR data */
1313int ub_ctx_data_add(struct ub_ctx* ctx, const char *data)
1314{
1315	int res = ub_ctx_finalize(ctx);
1316	if (res) return res;
1317
1318	res = local_zones_add_RR(ctx->local_zones, data);
1319	return (!res) ? UB_NOMEM : UB_NOERROR;
1320}
1321
1322/* Remove RR data */
1323int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data)
1324{
1325	uint8_t* nm;
1326	int nmlabs;
1327	size_t nmlen;
1328	int res = ub_ctx_finalize(ctx);
1329	if (res) return res;
1330
1331	if(!parse_dname(data, &nm, &nmlen, &nmlabs))
1332		return UB_SYNTAX;
1333
1334	local_zones_del_data(ctx->local_zones, nm, nmlen, nmlabs,
1335		LDNS_RR_CLASS_IN);
1336
1337	free(nm);
1338	return UB_NOERROR;
1339}
1340
1341const char* ub_version(void)
1342{
1343	return PACKAGE_VERSION;
1344}
1345
1346int
1347ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base) {
1348	struct ub_event_base* new_base;
1349
1350	if (!ctx || !ctx->event_base || !base) {
1351		return UB_INITFAIL;
1352	}
1353	if (ub_libevent_get_event_base(ctx->event_base) == base) {
1354		/* already set */
1355		return UB_NOERROR;
1356	}
1357
1358	lock_basic_lock(&ctx->cfglock);
1359	/* destroy the current worker - safe to pass in NULL */
1360	libworker_delete_event(ctx->event_worker);
1361	ctx->event_worker = NULL;
1362	new_base = ub_libevent_event_base(base);
1363	if (new_base)
1364		ctx->event_base = new_base;
1365	ctx->created_bg = 0;
1366	ctx->dothread = 1;
1367	lock_basic_unlock(&ctx->cfglock);
1368	return new_base ? UB_NOERROR : UB_INITFAIL;
1369}
1370