1/*
2 * daemon/worker.c - worker that handles a pending list of requests.
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 LIMITED
25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36/**
37 * \file
38 *
39 * This file implements the worker that handles callbacks on events, for
40 * pending requests.
41 */
42#include "config.h"
43#include <ldns/wire2host.h>
44#include "util/log.h"
45#include "util/net_help.h"
46#include "util/random.h"
47#include "daemon/worker.h"
48#include "daemon/daemon.h"
49#include "daemon/remote.h"
50#include "daemon/acl_list.h"
51#include "util/netevent.h"
52#include "util/config_file.h"
53#include "util/module.h"
54#include "util/regional.h"
55#include "util/storage/slabhash.h"
56#include "services/listen_dnsport.h"
57#include "services/outside_network.h"
58#include "services/outbound_list.h"
59#include "services/cache/rrset.h"
60#include "services/cache/infra.h"
61#include "services/cache/dns.h"
62#include "services/mesh.h"
63#include "services/localzone.h"
64#include "util/data/msgparse.h"
65#include "util/data/msgencode.h"
66#include "util/data/dname.h"
67#include "util/fptr_wlist.h"
68#include "util/tube.h"
69#include "iterator/iter_fwd.h"
70#include "iterator/iter_hints.h"
71#include "validator/autotrust.h"
72#include "validator/val_anchor.h"
73#include "libunbound/context.h"
74#include "libunbound/libworker.h"
75
76#ifdef HAVE_SYS_TYPES_H
77#  include <sys/types.h>
78#endif
79#ifdef HAVE_NETDB_H
80#include <netdb.h>
81#endif
82#include <signal.h>
83#ifdef UB_ON_WINDOWS
84#include "winrc/win_svc.h"
85#endif
86
87/** Size of an UDP datagram */
88#define NORMAL_UDP_SIZE	512 /* bytes */
89
90/**
91 * seconds to add to prefetch leeway.  This is a TTL that expires old rrsets
92 * earlier than they should in order to put the new update into the cache.
93 * This additional value is to make sure that if not all TTLs are equal in
94 * the message to be updated(and replaced), that rrsets with up to this much
95 * extra TTL are also replaced.  This means that the resulting new message
96 * will have (most likely) this TTL at least, avoiding very small 'split
97 * second' TTLs due to operators choosing relative primes for TTLs (or so).
98 * Also has to be at least one to break ties (and overwrite cached entry).
99 */
100#define PREFETCH_EXPIRY_ADD 60
101
102#ifdef UNBOUND_ALLOC_STATS
103/** measure memory leakage */
104static void
105debug_memleak(size_t accounted, size_t heap,
106	size_t total_alloc, size_t total_free)
107{
108	static int init = 0;
109	static size_t base_heap, base_accounted, base_alloc, base_free;
110	size_t base_af, cur_af, grow_af, grow_acc;
111	if(!init) {
112		init = 1;
113		base_heap = heap;
114		base_accounted = accounted;
115		base_alloc = total_alloc;
116		base_free = total_free;
117	}
118	base_af = base_alloc - base_free;
119	cur_af = total_alloc - total_free;
120	grow_af = cur_af - base_af;
121	grow_acc = accounted - base_accounted;
122	log_info("Leakage: %d leaked. growth: %u use, %u acc, %u heap",
123		(int)(grow_af - grow_acc), (unsigned)grow_af,
124		(unsigned)grow_acc, (unsigned)(heap - base_heap));
125}
126
127/** give debug heap size indication */
128static void
129debug_total_mem(size_t calctotal)
130{
131#ifdef HAVE_SBRK
132	extern void* unbound_start_brk;
133	extern size_t unbound_mem_alloc, unbound_mem_freed;
134	void* cur = sbrk(0);
135	int total = cur-unbound_start_brk;
136	log_info("Total heap memory estimate: %u  total-alloc: %u  "
137		"total-free: %u", (unsigned)total,
138		(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
139	debug_memleak(calctotal, (size_t)total,
140		unbound_mem_alloc, unbound_mem_freed);
141#else
142	(void)calctotal;
143#endif /* HAVE_SBRK */
144}
145#endif /* UNBOUND_ALLOC_STATS */
146
147/** Report on memory usage by this thread and global */
148static void
149worker_mem_report(struct worker* ATTR_UNUSED(worker),
150	struct serviced_query* ATTR_UNUSED(cur_serv))
151{
152#ifdef UNBOUND_ALLOC_STATS
153	/* debug func in validator module */
154	size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
155	size_t me, iter, val, anch;
156	int i;
157	if(verbosity < VERB_ALGO)
158		return;
159	front = listen_get_mem(worker->front);
160	back = outnet_get_mem(worker->back);
161	msg = slabhash_get_mem(worker->env.msg_cache);
162	rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
163	infra = infra_get_mem(worker->env.infra_cache);
164	mesh = mesh_get_mem(worker->env.mesh);
165	ac = alloc_get_mem(&worker->alloc);
166	superac = alloc_get_mem(&worker->daemon->superalloc);
167	anch = anchors_get_mem(worker->env.anchors);
168	iter = 0;
169	val = 0;
170	for(i=0; i<worker->env.mesh->mods.num; i++) {
171		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
172			mods.mod[i]->get_mem));
173		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
174			val += (*worker->env.mesh->mods.mod[i]->get_mem)
175				(&worker->env, i);
176		else	iter += (*worker->env.mesh->mods.mod[i]->get_mem)
177				(&worker->env, i);
178	}
179	me = sizeof(*worker) + sizeof(*worker->base) + sizeof(*worker->comsig)
180		+ comm_point_get_mem(worker->cmd_com)
181		+ sizeof(worker->rndstate)
182		+ regional_get_mem(worker->scratchpad)
183		+ sizeof(*worker->env.scratch_buffer)
184		+ ldns_buffer_capacity(worker->env.scratch_buffer)
185		+ forwards_get_mem(worker->env.fwds)
186		+ hints_get_mem(worker->env.hints);
187	if(worker->thread_num == 0)
188		me += acl_list_get_mem(worker->daemon->acl);
189	if(cur_serv) {
190		me += serviced_get_mem(cur_serv);
191	}
192	total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me;
193	log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
194		"rrset=%u infra=%u iter=%u val=%u anchors=%u "
195		"alloccache=%u globalalloccache=%u me=%u",
196		(unsigned)total, (unsigned)front, (unsigned)back,
197		(unsigned)mesh, (unsigned)msg, (unsigned)rrset,
198		(unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch,
199		(unsigned)ac, (unsigned)superac, (unsigned)me);
200	debug_total_mem(total);
201#else /* no UNBOUND_ALLOC_STATS */
202	size_t val = 0;
203	int i;
204	if(verbosity < VERB_QUERY)
205		return;
206	for(i=0; i<worker->env.mesh->mods.num; i++) {
207		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
208			mods.mod[i]->get_mem));
209		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
210			val += (*worker->env.mesh->mods.mod[i]->get_mem)
211				(&worker->env, i);
212	}
213	verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u",
214		(unsigned)slabhash_get_mem(worker->env.msg_cache),
215		(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
216		(unsigned)infra_get_mem(worker->env.infra_cache),
217		(unsigned)val);
218#endif /* UNBOUND_ALLOC_STATS */
219}
220
221void
222worker_send_cmd(struct worker* worker, enum worker_commands cmd)
223{
224	uint32_t c = (uint32_t)htonl(cmd);
225	if(!tube_write_msg(worker->cmd, (uint8_t*)&c, sizeof(c), 0)) {
226		log_err("worker send cmd %d failed", (int)cmd);
227	}
228}
229
230int
231worker_handle_reply(struct comm_point* c, void* arg, int error,
232	struct comm_reply* reply_info)
233{
234	struct module_qstate* q = (struct module_qstate*)arg;
235	struct worker* worker = q->env->worker;
236	struct outbound_entry e;
237	e.qstate = q;
238	e.qsent = NULL;
239
240	if(error != 0) {
241		mesh_report_reply(worker->env.mesh, &e, reply_info, error);
242		worker_mem_report(worker, NULL);
243		return 0;
244	}
245	/* sanity check. */
246	if(!LDNS_QR_WIRE(ldns_buffer_begin(c->buffer))
247		|| LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) !=
248			LDNS_PACKET_QUERY
249		|| LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) {
250		/* error becomes timeout for the module as if this reply
251		 * never arrived. */
252		mesh_report_reply(worker->env.mesh, &e, reply_info,
253			NETEVENT_TIMEOUT);
254		worker_mem_report(worker, NULL);
255		return 0;
256	}
257	mesh_report_reply(worker->env.mesh, &e, reply_info, NETEVENT_NOERROR);
258	worker_mem_report(worker, NULL);
259	return 0;
260}
261
262int
263worker_handle_service_reply(struct comm_point* c, void* arg, int error,
264	struct comm_reply* reply_info)
265{
266	struct outbound_entry* e = (struct outbound_entry*)arg;
267	struct worker* worker = e->qstate->env->worker;
268	struct serviced_query *sq = e->qsent;
269
270	verbose(VERB_ALGO, "worker svcd callback for qstate %p", e->qstate);
271	if(error != 0) {
272		mesh_report_reply(worker->env.mesh, e, reply_info, error);
273		worker_mem_report(worker, sq);
274		return 0;
275	}
276	/* sanity check. */
277	if(!LDNS_QR_WIRE(ldns_buffer_begin(c->buffer))
278		|| LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) !=
279			LDNS_PACKET_QUERY
280		|| LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) {
281		/* error becomes timeout for the module as if this reply
282		 * never arrived. */
283		verbose(VERB_ALGO, "worker: bad reply handled as timeout");
284		mesh_report_reply(worker->env.mesh, e, reply_info,
285			NETEVENT_TIMEOUT);
286		worker_mem_report(worker, sq);
287		return 0;
288	}
289	mesh_report_reply(worker->env.mesh, e, reply_info, NETEVENT_NOERROR);
290	worker_mem_report(worker, sq);
291	return 0;
292}
293
294/** check request sanity.
295 * @param pkt: the wire packet to examine for sanity.
296 * @param worker: parameters for checking.
297 * @return error code, 0 OK, or -1 discard.
298*/
299static int
300worker_check_request(ldns_buffer* pkt, struct worker* worker)
301{
302	if(ldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
303		verbose(VERB_QUERY, "request too short, discarded");
304		return -1;
305	}
306	if(ldns_buffer_limit(pkt) > NORMAL_UDP_SIZE &&
307		worker->daemon->cfg->harden_large_queries) {
308		verbose(VERB_QUERY, "request too large, discarded");
309		return -1;
310	}
311	if(LDNS_QR_WIRE(ldns_buffer_begin(pkt))) {
312		verbose(VERB_QUERY, "request has QR bit on, discarded");
313		return -1;
314	}
315	if(LDNS_TC_WIRE(ldns_buffer_begin(pkt))) {
316		LDNS_TC_CLR(ldns_buffer_begin(pkt));
317		verbose(VERB_QUERY, "request bad, has TC bit on");
318		return LDNS_RCODE_FORMERR;
319	}
320	if(LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
321		verbose(VERB_QUERY, "request unknown opcode %d",
322			LDNS_OPCODE_WIRE(ldns_buffer_begin(pkt)));
323		return LDNS_RCODE_NOTIMPL;
324	}
325	if(LDNS_QDCOUNT(ldns_buffer_begin(pkt)) != 1) {
326		verbose(VERB_QUERY, "request wrong nr qd=%d",
327			LDNS_QDCOUNT(ldns_buffer_begin(pkt)));
328		return LDNS_RCODE_FORMERR;
329	}
330	if(LDNS_ANCOUNT(ldns_buffer_begin(pkt)) != 0) {
331		verbose(VERB_QUERY, "request wrong nr an=%d",
332			LDNS_ANCOUNT(ldns_buffer_begin(pkt)));
333		return LDNS_RCODE_FORMERR;
334	}
335	if(LDNS_NSCOUNT(ldns_buffer_begin(pkt)) != 0) {
336		verbose(VERB_QUERY, "request wrong nr ns=%d",
337			LDNS_NSCOUNT(ldns_buffer_begin(pkt)));
338		return LDNS_RCODE_FORMERR;
339	}
340	if(LDNS_ARCOUNT(ldns_buffer_begin(pkt)) > 1) {
341		verbose(VERB_QUERY, "request wrong nr ar=%d",
342			LDNS_ARCOUNT(ldns_buffer_begin(pkt)));
343		return LDNS_RCODE_FORMERR;
344	}
345	return 0;
346}
347
348void
349worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
350	size_t len, int error, void* arg)
351{
352	struct worker* worker = (struct worker*)arg;
353	enum worker_commands cmd;
354	if(error != NETEVENT_NOERROR) {
355		free(msg);
356		if(error == NETEVENT_CLOSED)
357			comm_base_exit(worker->base);
358		else	log_info("control event: %d", error);
359		return;
360	}
361	if(len != sizeof(uint32_t)) {
362		fatal_exit("bad control msg length %d", (int)len);
363	}
364	cmd = ldns_read_uint32(msg);
365	free(msg);
366	switch(cmd) {
367	case worker_cmd_quit:
368		verbose(VERB_ALGO, "got control cmd quit");
369		comm_base_exit(worker->base);
370		break;
371	case worker_cmd_stats:
372		verbose(VERB_ALGO, "got control cmd stats");
373		server_stats_reply(worker, 1);
374		break;
375	case worker_cmd_stats_noreset:
376		verbose(VERB_ALGO, "got control cmd stats_noreset");
377		server_stats_reply(worker, 0);
378		break;
379	case worker_cmd_remote:
380		verbose(VERB_ALGO, "got control cmd remote");
381		daemon_remote_exec(worker);
382		break;
383	default:
384		log_err("bad command %d", (int)cmd);
385		break;
386	}
387}
388
389/** check if a delegation is secure */
390static enum sec_status
391check_delegation_secure(struct reply_info *rep)
392{
393	/* return smallest security status */
394	size_t i;
395	enum sec_status sec = sec_status_secure;
396	enum sec_status s;
397	size_t num = rep->an_numrrsets + rep->ns_numrrsets;
398	/* check if answer and authority are OK */
399	for(i=0; i<num; i++) {
400		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
401			->security;
402		if(s < sec)
403			sec = s;
404	}
405	/* in additional, only unchecked triggers revalidation */
406	for(i=num; i<rep->rrset_count; i++) {
407		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
408			->security;
409		if(s == sec_status_unchecked)
410			return s;
411	}
412	return sec;
413}
414
415/** remove nonsecure from a delegation referral additional section */
416static void
417deleg_remove_nonsecure_additional(struct reply_info* rep)
418{
419	/* we can simply edit it, since we are working in the scratch region */
420	size_t i;
421	enum sec_status s;
422
423	for(i = rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
424		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
425			->security;
426		if(s != sec_status_secure) {
427			memmove(rep->rrsets+i, rep->rrsets+i+1,
428				sizeof(struct ub_packed_rrset_key*)*
429				(rep->rrset_count - i - 1));
430			rep->ar_numrrsets--;
431			rep->rrset_count--;
432			i--;
433		}
434	}
435}
436
437/** answer nonrecursive query from the cache */
438static int
439answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
440	uint16_t id, uint16_t flags, struct comm_reply* repinfo,
441	struct edns_data* edns)
442{
443	/* for a nonrecursive query return either:
444	 * 	o an error (servfail; we try to avoid this)
445	 * 	o a delegation (closest we have; this routine tries that)
446	 * 	o the answer (checked by answer_from_cache)
447	 *
448	 * So, grab a delegation from the rrset cache.
449	 * Then check if it needs validation, if so, this routine fails,
450	 * so that iterator can prime and validator can verify rrsets.
451	 */
452	uint16_t udpsize = edns->udp_size;
453	int secure = 0;
454	uint32_t timenow = *worker->env.now;
455	int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
456		&& worker->env.need_to_validate;
457	struct dns_msg *msg = NULL;
458	struct delegpt *dp;
459
460	dp = dns_cache_find_delegation(&worker->env, qinfo->qname,
461		qinfo->qname_len, qinfo->qtype, qinfo->qclass,
462		worker->scratchpad, &msg, timenow);
463	if(!dp) { /* no delegation, need to reprime */
464		regional_free_all(worker->scratchpad);
465		return 0;
466	}
467	if(must_validate) {
468		switch(check_delegation_secure(msg->rep)) {
469		case sec_status_unchecked:
470			/* some rrsets have not been verified yet, go and
471			 * let validator do that */
472			regional_free_all(worker->scratchpad);
473			return 0;
474		case sec_status_bogus:
475			/* some rrsets are bogus, reply servfail */
476			edns->edns_version = EDNS_ADVERTISED_VERSION;
477			edns->udp_size = EDNS_ADVERTISED_SIZE;
478			edns->ext_rcode = 0;
479			edns->bits &= EDNS_DO;
480			error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
481				&msg->qinfo, id, flags, edns);
482			regional_free_all(worker->scratchpad);
483			if(worker->stats.extended) {
484				worker->stats.ans_bogus++;
485				worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL]++;
486			}
487			return 1;
488		case sec_status_secure:
489			/* all rrsets are secure */
490			/* remove non-secure rrsets from the add. section*/
491			if(worker->env.cfg->val_clean_additional)
492				deleg_remove_nonsecure_additional(msg->rep);
493			secure = 1;
494			break;
495		case sec_status_indeterminate:
496		case sec_status_insecure:
497		default:
498			/* not secure */
499			secure = 0;
500			break;
501		}
502	}
503	/* return this delegation from the cache */
504	edns->edns_version = EDNS_ADVERTISED_VERSION;
505	edns->udp_size = EDNS_ADVERTISED_SIZE;
506	edns->ext_rcode = 0;
507	edns->bits &= EDNS_DO;
508	msg->rep->flags |= BIT_QR|BIT_RA;
509	if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
510		repinfo->c->buffer, 0, 1, worker->scratchpad,
511		udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
512		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
513			&msg->qinfo, id, flags, edns);
514	}
515	regional_free_all(worker->scratchpad);
516	if(worker->stats.extended) {
517		if(secure) worker->stats.ans_secure++;
518		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
519	}
520	return 1;
521}
522
523/** answer query from the cache */
524static int
525answer_from_cache(struct worker* worker, struct query_info* qinfo,
526	struct reply_info* rep, uint16_t id, uint16_t flags,
527	struct comm_reply* repinfo, struct edns_data* edns)
528{
529	uint32_t timenow = *worker->env.now;
530	uint16_t udpsize = edns->udp_size;
531	int secure;
532	int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
533		&& worker->env.need_to_validate;
534	/* see if it is possible */
535	if(rep->ttl < timenow) {
536		/* the rrsets may have been updated in the meantime.
537		 * we will refetch the message format from the
538		 * authoritative server
539		 */
540		return 0;
541	}
542	if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
543		return 0;
544	/* locked and ids and ttls are OK. */
545	/* check CNAME chain (if any) */
546	if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
547		htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
548		htons(LDNS_RR_TYPE_DNAME))) {
549		if(!reply_check_cname_chain(rep)) {
550			/* cname chain invalid, redo iterator steps */
551			verbose(VERB_ALGO, "Cache reply: cname chain broken");
552		bail_out:
553			rrset_array_unlock_touch(worker->env.rrset_cache,
554				worker->scratchpad, rep->ref, rep->rrset_count);
555			regional_free_all(worker->scratchpad);
556			return 0;
557		}
558	}
559	/* check security status of the cached answer */
560	if( rep->security == sec_status_bogus && must_validate) {
561		/* BAD cached */
562		edns->edns_version = EDNS_ADVERTISED_VERSION;
563		edns->udp_size = EDNS_ADVERTISED_SIZE;
564		edns->ext_rcode = 0;
565		edns->bits &= EDNS_DO;
566		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
567			qinfo, id, flags, edns);
568		rrset_array_unlock_touch(worker->env.rrset_cache,
569			worker->scratchpad, rep->ref, rep->rrset_count);
570		regional_free_all(worker->scratchpad);
571		if(worker->stats.extended) {
572			worker->stats.ans_bogus ++;
573			worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++;
574		}
575		return 1;
576	} else if( rep->security == sec_status_unchecked && must_validate) {
577		verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
578			"validation");
579		goto bail_out; /* need to validate cache entry first */
580	} else if(rep->security == sec_status_secure) {
581		if(reply_all_rrsets_secure(rep))
582			secure = 1;
583		else	{
584			if(must_validate) {
585				verbose(VERB_ALGO, "Cache reply: secure entry"
586					" changed status");
587				goto bail_out; /* rrset changed, re-verify */
588			}
589			secure = 0;
590		}
591	} else	secure = 0;
592
593	edns->edns_version = EDNS_ADVERTISED_VERSION;
594	edns->udp_size = EDNS_ADVERTISED_SIZE;
595	edns->ext_rcode = 0;
596	edns->bits &= EDNS_DO;
597	if(!reply_info_answer_encode(qinfo, rep, id, flags,
598		repinfo->c->buffer, timenow, 1, worker->scratchpad,
599		udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
600		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
601			qinfo, id, flags, edns);
602	}
603	/* cannot send the reply right now, because blocking network syscall
604	 * is bad while holding locks. */
605	rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
606		rep->ref, rep->rrset_count);
607	regional_free_all(worker->scratchpad);
608	if(worker->stats.extended) {
609		if(secure) worker->stats.ans_secure++;
610		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
611	}
612	/* go and return this buffer to the client */
613	return 1;
614}
615
616/** Reply to client and perform prefetch to keep cache up to date */
617static void
618reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
619	uint16_t flags, struct comm_reply* repinfo, uint32_t leeway)
620{
621	/* first send answer to client to keep its latency
622	 * as small as a cachereply */
623	comm_point_send_reply(repinfo);
624	server_stats_prefetch(&worker->stats, worker);
625
626	/* create the prefetch in the mesh as a normal lookup without
627	 * client addrs waiting, which has the cache blacklisted (to bypass
628	 * the cache and go to the network for the data). */
629	/* this (potentially) runs the mesh for the new query */
630	mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
631		PREFETCH_EXPIRY_ADD);
632}
633
634/**
635 * Fill CH class answer into buffer. Keeps query.
636 * @param pkt: buffer
637 * @param str: string to put into text record (<255).
638 * @param edns: edns reply information.
639 */
640static void
641chaos_replystr(ldns_buffer* pkt, const char* str, struct edns_data* edns)
642{
643	size_t len = strlen(str);
644	unsigned int rd = LDNS_RD_WIRE(ldns_buffer_begin(pkt));
645	unsigned int cd = LDNS_CD_WIRE(ldns_buffer_begin(pkt));
646	if(len>255) len=255; /* cap size of TXT record */
647	ldns_buffer_clear(pkt);
648	ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */
649	ldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA));
650	if(rd) LDNS_RD_SET(ldns_buffer_begin(pkt));
651	if(cd) LDNS_CD_SET(ldns_buffer_begin(pkt));
652	ldns_buffer_write_u16(pkt, 1); /* qdcount */
653	ldns_buffer_write_u16(pkt, 1); /* ancount */
654	ldns_buffer_write_u16(pkt, 0); /* nscount */
655	ldns_buffer_write_u16(pkt, 0); /* arcount */
656	(void)query_dname_len(pkt); /* skip qname */
657	ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */
658	ldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */
659	ldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
660	ldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
661	ldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
662	ldns_buffer_write_u32(pkt, 0); /* TTL */
663	ldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
664	ldns_buffer_write_u8(pkt, len);
665	ldns_buffer_write(pkt, str, len);
666	ldns_buffer_flip(pkt);
667	edns->edns_version = EDNS_ADVERTISED_VERSION;
668	edns->udp_size = EDNS_ADVERTISED_SIZE;
669	edns->bits &= EDNS_DO;
670	attach_edns_record(pkt, edns);
671}
672
673/**
674 * Answer CH class queries.
675 * @param w: worker
676 * @param qinfo: query info. Pointer into packet buffer.
677 * @param edns: edns info from query.
678 * @param pkt: packet buffer.
679 * @return: true if a reply is to be sent.
680 */
681static int
682answer_chaos(struct worker* w, struct query_info* qinfo,
683	struct edns_data* edns, ldns_buffer* pkt)
684{
685	struct config_file* cfg = w->env.cfg;
686	if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
687		return 0;
688	if(query_dname_compare(qinfo->qname,
689		(uint8_t*)"\002id\006server") == 0 ||
690		query_dname_compare(qinfo->qname,
691		(uint8_t*)"\010hostname\004bind") == 0)
692	{
693		if(cfg->hide_identity)
694			return 0;
695		if(cfg->identity==NULL || cfg->identity[0]==0) {
696			char buf[MAXHOSTNAMELEN+1];
697			if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
698				buf[MAXHOSTNAMELEN] = 0;
699				chaos_replystr(pkt, buf, edns);
700			} else 	{
701				log_err("gethostname: %s", strerror(errno));
702				chaos_replystr(pkt, "no hostname", edns);
703			}
704		}
705		else 	chaos_replystr(pkt, cfg->identity, edns);
706		return 1;
707	}
708	if(query_dname_compare(qinfo->qname,
709		(uint8_t*)"\007version\006server") == 0 ||
710		query_dname_compare(qinfo->qname,
711		(uint8_t*)"\007version\004bind") == 0)
712	{
713		if(cfg->hide_version)
714			return 0;
715		if(cfg->version==NULL || cfg->version[0]==0)
716			chaos_replystr(pkt, PACKAGE_STRING, edns);
717		else 	chaos_replystr(pkt, cfg->version, edns);
718		return 1;
719	}
720	return 0;
721}
722
723int
724worker_handle_request(struct comm_point* c, void* arg, int error,
725	struct comm_reply* repinfo)
726{
727	struct worker* worker = (struct worker*)arg;
728	int ret;
729	hashvalue_t h;
730	struct lruhash_entry* e;
731	struct query_info qinfo;
732	struct edns_data edns;
733	enum acl_access acl;
734
735	if(error != NETEVENT_NOERROR) {
736		/* some bad tcp query DNS formats give these error calls */
737		verbose(VERB_ALGO, "handle request called with err=%d", error);
738		return 0;
739	}
740	acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
741		repinfo->addrlen);
742	if(acl == acl_deny) {
743		comm_point_drop_reply(repinfo);
744		if(worker->stats.extended)
745			worker->stats.unwanted_queries++;
746		return 0;
747	} else if(acl == acl_refuse) {
748		log_addr(VERB_ALGO, "refused query from",
749			&repinfo->addr, repinfo->addrlen);
750		log_buf(VERB_ALGO, "refuse", c->buffer);
751		if(worker->stats.extended)
752			worker->stats.unwanted_queries++;
753		if(worker_check_request(c->buffer, worker) == -1) {
754			comm_point_drop_reply(repinfo);
755			return 0; /* discard this */
756		}
757		ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
758		ldns_buffer_write_at(c->buffer, 4,
759			(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
760		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
761		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
762			LDNS_RCODE_REFUSED);
763		return 1;
764	}
765	if((ret=worker_check_request(c->buffer, worker)) != 0) {
766		verbose(VERB_ALGO, "worker check request: bad query.");
767		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
768		if(ret != -1) {
769			LDNS_QR_SET(ldns_buffer_begin(c->buffer));
770			LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
771			return 1;
772		}
773		comm_point_drop_reply(repinfo);
774		return 0;
775	}
776	worker->stats.num_queries++;
777	/* see if query is in the cache */
778	if(!query_info_parse(&qinfo, c->buffer)) {
779		verbose(VERB_ALGO, "worker parse request: formerror.");
780		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
781		ldns_buffer_rewind(c->buffer);
782		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
783		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
784			LDNS_RCODE_FORMERR);
785		server_stats_insrcode(&worker->stats, c->buffer);
786		return 1;
787	}
788	if(worker->env.cfg->log_queries) {
789		char ip[128];
790		addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
791		log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
792	}
793	if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
794		qinfo.qtype == LDNS_RR_TYPE_IXFR) {
795		verbose(VERB_ALGO, "worker request: refused zone transfer.");
796		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
797		ldns_buffer_rewind(c->buffer);
798		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
799		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
800			LDNS_RCODE_REFUSED);
801		if(worker->stats.extended) {
802			worker->stats.qtype[qinfo.qtype]++;
803			server_stats_insrcode(&worker->stats, c->buffer);
804		}
805		return 1;
806	}
807	if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) {
808		verbose(VERB_ALGO, "worker parse edns: formerror.");
809		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
810		ldns_buffer_rewind(c->buffer);
811		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
812		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), ret);
813		server_stats_insrcode(&worker->stats, c->buffer);
814		return 1;
815	}
816	if(edns.edns_present && edns.edns_version != 0) {
817		edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
818		edns.edns_version = EDNS_ADVERTISED_VERSION;
819		edns.udp_size = EDNS_ADVERTISED_SIZE;
820		edns.bits &= EDNS_DO;
821		verbose(VERB_ALGO, "query with bad edns version.");
822		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
823		error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
824			*(uint16_t*)(void *)ldns_buffer_begin(c->buffer),
825			ldns_buffer_read_u16_at(c->buffer, 2), NULL);
826		attach_edns_record(c->buffer, &edns);
827		return 1;
828	}
829	if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
830		worker->daemon->cfg->harden_short_bufsize) {
831		verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
832			(int)edns.udp_size);
833		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
834		edns.udp_size = NORMAL_UDP_SIZE;
835	}
836	if(edns.edns_present && edns.udp_size < LDNS_HEADER_SIZE) {
837		verbose(VERB_ALGO, "worker request: edns is too small.");
838		log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen);
839		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
840		LDNS_TC_SET(ldns_buffer_begin(c->buffer));
841		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
842			LDNS_RCODE_SERVFAIL);
843		ldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
844		ldns_buffer_write_at(c->buffer, 4,
845			(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
846		ldns_buffer_flip(c->buffer);
847		return 1;
848	}
849	if(worker->stats.extended)
850		server_stats_insquery(&worker->stats, c, qinfo.qtype,
851			qinfo.qclass, &edns, repinfo);
852	if(c->type != comm_udp)
853		edns.udp_size = 65535; /* max size for TCP replies */
854	if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
855		&edns, c->buffer)) {
856		server_stats_insrcode(&worker->stats, c->buffer);
857		return 1;
858	}
859	if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
860		c->buffer, worker->scratchpad)) {
861		regional_free_all(worker->scratchpad);
862		if(ldns_buffer_limit(c->buffer) == 0) {
863			comm_point_drop_reply(repinfo);
864			return 0;
865		}
866		server_stats_insrcode(&worker->stats, c->buffer);
867		return 1;
868	}
869	if(!(LDNS_RD_WIRE(ldns_buffer_begin(c->buffer))) &&
870		acl != acl_allow_snoop ) {
871		ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
872		ldns_buffer_write_at(c->buffer, 4,
873			(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
874		LDNS_QR_SET(ldns_buffer_begin(c->buffer));
875		LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
876			LDNS_RCODE_REFUSED);
877		ldns_buffer_flip(c->buffer);
878		server_stats_insrcode(&worker->stats, c->buffer);
879		log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
880			&repinfo->addr, repinfo->addrlen);
881		return 1;
882	}
883	h = query_info_hash(&qinfo);
884	if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
885		/* answer from cache - we have acquired a readlock on it */
886		if(answer_from_cache(worker, &qinfo,
887			(struct reply_info*)e->data,
888			*(uint16_t*)(void *)ldns_buffer_begin(c->buffer),
889			ldns_buffer_read_u16_at(c->buffer, 2), repinfo,
890			&edns)) {
891			/* prefetch it if the prefetch TTL expired */
892			if(worker->env.cfg->prefetch && *worker->env.now >=
893				((struct reply_info*)e->data)->prefetch_ttl) {
894				uint32_t leeway = ((struct reply_info*)e->
895					data)->ttl - *worker->env.now;
896				lock_rw_unlock(&e->lock);
897				reply_and_prefetch(worker, &qinfo,
898					ldns_buffer_read_u16_at(c->buffer, 2),
899					repinfo, leeway);
900				return 0;
901			}
902			lock_rw_unlock(&e->lock);
903			return 1;
904		}
905		verbose(VERB_ALGO, "answer from the cache failed");
906		lock_rw_unlock(&e->lock);
907	}
908	if(!LDNS_RD_WIRE(ldns_buffer_begin(c->buffer))) {
909		if(answer_norec_from_cache(worker, &qinfo,
910			*(uint16_t*)(void *)ldns_buffer_begin(c->buffer),
911			ldns_buffer_read_u16_at(c->buffer, 2), repinfo,
912			&edns)) {
913			return 1;
914		}
915		verbose(VERB_ALGO, "answer norec from cache -- "
916			"need to validate or not primed");
917	}
918	ldns_buffer_rewind(c->buffer);
919	server_stats_querymiss(&worker->stats, worker);
920
921	if(verbosity >= VERB_CLIENT) {
922		if(c->type == comm_udp)
923			log_addr(VERB_CLIENT, "udp request from",
924				&repinfo->addr, repinfo->addrlen);
925		else	log_addr(VERB_CLIENT, "tcp request from",
926				&repinfo->addr, repinfo->addrlen);
927	}
928
929	/* grab a work request structure for this new request */
930	mesh_new_client(worker->env.mesh, &qinfo,
931		ldns_buffer_read_u16_at(c->buffer, 2), &edns, repinfo,
932		*(uint16_t*)(void *)ldns_buffer_begin(c->buffer));
933	worker_mem_report(worker, NULL);
934	return 0;
935}
936
937void
938worker_sighandler(int sig, void* arg)
939{
940	/* note that log, print, syscalls here give race conditions. */
941	/* we still print DETAIL logs, because this is extensive per message
942	 * logging anyway, and the operator may then have an interest
943	 * in the cause for unbound to exit */
944	struct worker* worker = (struct worker*)arg;
945	switch(sig) {
946#ifdef SIGHUP
947		case SIGHUP:
948			verbose(VERB_QUERY, "caught signal SIGHUP");
949			comm_base_exit(worker->base);
950			break;
951#endif
952		case SIGINT:
953			verbose(VERB_QUERY, "caught signal SIGINT");
954			worker->need_to_exit = 1;
955			comm_base_exit(worker->base);
956			break;
957#ifdef SIGQUIT
958		case SIGQUIT:
959			verbose(VERB_QUERY, "caught signal SIGQUIT");
960			worker->need_to_exit = 1;
961			comm_base_exit(worker->base);
962			break;
963#endif
964		case SIGTERM:
965			verbose(VERB_QUERY, "caught signal SIGTERM");
966			worker->need_to_exit = 1;
967			comm_base_exit(worker->base);
968			break;
969		default:
970			log_err("unknown signal: %d, ignored", sig);
971			break;
972	}
973}
974
975/** restart statistics timer for worker, if enabled */
976static void
977worker_restart_timer(struct worker* worker)
978{
979	if(worker->env.cfg->stat_interval > 0) {
980		struct timeval tv;
981#ifndef S_SPLINT_S
982		tv.tv_sec = worker->env.cfg->stat_interval;
983		tv.tv_usec = 0;
984#endif
985		comm_timer_set(worker->stat_timer, &tv);
986	}
987}
988
989void worker_stat_timer_cb(void* arg)
990{
991	struct worker* worker = (struct worker*)arg;
992	server_stats_log(&worker->stats, worker, worker->thread_num);
993	mesh_stats(worker->env.mesh, "mesh has");
994	worker_mem_report(worker, NULL);
995	if(!worker->daemon->cfg->stat_cumulative) {
996		worker_stats_clear(worker);
997	}
998	/* start next timer */
999	worker_restart_timer(worker);
1000}
1001
1002void worker_probe_timer_cb(void* arg)
1003{
1004	struct worker* worker = (struct worker*)arg;
1005	struct timeval tv;
1006#ifndef S_SPLINT_S
1007	tv.tv_sec = (time_t)autr_probe_timer(&worker->env);
1008	tv.tv_usec = 0;
1009#endif
1010	if(tv.tv_sec != 0)
1011		comm_timer_set(worker->env.probe_timer, &tv);
1012}
1013
1014struct worker*
1015worker_create(struct daemon* daemon, int id, int* ports, int n)
1016{
1017	unsigned int seed;
1018	struct worker* worker = (struct worker*)calloc(1,
1019		sizeof(struct worker));
1020	if(!worker)
1021		return NULL;
1022	worker->numports = n;
1023	worker->ports = (int*)memdup(ports, sizeof(int)*n);
1024	if(!worker->ports) {
1025		free(worker);
1026		return NULL;
1027	}
1028	worker->daemon = daemon;
1029	worker->thread_num = id;
1030	if(!(worker->cmd = tube_create())) {
1031		free(worker->ports);
1032		free(worker);
1033		return NULL;
1034	}
1035	/* create random state here to avoid locking trouble in RAND_bytes */
1036	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
1037		(((unsigned int)worker->thread_num)<<17);
1038		/* shift thread_num so it does not match out pid bits */
1039	if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
1040		seed = 0;
1041		log_err("could not init random numbers.");
1042		tube_delete(worker->cmd);
1043		free(worker->ports);
1044		free(worker);
1045		return NULL;
1046	}
1047	seed = 0;
1048	return worker;
1049}
1050
1051int
1052worker_init(struct worker* worker, struct config_file *cfg,
1053	struct listen_port* ports, int do_sigs)
1054{
1055	worker->need_to_exit = 0;
1056	worker->base = comm_base_create(do_sigs);
1057	if(!worker->base) {
1058		log_err("could not create event handling base");
1059		worker_delete(worker);
1060		return 0;
1061	}
1062	comm_base_set_slow_accept_handlers(worker->base, &worker_stop_accept,
1063		&worker_start_accept, worker);
1064	if(do_sigs) {
1065#ifdef SIGHUP
1066		ub_thread_sig_unblock(SIGHUP);
1067#endif
1068		ub_thread_sig_unblock(SIGINT);
1069#ifdef SIGQUIT
1070		ub_thread_sig_unblock(SIGQUIT);
1071#endif
1072		ub_thread_sig_unblock(SIGTERM);
1073#ifndef LIBEVENT_SIGNAL_PROBLEM
1074		worker->comsig = comm_signal_create(worker->base,
1075			worker_sighandler, worker);
1076		if(!worker->comsig
1077#ifdef SIGHUP
1078			|| !comm_signal_bind(worker->comsig, SIGHUP)
1079#endif
1080#ifdef SIGQUIT
1081			|| !comm_signal_bind(worker->comsig, SIGQUIT)
1082#endif
1083			|| !comm_signal_bind(worker->comsig, SIGTERM)
1084			|| !comm_signal_bind(worker->comsig, SIGINT)) {
1085			log_err("could not create signal handlers");
1086			worker_delete(worker);
1087			return 0;
1088		}
1089#endif /* LIBEVENT_SIGNAL_PROBLEM */
1090		if(!daemon_remote_open_accept(worker->daemon->rc,
1091			worker->daemon->rc_ports, worker)) {
1092			worker_delete(worker);
1093			return 0;
1094		}
1095#ifdef UB_ON_WINDOWS
1096		wsvc_setup_worker(worker);
1097#endif /* UB_ON_WINDOWS */
1098	} else { /* !do_sigs */
1099		worker->comsig = NULL;
1100	}
1101	worker->front = listen_create(worker->base, ports,
1102		cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
1103		worker->daemon->listen_sslctx, worker_handle_request, worker);
1104	if(!worker->front) {
1105		log_err("could not create listening sockets");
1106		worker_delete(worker);
1107		return 0;
1108	}
1109	worker->back = outside_network_create(worker->base,
1110		cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
1111		cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
1112		cfg->do_tcp?cfg->outgoing_num_tcp:0,
1113		worker->daemon->env->infra_cache, worker->rndstate,
1114		cfg->use_caps_bits_for_id, worker->ports, worker->numports,
1115		cfg->unwanted_threshold, &worker_alloc_cleanup, worker,
1116		cfg->do_udp, worker->daemon->connect_sslctx);
1117	if(!worker->back) {
1118		log_err("could not create outgoing sockets");
1119		worker_delete(worker);
1120		return 0;
1121	}
1122	/* start listening to commands */
1123	if(!tube_setup_bg_listen(worker->cmd, worker->base,
1124		&worker_handle_control_cmd, worker)) {
1125		log_err("could not create control compt.");
1126		worker_delete(worker);
1127		return 0;
1128	}
1129	worker->stat_timer = comm_timer_create(worker->base,
1130		worker_stat_timer_cb, worker);
1131	if(!worker->stat_timer) {
1132		log_err("could not create statistics timer");
1133	}
1134
1135	/* we use the msg_buffer_size as a good estimate for what the
1136	 * user wants for memory usage sizes */
1137	worker->scratchpad = regional_create_custom(cfg->msg_buffer_size);
1138	if(!worker->scratchpad) {
1139		log_err("malloc failure");
1140		worker_delete(worker);
1141		return 0;
1142	}
1143
1144	server_stats_init(&worker->stats, cfg);
1145	alloc_init(&worker->alloc, &worker->daemon->superalloc,
1146		worker->thread_num);
1147	alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
1148	worker->env = *worker->daemon->env;
1149	comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
1150	if(worker->thread_num == 0)
1151		log_set_time(worker->env.now);
1152	worker->env.worker = worker;
1153	worker->env.send_query = &worker_send_query;
1154	worker->env.alloc = &worker->alloc;
1155	worker->env.rnd = worker->rndstate;
1156	worker->env.scratch = worker->scratchpad;
1157	worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
1158	worker->env.detach_subs = &mesh_detach_subs;
1159	worker->env.attach_sub = &mesh_attach_sub;
1160	worker->env.kill_sub = &mesh_state_delete;
1161	worker->env.detect_cycle = &mesh_detect_cycle;
1162	worker->env.scratch_buffer = ldns_buffer_new(cfg->msg_buffer_size);
1163	if(!(worker->env.fwds = forwards_create()) ||
1164		!forwards_apply_cfg(worker->env.fwds, cfg)) {
1165		log_err("Could not set forward zones");
1166		worker_delete(worker);
1167		return 0;
1168	}
1169	if(!(worker->env.hints = hints_create()) ||
1170		!hints_apply_cfg(worker->env.hints, cfg)) {
1171		log_err("Could not set root or stub hints");
1172		worker_delete(worker);
1173		return 0;
1174	}
1175	/* one probe timer per process -- if we have 5011 anchors */
1176	if(autr_get_num_anchors(worker->env.anchors) > 0
1177#ifndef THREADS_DISABLED
1178		&& worker->thread_num == 0
1179#endif
1180		) {
1181		struct timeval tv;
1182		tv.tv_sec = 0;
1183		tv.tv_usec = 0;
1184		worker->env.probe_timer = comm_timer_create(worker->base,
1185			worker_probe_timer_cb, worker);
1186		if(!worker->env.probe_timer) {
1187			log_err("could not create 5011-probe timer");
1188		} else {
1189			/* let timer fire, then it can reset itself */
1190			comm_timer_set(worker->env.probe_timer, &tv);
1191		}
1192	}
1193	if(!worker->env.mesh || !worker->env.scratch_buffer) {
1194		worker_delete(worker);
1195		return 0;
1196	}
1197	worker_mem_report(worker, NULL);
1198	/* if statistics enabled start timer */
1199	if(worker->env.cfg->stat_interval > 0) {
1200		verbose(VERB_ALGO, "set statistics interval %d secs",
1201			worker->env.cfg->stat_interval);
1202		worker_restart_timer(worker);
1203	}
1204	return 1;
1205}
1206
1207void
1208worker_work(struct worker* worker)
1209{
1210	comm_base_dispatch(worker->base);
1211}
1212
1213void
1214worker_delete(struct worker* worker)
1215{
1216	if(!worker)
1217		return;
1218	if(worker->env.mesh && verbosity >= VERB_OPS) {
1219		server_stats_log(&worker->stats, worker, worker->thread_num);
1220		mesh_stats(worker->env.mesh, "mesh has");
1221		worker_mem_report(worker, NULL);
1222	}
1223	outside_network_quit_prepare(worker->back);
1224	mesh_delete(worker->env.mesh);
1225	ldns_buffer_free(worker->env.scratch_buffer);
1226	forwards_delete(worker->env.fwds);
1227	hints_delete(worker->env.hints);
1228	listen_delete(worker->front);
1229	outside_network_delete(worker->back);
1230	comm_signal_delete(worker->comsig);
1231	tube_delete(worker->cmd);
1232	comm_timer_delete(worker->stat_timer);
1233	comm_timer_delete(worker->env.probe_timer);
1234	free(worker->ports);
1235	if(worker->thread_num == 0) {
1236		log_set_time(NULL);
1237#ifdef UB_ON_WINDOWS
1238		wsvc_desetup_worker(worker);
1239#endif /* UB_ON_WINDOWS */
1240	}
1241	comm_base_delete(worker->base);
1242	ub_randfree(worker->rndstate);
1243	alloc_clear(&worker->alloc);
1244	regional_destroy(worker->scratchpad);
1245	free(worker);
1246}
1247
1248struct outbound_entry*
1249worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
1250	uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec,
1251	struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
1252	size_t zonelen, struct module_qstate* q)
1253{
1254	struct worker* worker = q->env->worker;
1255	struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
1256		q->region, sizeof(*e));
1257	if(!e)
1258		return NULL;
1259	e->qstate = q;
1260	e->qsent = outnet_serviced_query(worker->back, qname,
1261		qnamelen, qtype, qclass, flags, dnssec, want_dnssec,
1262		q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr,
1263		addrlen, zone, zonelen, worker_handle_service_reply, e,
1264		worker->back->udp_buff);
1265	if(!e->qsent) {
1266		return NULL;
1267	}
1268	return e;
1269}
1270
1271void
1272worker_alloc_cleanup(void* arg)
1273{
1274	struct worker* worker = (struct worker*)arg;
1275	slabhash_clear(&worker->env.rrset_cache->table);
1276	slabhash_clear(worker->env.msg_cache);
1277}
1278
1279void worker_stats_clear(struct worker* worker)
1280{
1281	server_stats_init(&worker->stats, worker->env.cfg);
1282	mesh_stats_clear(worker->env.mesh);
1283	worker->back->unwanted_replies = 0;
1284}
1285
1286void worker_start_accept(void* arg)
1287{
1288	struct worker* worker = (struct worker*)arg;
1289	listen_start_accept(worker->front);
1290	if(worker->thread_num == 0)
1291		daemon_remote_start_accept(worker->daemon->rc);
1292}
1293
1294void worker_stop_accept(void* arg)
1295{
1296	struct worker* worker = (struct worker*)arg;
1297	listen_stop_accept(worker->front);
1298	if(worker->thread_num == 0)
1299		daemon_remote_stop_accept(worker->daemon->rc);
1300}
1301
1302/* --- fake callbacks for fptr_wlist to work --- */
1303struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
1304	size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
1305	uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
1306	int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
1307	struct sockaddr_storage* ATTR_UNUSED(addr),
1308	socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
1309	size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
1310{
1311	log_assert(0);
1312	return 0;
1313}
1314
1315int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c),
1316	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1317        struct comm_reply* ATTR_UNUSED(reply_info))
1318{
1319	log_assert(0);
1320	return 0;
1321}
1322
1323int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
1324	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
1325        struct comm_reply* ATTR_UNUSED(reply_info))
1326{
1327	log_assert(0);
1328	return 0;
1329}
1330
1331void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
1332        uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
1333        int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
1334{
1335	log_assert(0);
1336}
1337
1338void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
1339        ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
1340	char* ATTR_UNUSED(why_bogus))
1341{
1342	log_assert(0);
1343}
1344
1345void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
1346        ldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
1347	char* ATTR_UNUSED(why_bogus))
1348{
1349	log_assert(0);
1350}
1351
1352int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1353{
1354	log_assert(0);
1355	return 0;
1356}
1357
1358int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
1359{
1360        log_assert(0);
1361        return 0;
1362}
1363
1364int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
1365{
1366        log_assert(0);
1367        return 0;
1368}
1369
1370