Home | History | Annotate | Line # | Download | only in daemon
worker.c revision 1.1.1.3
      1      1.1  christos /*
      2      1.1  christos  * daemon/worker.c - worker that handles a pending list of requests.
      3      1.1  christos  *
      4      1.1  christos  * Copyright (c) 2007, NLnet Labs. All rights reserved.
      5      1.1  christos  *
      6      1.1  christos  * This software is open source.
      7      1.1  christos  *
      8      1.1  christos  * Redistribution and use in source and binary forms, with or without
      9      1.1  christos  * modification, are permitted provided that the following conditions
     10      1.1  christos  * are met:
     11      1.1  christos  *
     12      1.1  christos  * Redistributions of source code must retain the above copyright notice,
     13      1.1  christos  * this list of conditions and the following disclaimer.
     14      1.1  christos  *
     15      1.1  christos  * Redistributions in binary form must reproduce the above copyright notice,
     16      1.1  christos  * this list of conditions and the following disclaimer in the documentation
     17      1.1  christos  * and/or other materials provided with the distribution.
     18      1.1  christos  *
     19      1.1  christos  * Neither the name of the NLNET LABS nor the names of its contributors may
     20      1.1  christos  * be used to endorse or promote products derived from this software without
     21      1.1  christos  * specific prior written permission.
     22      1.1  christos  *
     23      1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     24      1.1  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     25      1.1  christos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     26      1.1  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     27      1.1  christos  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     28      1.1  christos  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
     29      1.1  christos  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     30      1.1  christos  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     31      1.1  christos  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     32      1.1  christos  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     33      1.1  christos  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     34      1.1  christos  */
     35      1.1  christos 
     36      1.1  christos /**
     37      1.1  christos  * \file
     38      1.1  christos  *
     39      1.1  christos  * This file implements the worker that handles callbacks on events, for
     40      1.1  christos  * pending requests.
     41      1.1  christos  */
     42      1.1  christos #include "config.h"
     43      1.1  christos #include "util/log.h"
     44      1.1  christos #include "util/net_help.h"
     45      1.1  christos #include "util/random.h"
     46      1.1  christos #include "daemon/worker.h"
     47      1.1  christos #include "daemon/daemon.h"
     48      1.1  christos #include "daemon/remote.h"
     49      1.1  christos #include "daemon/acl_list.h"
     50      1.1  christos #include "util/netevent.h"
     51      1.1  christos #include "util/config_file.h"
     52      1.1  christos #include "util/module.h"
     53      1.1  christos #include "util/regional.h"
     54      1.1  christos #include "util/storage/slabhash.h"
     55      1.1  christos #include "services/listen_dnsport.h"
     56      1.1  christos #include "services/outside_network.h"
     57      1.1  christos #include "services/outbound_list.h"
     58      1.1  christos #include "services/cache/rrset.h"
     59      1.1  christos #include "services/cache/infra.h"
     60      1.1  christos #include "services/cache/dns.h"
     61  1.1.1.3  christos #include "services/authzone.h"
     62      1.1  christos #include "services/mesh.h"
     63      1.1  christos #include "services/localzone.h"
     64      1.1  christos #include "util/data/msgparse.h"
     65      1.1  christos #include "util/data/msgencode.h"
     66      1.1  christos #include "util/data/dname.h"
     67      1.1  christos #include "util/fptr_wlist.h"
     68      1.1  christos #include "util/tube.h"
     69      1.1  christos #include "iterator/iter_fwd.h"
     70      1.1  christos #include "iterator/iter_hints.h"
     71      1.1  christos #include "validator/autotrust.h"
     72      1.1  christos #include "validator/val_anchor.h"
     73  1.1.1.2  christos #include "respip/respip.h"
     74      1.1  christos #include "libunbound/context.h"
     75      1.1  christos #include "libunbound/libworker.h"
     76      1.1  christos #include "sldns/sbuffer.h"
     77  1.1.1.2  christos #include "sldns/wire2str.h"
     78  1.1.1.2  christos #include "util/shm_side/shm_main.h"
     79  1.1.1.2  christos #include "dnscrypt/dnscrypt.h"
     80      1.1  christos 
     81      1.1  christos #ifdef HAVE_SYS_TYPES_H
     82      1.1  christos #  include <sys/types.h>
     83      1.1  christos #endif
     84      1.1  christos #ifdef HAVE_NETDB_H
     85      1.1  christos #include <netdb.h>
     86      1.1  christos #endif
     87      1.1  christos #include <signal.h>
     88      1.1  christos #ifdef UB_ON_WINDOWS
     89      1.1  christos #include "winrc/win_svc.h"
     90      1.1  christos #endif
     91      1.1  christos 
     92      1.1  christos /** Size of an UDP datagram */
     93      1.1  christos #define NORMAL_UDP_SIZE	512 /* bytes */
     94      1.1  christos /** ratelimit for error responses */
     95      1.1  christos #define ERROR_RATELIMIT 100 /* qps */
     96      1.1  christos 
     97      1.1  christos /**
     98      1.1  christos  * seconds to add to prefetch leeway.  This is a TTL that expires old rrsets
     99      1.1  christos  * earlier than they should in order to put the new update into the cache.
    100      1.1  christos  * This additional value is to make sure that if not all TTLs are equal in
    101      1.1  christos  * the message to be updated(and replaced), that rrsets with up to this much
    102      1.1  christos  * extra TTL are also replaced.  This means that the resulting new message
    103      1.1  christos  * will have (most likely) this TTL at least, avoiding very small 'split
    104      1.1  christos  * second' TTLs due to operators choosing relative primes for TTLs (or so).
    105      1.1  christos  * Also has to be at least one to break ties (and overwrite cached entry).
    106      1.1  christos  */
    107      1.1  christos #define PREFETCH_EXPIRY_ADD 60
    108      1.1  christos 
    109      1.1  christos /** Report on memory usage by this thread and global */
    110      1.1  christos static void
    111      1.1  christos worker_mem_report(struct worker* ATTR_UNUSED(worker),
    112      1.1  christos 	struct serviced_query* ATTR_UNUSED(cur_serv))
    113      1.1  christos {
    114      1.1  christos #ifdef UNBOUND_ALLOC_STATS
    115  1.1.1.2  christos 	/* measure memory leakage */
    116  1.1.1.2  christos 	extern size_t unbound_mem_alloc, unbound_mem_freed;
    117      1.1  christos 	/* debug func in validator module */
    118      1.1  christos 	size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
    119      1.1  christos 	size_t me, iter, val, anch;
    120      1.1  christos 	int i;
    121  1.1.1.2  christos #ifdef CLIENT_SUBNET
    122  1.1.1.2  christos 	size_t subnet = 0;
    123  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    124      1.1  christos 	if(verbosity < VERB_ALGO)
    125      1.1  christos 		return;
    126      1.1  christos 	front = listen_get_mem(worker->front);
    127      1.1  christos 	back = outnet_get_mem(worker->back);
    128      1.1  christos 	msg = slabhash_get_mem(worker->env.msg_cache);
    129      1.1  christos 	rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
    130      1.1  christos 	infra = infra_get_mem(worker->env.infra_cache);
    131      1.1  christos 	mesh = mesh_get_mem(worker->env.mesh);
    132      1.1  christos 	ac = alloc_get_mem(&worker->alloc);
    133      1.1  christos 	superac = alloc_get_mem(&worker->daemon->superalloc);
    134      1.1  christos 	anch = anchors_get_mem(worker->env.anchors);
    135      1.1  christos 	iter = 0;
    136      1.1  christos 	val = 0;
    137      1.1  christos 	for(i=0; i<worker->env.mesh->mods.num; i++) {
    138      1.1  christos 		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
    139      1.1  christos 			mods.mod[i]->get_mem));
    140      1.1  christos 		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
    141      1.1  christos 			val += (*worker->env.mesh->mods.mod[i]->get_mem)
    142      1.1  christos 				(&worker->env, i);
    143  1.1.1.2  christos #ifdef CLIENT_SUBNET
    144  1.1.1.2  christos 		else if(strcmp(worker->env.mesh->mods.mod[i]->name,
    145  1.1.1.2  christos 			"subnet")==0)
    146  1.1.1.2  christos 			subnet += (*worker->env.mesh->mods.mod[i]->get_mem)
    147  1.1.1.2  christos 				(&worker->env, i);
    148  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    149      1.1  christos 		else	iter += (*worker->env.mesh->mods.mod[i]->get_mem)
    150      1.1  christos 				(&worker->env, i);
    151      1.1  christos 	}
    152      1.1  christos 	me = sizeof(*worker) + sizeof(*worker->base) + sizeof(*worker->comsig)
    153      1.1  christos 		+ comm_point_get_mem(worker->cmd_com)
    154      1.1  christos 		+ sizeof(worker->rndstate)
    155      1.1  christos 		+ regional_get_mem(worker->scratchpad)
    156      1.1  christos 		+ sizeof(*worker->env.scratch_buffer)
    157      1.1  christos 		+ sldns_buffer_capacity(worker->env.scratch_buffer)
    158      1.1  christos 		+ forwards_get_mem(worker->env.fwds)
    159      1.1  christos 		+ hints_get_mem(worker->env.hints);
    160      1.1  christos 	if(worker->thread_num == 0)
    161      1.1  christos 		me += acl_list_get_mem(worker->daemon->acl);
    162      1.1  christos 	if(cur_serv) {
    163      1.1  christos 		me += serviced_get_mem(cur_serv);
    164      1.1  christos 	}
    165      1.1  christos 	total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me;
    166  1.1.1.2  christos #ifdef CLIENT_SUBNET
    167  1.1.1.2  christos 	total += subnet;
    168  1.1.1.2  christos 	log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
    169  1.1.1.2  christos 		"rrset=%u infra=%u iter=%u val=%u subnet=%u anchors=%u "
    170  1.1.1.2  christos 		"alloccache=%u globalalloccache=%u me=%u",
    171  1.1.1.2  christos 		(unsigned)total, (unsigned)front, (unsigned)back,
    172  1.1.1.2  christos 		(unsigned)mesh, (unsigned)msg, (unsigned)rrset, (unsigned)infra,
    173  1.1.1.2  christos 		(unsigned)iter, (unsigned)val,
    174  1.1.1.2  christos 		(unsigned)subnet, (unsigned)anch, (unsigned)ac,
    175  1.1.1.2  christos 		(unsigned)superac, (unsigned)me);
    176  1.1.1.2  christos #else /* no CLIENT_SUBNET */
    177      1.1  christos 	log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
    178      1.1  christos 		"rrset=%u infra=%u iter=%u val=%u anchors=%u "
    179      1.1  christos 		"alloccache=%u globalalloccache=%u me=%u",
    180      1.1  christos 		(unsigned)total, (unsigned)front, (unsigned)back,
    181      1.1  christos 		(unsigned)mesh, (unsigned)msg, (unsigned)rrset,
    182      1.1  christos 		(unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch,
    183      1.1  christos 		(unsigned)ac, (unsigned)superac, (unsigned)me);
    184  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    185  1.1.1.2  christos 	log_info("Total heap memory estimate: %u  total-alloc: %u  "
    186  1.1.1.2  christos 		"total-free: %u", (unsigned)total,
    187  1.1.1.2  christos 		(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
    188      1.1  christos #else /* no UNBOUND_ALLOC_STATS */
    189      1.1  christos 	size_t val = 0;
    190  1.1.1.2  christos #ifdef CLIENT_SUBNET
    191  1.1.1.2  christos 	size_t subnet = 0;
    192  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    193      1.1  christos 	int i;
    194      1.1  christos 	if(verbosity < VERB_QUERY)
    195      1.1  christos 		return;
    196      1.1  christos 	for(i=0; i<worker->env.mesh->mods.num; i++) {
    197      1.1  christos 		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
    198      1.1  christos 			mods.mod[i]->get_mem));
    199      1.1  christos 		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
    200      1.1  christos 			val += (*worker->env.mesh->mods.mod[i]->get_mem)
    201      1.1  christos 				(&worker->env, i);
    202  1.1.1.2  christos #ifdef CLIENT_SUBNET
    203  1.1.1.2  christos 		else if(strcmp(worker->env.mesh->mods.mod[i]->name,
    204  1.1.1.2  christos 			"subnet")==0)
    205  1.1.1.2  christos 			subnet += (*worker->env.mesh->mods.mod[i]->get_mem)
    206  1.1.1.2  christos 				(&worker->env, i);
    207  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    208      1.1  christos 	}
    209  1.1.1.2  christos #ifdef CLIENT_SUBNET
    210  1.1.1.2  christos 	verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u "
    211  1.1.1.2  christos 		"subnet=%u",
    212  1.1.1.2  christos 		(unsigned)slabhash_get_mem(worker->env.msg_cache),
    213  1.1.1.2  christos 		(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
    214  1.1.1.2  christos 		(unsigned)infra_get_mem(worker->env.infra_cache),
    215  1.1.1.2  christos 		(unsigned)val, (unsigned)subnet);
    216  1.1.1.2  christos #else /* no CLIENT_SUBNET */
    217      1.1  christos 	verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u",
    218      1.1  christos 		(unsigned)slabhash_get_mem(worker->env.msg_cache),
    219      1.1  christos 		(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
    220      1.1  christos 		(unsigned)infra_get_mem(worker->env.infra_cache),
    221      1.1  christos 		(unsigned)val);
    222  1.1.1.2  christos #endif /* CLIENT_SUBNET */
    223      1.1  christos #endif /* UNBOUND_ALLOC_STATS */
    224      1.1  christos }
    225      1.1  christos 
    226      1.1  christos void
    227      1.1  christos worker_send_cmd(struct worker* worker, enum worker_commands cmd)
    228      1.1  christos {
    229      1.1  christos 	uint32_t c = (uint32_t)htonl(cmd);
    230      1.1  christos 	if(!tube_write_msg(worker->cmd, (uint8_t*)&c, sizeof(c), 0)) {
    231      1.1  christos 		log_err("worker send cmd %d failed", (int)cmd);
    232      1.1  christos 	}
    233      1.1  christos }
    234      1.1  christos 
    235      1.1  christos int
    236      1.1  christos worker_handle_reply(struct comm_point* c, void* arg, int error,
    237      1.1  christos 	struct comm_reply* reply_info)
    238      1.1  christos {
    239      1.1  christos 	struct module_qstate* q = (struct module_qstate*)arg;
    240      1.1  christos 	struct worker* worker = q->env->worker;
    241      1.1  christos 	struct outbound_entry e;
    242      1.1  christos 	e.qstate = q;
    243      1.1  christos 	e.qsent = NULL;
    244      1.1  christos 
    245      1.1  christos 	if(error != 0) {
    246      1.1  christos 		mesh_report_reply(worker->env.mesh, &e, reply_info, error);
    247      1.1  christos 		worker_mem_report(worker, NULL);
    248      1.1  christos 		return 0;
    249      1.1  christos 	}
    250      1.1  christos 	/* sanity check. */
    251      1.1  christos 	if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
    252      1.1  christos 		|| LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
    253      1.1  christos 			LDNS_PACKET_QUERY
    254      1.1  christos 		|| LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
    255      1.1  christos 		/* error becomes timeout for the module as if this reply
    256      1.1  christos 		 * never arrived. */
    257      1.1  christos 		mesh_report_reply(worker->env.mesh, &e, reply_info,
    258      1.1  christos 			NETEVENT_TIMEOUT);
    259      1.1  christos 		worker_mem_report(worker, NULL);
    260      1.1  christos 		return 0;
    261      1.1  christos 	}
    262      1.1  christos 	mesh_report_reply(worker->env.mesh, &e, reply_info, NETEVENT_NOERROR);
    263      1.1  christos 	worker_mem_report(worker, NULL);
    264      1.1  christos 	return 0;
    265      1.1  christos }
    266      1.1  christos 
    267      1.1  christos int
    268      1.1  christos worker_handle_service_reply(struct comm_point* c, void* arg, int error,
    269      1.1  christos 	struct comm_reply* reply_info)
    270      1.1  christos {
    271      1.1  christos 	struct outbound_entry* e = (struct outbound_entry*)arg;
    272      1.1  christos 	struct worker* worker = e->qstate->env->worker;
    273      1.1  christos 	struct serviced_query *sq = e->qsent;
    274      1.1  christos 
    275      1.1  christos 	verbose(VERB_ALGO, "worker svcd callback for qstate %p", e->qstate);
    276      1.1  christos 	if(error != 0) {
    277      1.1  christos 		mesh_report_reply(worker->env.mesh, e, reply_info, error);
    278      1.1  christos 		worker_mem_report(worker, sq);
    279      1.1  christos 		return 0;
    280      1.1  christos 	}
    281      1.1  christos 	/* sanity check. */
    282      1.1  christos 	if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
    283      1.1  christos 		|| LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
    284      1.1  christos 			LDNS_PACKET_QUERY
    285      1.1  christos 		|| LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
    286      1.1  christos 		/* error becomes timeout for the module as if this reply
    287      1.1  christos 		 * never arrived. */
    288      1.1  christos 		verbose(VERB_ALGO, "worker: bad reply handled as timeout");
    289      1.1  christos 		mesh_report_reply(worker->env.mesh, e, reply_info,
    290      1.1  christos 			NETEVENT_TIMEOUT);
    291      1.1  christos 		worker_mem_report(worker, sq);
    292      1.1  christos 		return 0;
    293      1.1  christos 	}
    294      1.1  christos 	mesh_report_reply(worker->env.mesh, e, reply_info, NETEVENT_NOERROR);
    295      1.1  christos 	worker_mem_report(worker, sq);
    296      1.1  christos 	return 0;
    297      1.1  christos }
    298      1.1  christos 
    299      1.1  christos /** ratelimit error replies
    300      1.1  christos  * @param worker: the worker struct with ratelimit counter
    301      1.1  christos  * @param err: error code that would be wanted.
    302      1.1  christos  * @return value of err if okay, or -1 if it should be discarded instead.
    303      1.1  christos  */
    304      1.1  christos static int
    305      1.1  christos worker_err_ratelimit(struct worker* worker, int err)
    306      1.1  christos {
    307      1.1  christos 	if(worker->err_limit_time == *worker->env.now) {
    308      1.1  christos 		/* see if limit is exceeded for this second */
    309      1.1  christos 		if(worker->err_limit_count++ > ERROR_RATELIMIT)
    310      1.1  christos 			return -1;
    311      1.1  christos 	} else {
    312      1.1  christos 		/* new second, new limits */
    313      1.1  christos 		worker->err_limit_time = *worker->env.now;
    314      1.1  christos 		worker->err_limit_count = 1;
    315      1.1  christos 	}
    316      1.1  christos 	return err;
    317      1.1  christos }
    318      1.1  christos 
    319      1.1  christos /** check request sanity.
    320      1.1  christos  * @param pkt: the wire packet to examine for sanity.
    321      1.1  christos  * @param worker: parameters for checking.
    322      1.1  christos  * @return error code, 0 OK, or -1 discard.
    323      1.1  christos */
    324      1.1  christos static int
    325      1.1  christos worker_check_request(sldns_buffer* pkt, struct worker* worker)
    326      1.1  christos {
    327      1.1  christos 	if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
    328      1.1  christos 		verbose(VERB_QUERY, "request too short, discarded");
    329      1.1  christos 		return -1;
    330      1.1  christos 	}
    331      1.1  christos 	if(sldns_buffer_limit(pkt) > NORMAL_UDP_SIZE &&
    332      1.1  christos 		worker->daemon->cfg->harden_large_queries) {
    333      1.1  christos 		verbose(VERB_QUERY, "request too large, discarded");
    334      1.1  christos 		return -1;
    335      1.1  christos 	}
    336      1.1  christos 	if(LDNS_QR_WIRE(sldns_buffer_begin(pkt))) {
    337      1.1  christos 		verbose(VERB_QUERY, "request has QR bit on, discarded");
    338      1.1  christos 		return -1;
    339      1.1  christos 	}
    340      1.1  christos 	if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
    341      1.1  christos 		LDNS_TC_CLR(sldns_buffer_begin(pkt));
    342      1.1  christos 		verbose(VERB_QUERY, "request bad, has TC bit on");
    343      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
    344      1.1  christos 	}
    345  1.1.1.3  christos 	if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY &&
    346  1.1.1.3  christos 		LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) {
    347      1.1  christos 		verbose(VERB_QUERY, "request unknown opcode %d",
    348      1.1  christos 			LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
    349      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
    350      1.1  christos 	}
    351      1.1  christos 	if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
    352      1.1  christos 		verbose(VERB_QUERY, "request wrong nr qd=%d",
    353      1.1  christos 			LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
    354      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
    355      1.1  christos 	}
    356  1.1.1.3  christos 	if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 &&
    357  1.1.1.3  christos 		(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 ||
    358  1.1.1.3  christos 		LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) {
    359      1.1  christos 		verbose(VERB_QUERY, "request wrong nr an=%d",
    360      1.1  christos 			LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
    361      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
    362      1.1  christos 	}
    363      1.1  christos 	if(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
    364      1.1  christos 		verbose(VERB_QUERY, "request wrong nr ns=%d",
    365      1.1  christos 			LDNS_NSCOUNT(sldns_buffer_begin(pkt)));
    366      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
    367      1.1  christos 	}
    368      1.1  christos 	if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
    369      1.1  christos 		verbose(VERB_QUERY, "request wrong nr ar=%d",
    370      1.1  christos 			LDNS_ARCOUNT(sldns_buffer_begin(pkt)));
    371      1.1  christos 		return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
    372      1.1  christos 	}
    373      1.1  christos 	return 0;
    374      1.1  christos }
    375      1.1  christos 
    376      1.1  christos void
    377      1.1  christos worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
    378      1.1  christos 	size_t len, int error, void* arg)
    379      1.1  christos {
    380      1.1  christos 	struct worker* worker = (struct worker*)arg;
    381      1.1  christos 	enum worker_commands cmd;
    382      1.1  christos 	if(error != NETEVENT_NOERROR) {
    383      1.1  christos 		free(msg);
    384      1.1  christos 		if(error == NETEVENT_CLOSED)
    385      1.1  christos 			comm_base_exit(worker->base);
    386      1.1  christos 		else	log_info("control event: %d", error);
    387      1.1  christos 		return;
    388      1.1  christos 	}
    389      1.1  christos 	if(len != sizeof(uint32_t)) {
    390      1.1  christos 		fatal_exit("bad control msg length %d", (int)len);
    391      1.1  christos 	}
    392      1.1  christos 	cmd = sldns_read_uint32(msg);
    393      1.1  christos 	free(msg);
    394      1.1  christos 	switch(cmd) {
    395      1.1  christos 	case worker_cmd_quit:
    396      1.1  christos 		verbose(VERB_ALGO, "got control cmd quit");
    397      1.1  christos 		comm_base_exit(worker->base);
    398      1.1  christos 		break;
    399      1.1  christos 	case worker_cmd_stats:
    400      1.1  christos 		verbose(VERB_ALGO, "got control cmd stats");
    401      1.1  christos 		server_stats_reply(worker, 1);
    402      1.1  christos 		break;
    403      1.1  christos 	case worker_cmd_stats_noreset:
    404      1.1  christos 		verbose(VERB_ALGO, "got control cmd stats_noreset");
    405      1.1  christos 		server_stats_reply(worker, 0);
    406      1.1  christos 		break;
    407      1.1  christos 	case worker_cmd_remote:
    408      1.1  christos 		verbose(VERB_ALGO, "got control cmd remote");
    409      1.1  christos 		daemon_remote_exec(worker);
    410      1.1  christos 		break;
    411      1.1  christos 	default:
    412      1.1  christos 		log_err("bad command %d", (int)cmd);
    413      1.1  christos 		break;
    414      1.1  christos 	}
    415      1.1  christos }
    416      1.1  christos 
    417      1.1  christos /** check if a delegation is secure */
    418      1.1  christos static enum sec_status
    419      1.1  christos check_delegation_secure(struct reply_info *rep)
    420      1.1  christos {
    421      1.1  christos 	/* return smallest security status */
    422      1.1  christos 	size_t i;
    423      1.1  christos 	enum sec_status sec = sec_status_secure;
    424      1.1  christos 	enum sec_status s;
    425      1.1  christos 	size_t num = rep->an_numrrsets + rep->ns_numrrsets;
    426      1.1  christos 	/* check if answer and authority are OK */
    427      1.1  christos 	for(i=0; i<num; i++) {
    428      1.1  christos 		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
    429      1.1  christos 			->security;
    430      1.1  christos 		if(s < sec)
    431      1.1  christos 			sec = s;
    432      1.1  christos 	}
    433      1.1  christos 	/* in additional, only unchecked triggers revalidation */
    434      1.1  christos 	for(i=num; i<rep->rrset_count; i++) {
    435      1.1  christos 		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
    436      1.1  christos 			->security;
    437      1.1  christos 		if(s == sec_status_unchecked)
    438      1.1  christos 			return s;
    439      1.1  christos 	}
    440      1.1  christos 	return sec;
    441      1.1  christos }
    442      1.1  christos 
    443      1.1  christos /** remove nonsecure from a delegation referral additional section */
    444      1.1  christos static void
    445      1.1  christos deleg_remove_nonsecure_additional(struct reply_info* rep)
    446      1.1  christos {
    447      1.1  christos 	/* we can simply edit it, since we are working in the scratch region */
    448      1.1  christos 	size_t i;
    449      1.1  christos 	enum sec_status s;
    450      1.1  christos 
    451      1.1  christos 	for(i = rep->an_numrrsets+rep->ns_numrrsets; i<rep->rrset_count; i++) {
    452      1.1  christos 		s = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)
    453      1.1  christos 			->security;
    454      1.1  christos 		if(s != sec_status_secure) {
    455      1.1  christos 			memmove(rep->rrsets+i, rep->rrsets+i+1,
    456      1.1  christos 				sizeof(struct ub_packed_rrset_key*)*
    457      1.1  christos 				(rep->rrset_count - i - 1));
    458      1.1  christos 			rep->ar_numrrsets--;
    459      1.1  christos 			rep->rrset_count--;
    460      1.1  christos 			i--;
    461      1.1  christos 		}
    462      1.1  christos 	}
    463      1.1  christos }
    464      1.1  christos 
    465      1.1  christos /** answer nonrecursive query from the cache */
    466      1.1  christos static int
    467      1.1  christos answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
    468      1.1  christos 	uint16_t id, uint16_t flags, struct comm_reply* repinfo,
    469      1.1  christos 	struct edns_data* edns)
    470      1.1  christos {
    471      1.1  christos 	/* for a nonrecursive query return either:
    472      1.1  christos 	 * 	o an error (servfail; we try to avoid this)
    473      1.1  christos 	 * 	o a delegation (closest we have; this routine tries that)
    474      1.1  christos 	 * 	o the answer (checked by answer_from_cache)
    475      1.1  christos 	 *
    476      1.1  christos 	 * So, grab a delegation from the rrset cache.
    477      1.1  christos 	 * Then check if it needs validation, if so, this routine fails,
    478      1.1  christos 	 * so that iterator can prime and validator can verify rrsets.
    479      1.1  christos 	 */
    480      1.1  christos 	uint16_t udpsize = edns->udp_size;
    481      1.1  christos 	int secure = 0;
    482      1.1  christos 	time_t timenow = *worker->env.now;
    483      1.1  christos 	int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
    484      1.1  christos 		&& worker->env.need_to_validate;
    485      1.1  christos 	struct dns_msg *msg = NULL;
    486      1.1  christos 	struct delegpt *dp;
    487      1.1  christos 
    488      1.1  christos 	dp = dns_cache_find_delegation(&worker->env, qinfo->qname,
    489      1.1  christos 		qinfo->qname_len, qinfo->qtype, qinfo->qclass,
    490      1.1  christos 		worker->scratchpad, &msg, timenow);
    491      1.1  christos 	if(!dp) { /* no delegation, need to reprime */
    492      1.1  christos 		return 0;
    493      1.1  christos 	}
    494  1.1.1.2  christos 	/* In case we have a local alias, copy it into the delegation message.
    495  1.1.1.2  christos 	 * Shallow copy should be fine, as we'll be done with msg in this
    496  1.1.1.2  christos 	 * function. */
    497  1.1.1.2  christos 	msg->qinfo.local_alias = qinfo->local_alias;
    498      1.1  christos 	if(must_validate) {
    499      1.1  christos 		switch(check_delegation_secure(msg->rep)) {
    500      1.1  christos 		case sec_status_unchecked:
    501      1.1  christos 			/* some rrsets have not been verified yet, go and
    502      1.1  christos 			 * let validator do that */
    503      1.1  christos 			return 0;
    504      1.1  christos 		case sec_status_bogus:
    505  1.1.1.3  christos 		case sec_status_secure_sentinel_fail:
    506      1.1  christos 			/* some rrsets are bogus, reply servfail */
    507      1.1  christos 			edns->edns_version = EDNS_ADVERTISED_VERSION;
    508      1.1  christos 			edns->udp_size = EDNS_ADVERTISED_SIZE;
    509      1.1  christos 			edns->ext_rcode = 0;
    510      1.1  christos 			edns->bits &= EDNS_DO;
    511  1.1.1.2  christos 			if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
    512  1.1.1.2  christos 				msg->rep, LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
    513  1.1.1.2  christos 					return 0;
    514      1.1  christos 			error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
    515      1.1  christos 				&msg->qinfo, id, flags, edns);
    516      1.1  christos 			if(worker->stats.extended) {
    517      1.1  christos 				worker->stats.ans_bogus++;
    518      1.1  christos 				worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL]++;
    519      1.1  christos 			}
    520      1.1  christos 			return 1;
    521      1.1  christos 		case sec_status_secure:
    522      1.1  christos 			/* all rrsets are secure */
    523      1.1  christos 			/* remove non-secure rrsets from the add. section*/
    524      1.1  christos 			if(worker->env.cfg->val_clean_additional)
    525      1.1  christos 				deleg_remove_nonsecure_additional(msg->rep);
    526      1.1  christos 			secure = 1;
    527      1.1  christos 			break;
    528      1.1  christos 		case sec_status_indeterminate:
    529      1.1  christos 		case sec_status_insecure:
    530      1.1  christos 		default:
    531      1.1  christos 			/* not secure */
    532      1.1  christos 			secure = 0;
    533      1.1  christos 			break;
    534      1.1  christos 		}
    535      1.1  christos 	}
    536      1.1  christos 	/* return this delegation from the cache */
    537      1.1  christos 	edns->edns_version = EDNS_ADVERTISED_VERSION;
    538      1.1  christos 	edns->udp_size = EDNS_ADVERTISED_SIZE;
    539      1.1  christos 	edns->ext_rcode = 0;
    540      1.1  christos 	edns->bits &= EDNS_DO;
    541  1.1.1.2  christos 	if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
    542  1.1.1.2  christos 		(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
    543  1.1.1.2  christos 			return 0;
    544      1.1  christos 	msg->rep->flags |= BIT_QR|BIT_RA;
    545      1.1  christos 	if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
    546      1.1  christos 		repinfo->c->buffer, 0, 1, worker->scratchpad,
    547      1.1  christos 		udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
    548  1.1.1.2  christos 		if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
    549  1.1.1.2  christos 			LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
    550  1.1.1.2  christos 				edns->opt_list = NULL;
    551      1.1  christos 		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
    552      1.1  christos 			&msg->qinfo, id, flags, edns);
    553      1.1  christos 	}
    554      1.1  christos 	if(worker->stats.extended) {
    555      1.1  christos 		if(secure) worker->stats.ans_secure++;
    556      1.1  christos 		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
    557      1.1  christos 	}
    558      1.1  christos 	return 1;
    559      1.1  christos }
    560      1.1  christos 
    561  1.1.1.2  christos /** Apply, if applicable, a response IP action to a cached answer.
    562  1.1.1.2  christos  * If the answer is rewritten as a result of an action, '*encode_repp' will
    563  1.1.1.2  christos  * point to the reply info containing the modified answer.  '*encode_repp' will
    564  1.1.1.2  christos  * be intact otherwise.
    565  1.1.1.2  christos  * It returns 1 on success, 0 otherwise. */
    566  1.1.1.2  christos static int
    567  1.1.1.2  christos apply_respip_action(struct worker* worker, const struct query_info* qinfo,
    568  1.1.1.2  christos 	struct respip_client_info* cinfo, struct reply_info* rep,
    569  1.1.1.2  christos 	struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
    570  1.1.1.2  christos 	struct reply_info** encode_repp)
    571  1.1.1.2  christos {
    572  1.1.1.2  christos 	struct respip_action_info actinfo = {respip_none, NULL};
    573  1.1.1.2  christos 
    574  1.1.1.2  christos 	if(qinfo->qtype != LDNS_RR_TYPE_A &&
    575  1.1.1.2  christos 		qinfo->qtype != LDNS_RR_TYPE_AAAA &&
    576  1.1.1.2  christos 		qinfo->qtype != LDNS_RR_TYPE_ANY)
    577  1.1.1.2  christos 		return 1;
    578  1.1.1.2  christos 
    579  1.1.1.2  christos 	if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
    580  1.1.1.2  christos 		alias_rrset, 0, worker->scratchpad))
    581  1.1.1.2  christos 		return 0;
    582  1.1.1.2  christos 
    583  1.1.1.2  christos 	/* xxx_deny actions mean dropping the reply, unless the original reply
    584  1.1.1.2  christos 	 * was redirected to response-ip data. */
    585  1.1.1.2  christos 	if((actinfo.action == respip_deny ||
    586  1.1.1.2  christos 		actinfo.action == respip_inform_deny) &&
    587  1.1.1.2  christos 		*encode_repp == rep)
    588  1.1.1.2  christos 		*encode_repp = NULL;
    589  1.1.1.2  christos 
    590  1.1.1.2  christos 	/* If address info is returned, it means the action should be an
    591  1.1.1.2  christos 	 * 'inform' variant and the information should be logged. */
    592  1.1.1.2  christos 	if(actinfo.addrinfo) {
    593  1.1.1.2  christos 		respip_inform_print(actinfo.addrinfo, qinfo->qname,
    594  1.1.1.2  christos 			qinfo->qtype, qinfo->qclass, qinfo->local_alias,
    595  1.1.1.2  christos 			repinfo);
    596  1.1.1.2  christos 	}
    597  1.1.1.2  christos 
    598  1.1.1.2  christos 	return 1;
    599  1.1.1.2  christos }
    600  1.1.1.2  christos 
    601  1.1.1.2  christos /** answer query from the cache.
    602  1.1.1.2  christos  * Normally, the answer message will be built in repinfo->c->buffer; if the
    603  1.1.1.2  christos  * answer is supposed to be suppressed or the answer is supposed to be an
    604  1.1.1.2  christos  * incomplete CNAME chain, the buffer is explicitly cleared to signal the
    605  1.1.1.2  christos  * caller as such.  In the latter case *partial_rep will point to the incomplete
    606  1.1.1.2  christos  * reply, and this function is (possibly) supposed to be called again with that
    607  1.1.1.2  christos  * *partial_rep value to complete the chain.  In addition, if the query should
    608  1.1.1.2  christos  * be completely dropped, '*need_drop' will be set to 1. */
    609      1.1  christos static int
    610      1.1  christos answer_from_cache(struct worker* worker, struct query_info* qinfo,
    611  1.1.1.2  christos 	struct respip_client_info* cinfo, int* need_drop,
    612  1.1.1.2  christos 	struct ub_packed_rrset_key** alias_rrset,
    613  1.1.1.2  christos 	struct reply_info** partial_repp,
    614      1.1  christos 	struct reply_info* rep, uint16_t id, uint16_t flags,
    615      1.1  christos 	struct comm_reply* repinfo, struct edns_data* edns)
    616      1.1  christos {
    617      1.1  christos 	time_t timenow = *worker->env.now;
    618      1.1  christos 	uint16_t udpsize = edns->udp_size;
    619  1.1.1.2  christos 	struct reply_info* encode_rep = rep;
    620  1.1.1.2  christos 	struct reply_info* partial_rep = *partial_repp;
    621      1.1  christos 	int secure;
    622      1.1  christos 	int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
    623      1.1  christos 		&& worker->env.need_to_validate;
    624  1.1.1.2  christos 	*partial_repp = NULL;	/* avoid accidental further pass */
    625  1.1.1.2  christos 	if(worker->env.cfg->serve_expired) {
    626  1.1.1.2  christos 		/* always lock rrsets, rep->ttl is ignored */
    627  1.1.1.2  christos 		if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
    628  1.1.1.2  christos 			return 0;
    629  1.1.1.2  christos 		/* below, rrsets with ttl before timenow become TTL 0 in
    630  1.1.1.2  christos 		 * the response */
    631  1.1.1.2  christos 		/* This response was served with zero TTL */
    632  1.1.1.2  christos 		if (timenow >= rep->ttl) {
    633  1.1.1.2  christos 			worker->stats.zero_ttl_responses++;
    634  1.1.1.2  christos 		}
    635  1.1.1.2  christos 	} else {
    636  1.1.1.2  christos 		/* see if it is possible */
    637  1.1.1.2  christos 		if(rep->ttl < timenow) {
    638  1.1.1.2  christos 			/* the rrsets may have been updated in the meantime.
    639  1.1.1.2  christos 			 * we will refetch the message format from the
    640  1.1.1.2  christos 			 * authoritative server
    641  1.1.1.2  christos 			 */
    642  1.1.1.2  christos 			return 0;
    643  1.1.1.2  christos 		}
    644  1.1.1.2  christos 		if(!rrset_array_lock(rep->ref, rep->rrset_count, timenow))
    645  1.1.1.2  christos 			return 0;
    646  1.1.1.2  christos 		/* locked and ids and ttls are OK. */
    647      1.1  christos 	}
    648      1.1  christos 	/* check CNAME chain (if any) */
    649      1.1  christos 	if(rep->an_numrrsets > 0 && (rep->rrsets[0]->rk.type ==
    650      1.1  christos 		htons(LDNS_RR_TYPE_CNAME) || rep->rrsets[0]->rk.type ==
    651      1.1  christos 		htons(LDNS_RR_TYPE_DNAME))) {
    652      1.1  christos 		if(!reply_check_cname_chain(qinfo, rep)) {
    653      1.1  christos 			/* cname chain invalid, redo iterator steps */
    654      1.1  christos 			verbose(VERB_ALGO, "Cache reply: cname chain broken");
    655      1.1  christos 		bail_out:
    656      1.1  christos 			rrset_array_unlock_touch(worker->env.rrset_cache,
    657      1.1  christos 				worker->scratchpad, rep->ref, rep->rrset_count);
    658      1.1  christos 			return 0;
    659      1.1  christos 		}
    660      1.1  christos 	}
    661      1.1  christos 	/* check security status of the cached answer */
    662  1.1.1.3  christos 	if(must_validate && (rep->security == sec_status_bogus ||
    663  1.1.1.3  christos 		rep->security == sec_status_secure_sentinel_fail)) {
    664      1.1  christos 		/* BAD cached */
    665      1.1  christos 		edns->edns_version = EDNS_ADVERTISED_VERSION;
    666      1.1  christos 		edns->udp_size = EDNS_ADVERTISED_SIZE;
    667      1.1  christos 		edns->ext_rcode = 0;
    668      1.1  christos 		edns->bits &= EDNS_DO;
    669  1.1.1.2  christos 		if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
    670  1.1.1.2  christos 			LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
    671  1.1.1.2  christos 			goto bail_out;
    672      1.1  christos 		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
    673      1.1  christos 			qinfo, id, flags, edns);
    674      1.1  christos 		rrset_array_unlock_touch(worker->env.rrset_cache,
    675      1.1  christos 			worker->scratchpad, rep->ref, rep->rrset_count);
    676      1.1  christos 		if(worker->stats.extended) {
    677      1.1  christos 			worker->stats.ans_bogus ++;
    678      1.1  christos 			worker->stats.ans_rcode[LDNS_RCODE_SERVFAIL] ++;
    679      1.1  christos 		}
    680      1.1  christos 		return 1;
    681      1.1  christos 	} else if( rep->security == sec_status_unchecked && must_validate) {
    682      1.1  christos 		verbose(VERB_ALGO, "Cache reply: unchecked entry needs "
    683      1.1  christos 			"validation");
    684      1.1  christos 		goto bail_out; /* need to validate cache entry first */
    685      1.1  christos 	} else if(rep->security == sec_status_secure) {
    686      1.1  christos 		if(reply_all_rrsets_secure(rep))
    687      1.1  christos 			secure = 1;
    688      1.1  christos 		else	{
    689      1.1  christos 			if(must_validate) {
    690      1.1  christos 				verbose(VERB_ALGO, "Cache reply: secure entry"
    691      1.1  christos 					" changed status");
    692      1.1  christos 				goto bail_out; /* rrset changed, re-verify */
    693      1.1  christos 			}
    694      1.1  christos 			secure = 0;
    695      1.1  christos 		}
    696      1.1  christos 	} else	secure = 0;
    697      1.1  christos 
    698      1.1  christos 	edns->edns_version = EDNS_ADVERTISED_VERSION;
    699      1.1  christos 	edns->udp_size = EDNS_ADVERTISED_SIZE;
    700      1.1  christos 	edns->ext_rcode = 0;
    701      1.1  christos 	edns->bits &= EDNS_DO;
    702  1.1.1.2  christos 	if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
    703  1.1.1.2  christos 		(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
    704  1.1.1.2  christos 		goto bail_out;
    705  1.1.1.2  christos 	*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
    706  1.1.1.2  christos 	if(worker->daemon->use_response_ip && !partial_rep &&
    707  1.1.1.2  christos 	   !apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset,
    708  1.1.1.2  christos 			&encode_rep)) {
    709  1.1.1.2  christos 		goto bail_out;
    710  1.1.1.2  christos 	} else if(partial_rep &&
    711  1.1.1.2  christos 		!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
    712  1.1.1.2  christos 		must_validate, &encode_rep, worker->scratchpad)) {
    713  1.1.1.2  christos 		goto bail_out;
    714  1.1.1.2  christos 	}
    715  1.1.1.2  christos 	if(encode_rep != rep)
    716  1.1.1.2  christos 		secure = 0; /* if rewritten, it can't be considered "secure" */
    717  1.1.1.2  christos 	if(!encode_rep || *alias_rrset) {
    718  1.1.1.2  christos 		sldns_buffer_clear(repinfo->c->buffer);
    719  1.1.1.2  christos 		sldns_buffer_flip(repinfo->c->buffer);
    720  1.1.1.2  christos 		if(!encode_rep)
    721  1.1.1.2  christos 			*need_drop = 1;
    722  1.1.1.2  christos 		else {
    723  1.1.1.2  christos 			/* If a partial CNAME chain is found, we first need to
    724  1.1.1.2  christos 			 * make a copy of the reply in the scratchpad so we
    725  1.1.1.2  christos 			 * can release the locks and lookup the cache again. */
    726  1.1.1.2  christos 			*partial_repp = reply_info_copy(encode_rep, NULL,
    727  1.1.1.2  christos 				worker->scratchpad);
    728  1.1.1.2  christos 			if(!*partial_repp)
    729  1.1.1.2  christos 				goto bail_out;
    730  1.1.1.2  christos 		}
    731  1.1.1.2  christos 	} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
    732      1.1  christos 		repinfo->c->buffer, timenow, 1, worker->scratchpad,
    733      1.1  christos 		udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
    734  1.1.1.2  christos 		if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
    735  1.1.1.2  christos 			LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
    736  1.1.1.2  christos 				edns->opt_list = NULL;
    737      1.1  christos 		error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
    738      1.1  christos 			qinfo, id, flags, edns);
    739      1.1  christos 	}
    740      1.1  christos 	/* cannot send the reply right now, because blocking network syscall
    741      1.1  christos 	 * is bad while holding locks. */
    742      1.1  christos 	rrset_array_unlock_touch(worker->env.rrset_cache, worker->scratchpad,
    743      1.1  christos 		rep->ref, rep->rrset_count);
    744      1.1  christos 	if(worker->stats.extended) {
    745      1.1  christos 		if(secure) worker->stats.ans_secure++;
    746      1.1  christos 		server_stats_insrcode(&worker->stats, repinfo->c->buffer);
    747      1.1  christos 	}
    748      1.1  christos 	/* go and return this buffer to the client */
    749      1.1  christos 	return 1;
    750      1.1  christos }
    751      1.1  christos 
    752  1.1.1.2  christos /** Reply to client and perform prefetch to keep cache up to date.
    753  1.1.1.2  christos  * If the buffer for the reply is empty, it indicates that only prefetch is
    754  1.1.1.2  christos  * necessary and the reply should be suppressed (because it's dropped or
    755  1.1.1.2  christos  * being deferred). */
    756      1.1  christos static void
    757      1.1  christos reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
    758      1.1  christos 	uint16_t flags, struct comm_reply* repinfo, time_t leeway)
    759      1.1  christos {
    760      1.1  christos 	/* first send answer to client to keep its latency
    761      1.1  christos 	 * as small as a cachereply */
    762  1.1.1.2  christos 	if(sldns_buffer_limit(repinfo->c->buffer) != 0)
    763  1.1.1.2  christos 		comm_point_send_reply(repinfo);
    764      1.1  christos 	server_stats_prefetch(&worker->stats, worker);
    765      1.1  christos 
    766      1.1  christos 	/* create the prefetch in the mesh as a normal lookup without
    767      1.1  christos 	 * client addrs waiting, which has the cache blacklisted (to bypass
    768      1.1  christos 	 * the cache and go to the network for the data). */
    769      1.1  christos 	/* this (potentially) runs the mesh for the new query */
    770      1.1  christos 	mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
    771      1.1  christos 		PREFETCH_EXPIRY_ADD);
    772      1.1  christos }
    773      1.1  christos 
    774      1.1  christos /**
    775      1.1  christos  * Fill CH class answer into buffer. Keeps query.
    776      1.1  christos  * @param pkt: buffer
    777      1.1  christos  * @param str: string to put into text record (<255).
    778  1.1.1.2  christos  * 	array of strings, every string becomes a text record.
    779  1.1.1.2  christos  * @param num: number of strings in array.
    780      1.1  christos  * @param edns: edns reply information.
    781      1.1  christos  * @param worker: worker with scratch region.
    782      1.1  christos  */
    783      1.1  christos static void
    784  1.1.1.2  christos chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
    785      1.1  christos 	struct worker* worker)
    786      1.1  christos {
    787  1.1.1.2  christos 	int i;
    788      1.1  christos 	unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
    789      1.1  christos 	unsigned int cd = LDNS_CD_WIRE(sldns_buffer_begin(pkt));
    790      1.1  christos 	sldns_buffer_clear(pkt);
    791      1.1  christos 	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip id */
    792      1.1  christos 	sldns_buffer_write_u16(pkt, (uint16_t)(BIT_QR|BIT_RA));
    793      1.1  christos 	if(rd) LDNS_RD_SET(sldns_buffer_begin(pkt));
    794      1.1  christos 	if(cd) LDNS_CD_SET(sldns_buffer_begin(pkt));
    795      1.1  christos 	sldns_buffer_write_u16(pkt, 1); /* qdcount */
    796  1.1.1.2  christos 	sldns_buffer_write_u16(pkt, (uint16_t)num); /* ancount */
    797      1.1  christos 	sldns_buffer_write_u16(pkt, 0); /* nscount */
    798      1.1  christos 	sldns_buffer_write_u16(pkt, 0); /* arcount */
    799      1.1  christos 	(void)query_dname_len(pkt); /* skip qname */
    800      1.1  christos 	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qtype */
    801      1.1  christos 	sldns_buffer_skip(pkt, (ssize_t)sizeof(uint16_t)); /* skip qclass */
    802  1.1.1.2  christos 	for(i=0; i<num; i++) {
    803  1.1.1.2  christos 		size_t len = strlen(str[i]);
    804  1.1.1.2  christos 		if(len>255) len=255; /* cap size of TXT record */
    805  1.1.1.2  christos 		sldns_buffer_write_u16(pkt, 0xc00c); /* compr ptr to query */
    806  1.1.1.2  christos 		sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_TXT);
    807  1.1.1.2  christos 		sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_CH);
    808  1.1.1.2  christos 		sldns_buffer_write_u32(pkt, 0); /* TTL */
    809  1.1.1.2  christos 		sldns_buffer_write_u16(pkt, sizeof(uint8_t) + len);
    810  1.1.1.2  christos 		sldns_buffer_write_u8(pkt, len);
    811  1.1.1.2  christos 		sldns_buffer_write(pkt, str[i], len);
    812  1.1.1.2  christos 	}
    813      1.1  christos 	sldns_buffer_flip(pkt);
    814      1.1  christos 	edns->edns_version = EDNS_ADVERTISED_VERSION;
    815      1.1  christos 	edns->udp_size = EDNS_ADVERTISED_SIZE;
    816      1.1  christos 	edns->bits &= EDNS_DO;
    817  1.1.1.2  christos 	if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
    818  1.1.1.2  christos 		LDNS_RCODE_NOERROR, edns, worker->scratchpad))
    819  1.1.1.2  christos 			edns->opt_list = NULL;
    820  1.1.1.2  christos 	if(sldns_buffer_capacity(pkt) >=
    821  1.1.1.2  christos 		sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
    822  1.1.1.2  christos 		attach_edns_record(pkt, edns);
    823  1.1.1.2  christos }
    824  1.1.1.2  christos 
    825  1.1.1.2  christos /** Reply with one string */
    826  1.1.1.2  christos static void
    827  1.1.1.2  christos chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
    828  1.1.1.2  christos 	struct worker* worker)
    829  1.1.1.2  christos {
    830  1.1.1.2  christos 	chaos_replystr(pkt, (char**)&str, 1, edns, worker);
    831  1.1.1.2  christos }
    832  1.1.1.2  christos 
    833  1.1.1.2  christos /**
    834  1.1.1.2  christos  * Create CH class trustanchor answer.
    835  1.1.1.2  christos  * @param pkt: buffer
    836  1.1.1.2  christos  * @param edns: edns reply information.
    837  1.1.1.2  christos  * @param w: worker with scratch region.
    838  1.1.1.2  christos  */
    839  1.1.1.2  christos static void
    840  1.1.1.2  christos chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
    841  1.1.1.2  christos {
    842  1.1.1.2  christos #define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */
    843  1.1.1.2  christos #define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */
    844  1.1.1.2  christos 	char* str_array[TA_RESPONSE_MAX_TXT];
    845  1.1.1.2  christos 	uint16_t tags[TA_RESPONSE_MAX_TAGS];
    846  1.1.1.2  christos 	int num = 0;
    847  1.1.1.2  christos 	struct trust_anchor* ta;
    848  1.1.1.2  christos 
    849  1.1.1.2  christos 	if(!w->env.need_to_validate) {
    850  1.1.1.2  christos 		/* no validator module, reply no trustanchors */
    851  1.1.1.2  christos 		chaos_replystr(pkt, NULL, 0, edns, w);
    852  1.1.1.2  christos 		return;
    853  1.1.1.2  christos 	}
    854  1.1.1.2  christos 
    855  1.1.1.2  christos 	/* fill the string with contents */
    856  1.1.1.2  christos 	lock_basic_lock(&w->env.anchors->lock);
    857  1.1.1.2  christos 	RBTREE_FOR(ta, struct trust_anchor*, w->env.anchors->tree) {
    858  1.1.1.2  christos 		char* str;
    859  1.1.1.2  christos 		size_t i, numtag, str_len = 255;
    860  1.1.1.2  christos 		if(num == TA_RESPONSE_MAX_TXT) continue;
    861  1.1.1.2  christos 		str = (char*)regional_alloc(w->scratchpad, str_len);
    862  1.1.1.2  christos 		if(!str) continue;
    863  1.1.1.2  christos 		lock_basic_lock(&ta->lock);
    864  1.1.1.2  christos 		numtag = anchor_list_keytags(ta, tags, TA_RESPONSE_MAX_TAGS);
    865  1.1.1.2  christos 		if(numtag == 0) {
    866  1.1.1.2  christos 			/* empty, insecure point */
    867  1.1.1.2  christos 			lock_basic_unlock(&ta->lock);
    868  1.1.1.2  christos 			continue;
    869  1.1.1.2  christos 		}
    870  1.1.1.2  christos 		str_array[num] = str;
    871  1.1.1.2  christos 		num++;
    872  1.1.1.2  christos 
    873  1.1.1.2  christos 		/* spool name of anchor */
    874  1.1.1.2  christos 		(void)sldns_wire2str_dname_buf(ta->name, ta->namelen, str, str_len);
    875  1.1.1.2  christos 		str_len -= strlen(str); str += strlen(str);
    876  1.1.1.2  christos 		/* spool tags */
    877  1.1.1.2  christos 		for(i=0; i<numtag; i++) {
    878  1.1.1.2  christos 			snprintf(str, str_len, " %u", (unsigned)tags[i]);
    879  1.1.1.2  christos 			str_len -= strlen(str); str += strlen(str);
    880  1.1.1.2  christos 		}
    881  1.1.1.2  christos 		lock_basic_unlock(&ta->lock);
    882  1.1.1.2  christos 	}
    883  1.1.1.2  christos 	lock_basic_unlock(&w->env.anchors->lock);
    884  1.1.1.2  christos 
    885  1.1.1.2  christos 	chaos_replystr(pkt, str_array, num, edns, w);
    886  1.1.1.2  christos 	regional_free_all(w->scratchpad);
    887      1.1  christos }
    888      1.1  christos 
    889      1.1  christos /**
    890      1.1  christos  * Answer CH class queries.
    891      1.1  christos  * @param w: worker
    892      1.1  christos  * @param qinfo: query info. Pointer into packet buffer.
    893      1.1  christos  * @param edns: edns info from query.
    894      1.1  christos  * @param pkt: packet buffer.
    895      1.1  christos  * @return: true if a reply is to be sent.
    896      1.1  christos  */
    897      1.1  christos static int
    898      1.1  christos answer_chaos(struct worker* w, struct query_info* qinfo,
    899      1.1  christos 	struct edns_data* edns, sldns_buffer* pkt)
    900      1.1  christos {
    901      1.1  christos 	struct config_file* cfg = w->env.cfg;
    902      1.1  christos 	if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
    903      1.1  christos 		return 0;
    904      1.1  christos 	if(query_dname_compare(qinfo->qname,
    905      1.1  christos 		(uint8_t*)"\002id\006server") == 0 ||
    906      1.1  christos 		query_dname_compare(qinfo->qname,
    907      1.1  christos 		(uint8_t*)"\010hostname\004bind") == 0)
    908      1.1  christos 	{
    909      1.1  christos 		if(cfg->hide_identity)
    910      1.1  christos 			return 0;
    911      1.1  christos 		if(cfg->identity==NULL || cfg->identity[0]==0) {
    912      1.1  christos 			char buf[MAXHOSTNAMELEN+1];
    913      1.1  christos 			if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
    914      1.1  christos 				buf[MAXHOSTNAMELEN] = 0;
    915  1.1.1.2  christos 				chaos_replyonestr(pkt, buf, edns, w);
    916      1.1  christos 			} else 	{
    917      1.1  christos 				log_err("gethostname: %s", strerror(errno));
    918  1.1.1.2  christos 				chaos_replyonestr(pkt, "no hostname", edns, w);
    919      1.1  christos 			}
    920      1.1  christos 		}
    921  1.1.1.2  christos 		else 	chaos_replyonestr(pkt, cfg->identity, edns, w);
    922      1.1  christos 		return 1;
    923      1.1  christos 	}
    924      1.1  christos 	if(query_dname_compare(qinfo->qname,
    925      1.1  christos 		(uint8_t*)"\007version\006server") == 0 ||
    926      1.1  christos 		query_dname_compare(qinfo->qname,
    927      1.1  christos 		(uint8_t*)"\007version\004bind") == 0)
    928      1.1  christos 	{
    929      1.1  christos 		if(cfg->hide_version)
    930      1.1  christos 			return 0;
    931      1.1  christos 		if(cfg->version==NULL || cfg->version[0]==0)
    932  1.1.1.2  christos 			chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
    933  1.1.1.2  christos 		else 	chaos_replyonestr(pkt, cfg->version, edns, w);
    934      1.1  christos 		return 1;
    935      1.1  christos 	}
    936  1.1.1.2  christos 	if(query_dname_compare(qinfo->qname,
    937  1.1.1.2  christos 		(uint8_t*)"\013trustanchor\007unbound") == 0)
    938  1.1.1.2  christos 	{
    939  1.1.1.2  christos 		if(cfg->hide_trustanchor)
    940  1.1.1.2  christos 			return 0;
    941  1.1.1.2  christos 		chaos_trustanchor(pkt, edns, w);
    942  1.1.1.2  christos 		return 1;
    943  1.1.1.2  christos 	}
    944  1.1.1.2  christos 
    945      1.1  christos 	return 0;
    946      1.1  christos }
    947      1.1  christos 
    948  1.1.1.3  christos /**
    949  1.1.1.3  christos  * Answer notify queries.  These are notifies for authoritative zones,
    950  1.1.1.3  christos  * the reply is an ack that the notify has been received.  We need to check
    951  1.1.1.3  christos  * access permission here.
    952  1.1.1.3  christos  * @param w: worker
    953  1.1.1.3  christos  * @param qinfo: query info. Pointer into packet buffer.
    954  1.1.1.3  christos  * @param edns: edns info from query.
    955  1.1.1.3  christos  * @param repinfo: reply info with source address.
    956  1.1.1.3  christos  * @param pkt: packet buffer.
    957  1.1.1.3  christos  */
    958  1.1.1.3  christos static void
    959  1.1.1.3  christos answer_notify(struct worker* w, struct query_info* qinfo,
    960  1.1.1.3  christos 	struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
    961  1.1.1.3  christos {
    962  1.1.1.3  christos 	int refused = 0;
    963  1.1.1.3  christos 	int rcode = LDNS_RCODE_NOERROR;
    964  1.1.1.3  christos 	uint32_t serial = 0;
    965  1.1.1.3  christos 	int has_serial;
    966  1.1.1.3  christos 	if(!w->env.auth_zones) return;
    967  1.1.1.3  christos 	has_serial = auth_zone_parse_notify_serial(pkt, &serial);
    968  1.1.1.3  christos 	if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
    969  1.1.1.3  christos 		qinfo->qname_len, qinfo->qclass, &repinfo->addr,
    970  1.1.1.3  christos 		repinfo->addrlen, has_serial, serial, &refused)) {
    971  1.1.1.3  christos 		rcode = LDNS_RCODE_NOERROR;
    972  1.1.1.3  christos 	} else {
    973  1.1.1.3  christos 		if(refused)
    974  1.1.1.3  christos 			rcode = LDNS_RCODE_REFUSED;
    975  1.1.1.3  christos 		else	rcode = LDNS_RCODE_SERVFAIL;
    976  1.1.1.3  christos 	}
    977  1.1.1.3  christos 
    978  1.1.1.3  christos 	if(verbosity >= VERB_DETAIL) {
    979  1.1.1.3  christos 		char buf[380];
    980  1.1.1.3  christos 		char zname[255+1];
    981  1.1.1.3  christos 		char sr[25];
    982  1.1.1.3  christos 		dname_str(qinfo->qname, zname);
    983  1.1.1.3  christos 		sr[0]=0;
    984  1.1.1.3  christos 		if(has_serial)
    985  1.1.1.3  christos 			snprintf(sr, sizeof(sr), "serial %u ",
    986  1.1.1.3  christos 				(unsigned)serial);
    987  1.1.1.3  christos 		if(rcode == LDNS_RCODE_REFUSED)
    988  1.1.1.3  christos 			snprintf(buf, sizeof(buf),
    989  1.1.1.3  christos 				"refused NOTIFY %sfor %s from", sr, zname);
    990  1.1.1.3  christos 		else if(rcode == LDNS_RCODE_SERVFAIL)
    991  1.1.1.3  christos 			snprintf(buf, sizeof(buf),
    992  1.1.1.3  christos 				"servfail for NOTIFY %sfor %s from", sr, zname);
    993  1.1.1.3  christos 		else	snprintf(buf, sizeof(buf),
    994  1.1.1.3  christos 				"received NOTIFY %sfor %s from", sr, zname);
    995  1.1.1.3  christos 		log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
    996  1.1.1.3  christos 	}
    997  1.1.1.3  christos 	edns->edns_version = EDNS_ADVERTISED_VERSION;
    998  1.1.1.3  christos 	edns->udp_size = EDNS_ADVERTISED_SIZE;
    999  1.1.1.3  christos 	edns->ext_rcode = 0;
   1000  1.1.1.3  christos 	edns->bits &= EDNS_DO;
   1001  1.1.1.3  christos 	edns->opt_list = NULL;
   1002  1.1.1.3  christos 	error_encode(pkt, rcode, qinfo,
   1003  1.1.1.3  christos 		*(uint16_t*)(void *)sldns_buffer_begin(pkt),
   1004  1.1.1.3  christos 		sldns_buffer_read_u16_at(pkt, 2), edns);
   1005  1.1.1.3  christos 	LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
   1006  1.1.1.3  christos }
   1007  1.1.1.3  christos 
   1008      1.1  christos static int
   1009      1.1  christos deny_refuse(struct comm_point* c, enum acl_access acl,
   1010      1.1  christos 	enum acl_access deny, enum acl_access refuse,
   1011      1.1  christos 	struct worker* worker, struct comm_reply* repinfo)
   1012      1.1  christos {
   1013      1.1  christos 	if(acl == deny) {
   1014      1.1  christos 		comm_point_drop_reply(repinfo);
   1015      1.1  christos 		if(worker->stats.extended)
   1016      1.1  christos 			worker->stats.unwanted_queries++;
   1017      1.1  christos 		return 0;
   1018      1.1  christos 	} else if(acl == refuse) {
   1019      1.1  christos 		log_addr(VERB_ALGO, "refused query from",
   1020      1.1  christos 			&repinfo->addr, repinfo->addrlen);
   1021      1.1  christos 		log_buf(VERB_ALGO, "refuse", c->buffer);
   1022      1.1  christos 		if(worker->stats.extended)
   1023      1.1  christos 			worker->stats.unwanted_queries++;
   1024      1.1  christos 		if(worker_check_request(c->buffer, worker) == -1) {
   1025      1.1  christos 			comm_point_drop_reply(repinfo);
   1026      1.1  christos 			return 0; /* discard this */
   1027      1.1  christos 		}
   1028      1.1  christos 		sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
   1029      1.1  christos 		sldns_buffer_write_at(c->buffer, 4,
   1030      1.1  christos 			(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
   1031      1.1  christos 		LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1032      1.1  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
   1033      1.1  christos 			LDNS_RCODE_REFUSED);
   1034  1.1.1.2  christos 		sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
   1035  1.1.1.2  christos 		sldns_buffer_flip(c->buffer);
   1036      1.1  christos 		return 1;
   1037      1.1  christos 	}
   1038      1.1  christos 
   1039      1.1  christos 	return -1;
   1040      1.1  christos }
   1041      1.1  christos 
   1042      1.1  christos static int
   1043      1.1  christos deny_refuse_all(struct comm_point* c, enum acl_access acl,
   1044      1.1  christos 	struct worker* worker, struct comm_reply* repinfo)
   1045      1.1  christos {
   1046      1.1  christos 	return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo);
   1047      1.1  christos }
   1048      1.1  christos 
   1049      1.1  christos static int
   1050      1.1  christos deny_refuse_non_local(struct comm_point* c, enum acl_access acl,
   1051      1.1  christos 	struct worker* worker, struct comm_reply* repinfo)
   1052      1.1  christos {
   1053      1.1  christos 	return deny_refuse(c, acl, acl_deny_non_local, acl_refuse_non_local, worker, repinfo);
   1054      1.1  christos }
   1055      1.1  christos 
   1056      1.1  christos int
   1057      1.1  christos worker_handle_request(struct comm_point* c, void* arg, int error,
   1058      1.1  christos 	struct comm_reply* repinfo)
   1059      1.1  christos {
   1060      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1061      1.1  christos 	int ret;
   1062  1.1.1.2  christos 	hashvalue_type h;
   1063      1.1  christos 	struct lruhash_entry* e;
   1064      1.1  christos 	struct query_info qinfo;
   1065      1.1  christos 	struct edns_data edns;
   1066      1.1  christos 	enum acl_access acl;
   1067  1.1.1.2  christos 	struct acl_addr* acladdr;
   1068      1.1  christos 	int rc = 0;
   1069  1.1.1.2  christos 	int need_drop = 0;
   1070  1.1.1.2  christos 	/* We might have to chase a CNAME chain internally, in which case
   1071  1.1.1.2  christos 	 * we'll have up to two replies and combine them to build a complete
   1072  1.1.1.2  christos 	 * answer.  These variables control this case. */
   1073  1.1.1.2  christos 	struct ub_packed_rrset_key* alias_rrset = NULL;
   1074  1.1.1.2  christos 	struct reply_info* partial_rep = NULL;
   1075  1.1.1.2  christos 	struct query_info* lookup_qinfo = &qinfo;
   1076  1.1.1.2  christos 	struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
   1077  1.1.1.2  christos 	struct respip_client_info* cinfo = NULL, cinfo_tmp;
   1078  1.1.1.2  christos 	memset(&qinfo, 0, sizeof(qinfo));
   1079      1.1  christos 
   1080      1.1  christos 	if(error != NETEVENT_NOERROR) {
   1081      1.1  christos 		/* some bad tcp query DNS formats give these error calls */
   1082      1.1  christos 		verbose(VERB_ALGO, "handle request called with err=%d", error);
   1083      1.1  christos 		return 0;
   1084      1.1  christos 	}
   1085  1.1.1.2  christos #ifdef USE_DNSCRYPT
   1086  1.1.1.2  christos 	repinfo->max_udp_size = worker->daemon->cfg->max_udp_size;
   1087  1.1.1.2  christos 	if(!dnsc_handle_curved_request(worker->daemon->dnscenv, repinfo)) {
   1088  1.1.1.2  christos 		worker->stats.num_query_dnscrypt_crypted_malformed++;
   1089  1.1.1.2  christos 		return 0;
   1090  1.1.1.2  christos 	}
   1091  1.1.1.2  christos 	if(c->dnscrypt && !repinfo->is_dnscrypted) {
   1092  1.1.1.2  christos 		char buf[LDNS_MAX_DOMAINLEN+1];
   1093  1.1.1.2  christos 		/* Check if this is unencrypted and asking for certs */
   1094  1.1.1.2  christos 		if(worker_check_request(c->buffer, worker) != 0) {
   1095  1.1.1.2  christos 			verbose(VERB_ALGO,
   1096  1.1.1.2  christos 				"dnscrypt: worker check request: bad query.");
   1097  1.1.1.2  christos 			log_addr(VERB_CLIENT,"from",&repinfo->addr,
   1098  1.1.1.2  christos 				repinfo->addrlen);
   1099  1.1.1.2  christos 			comm_point_drop_reply(repinfo);
   1100  1.1.1.2  christos 			return 0;
   1101  1.1.1.2  christos 		}
   1102  1.1.1.2  christos 		if(!query_info_parse(&qinfo, c->buffer)) {
   1103  1.1.1.2  christos 			verbose(VERB_ALGO,
   1104  1.1.1.2  christos 				"dnscrypt: worker parse request: formerror.");
   1105  1.1.1.2  christos 			log_addr(VERB_CLIENT, "from", &repinfo->addr,
   1106  1.1.1.2  christos 				repinfo->addrlen);
   1107  1.1.1.2  christos 			comm_point_drop_reply(repinfo);
   1108  1.1.1.2  christos 			return 0;
   1109  1.1.1.2  christos 		}
   1110  1.1.1.2  christos 		dname_str(qinfo.qname, buf);
   1111  1.1.1.2  christos 		if(!(qinfo.qtype == LDNS_RR_TYPE_TXT &&
   1112  1.1.1.2  christos 			strcasecmp(buf,
   1113  1.1.1.2  christos 			worker->daemon->dnscenv->provider_name) == 0)) {
   1114  1.1.1.2  christos 			verbose(VERB_ALGO,
   1115  1.1.1.3  christos 				"dnscrypt: not TXT \"%s\". Received: %s \"%s\"",
   1116  1.1.1.2  christos 				worker->daemon->dnscenv->provider_name,
   1117  1.1.1.2  christos 				sldns_rr_descript(qinfo.qtype)->_name,
   1118  1.1.1.2  christos 				buf);
   1119  1.1.1.2  christos 			comm_point_drop_reply(repinfo);
   1120  1.1.1.2  christos 			worker->stats.num_query_dnscrypt_cleartext++;
   1121  1.1.1.2  christos 			return 0;
   1122  1.1.1.2  christos 		}
   1123  1.1.1.2  christos 		worker->stats.num_query_dnscrypt_cert++;
   1124  1.1.1.2  christos 		sldns_buffer_rewind(c->buffer);
   1125  1.1.1.2  christos 	} else if(c->dnscrypt && repinfo->is_dnscrypted) {
   1126  1.1.1.2  christos 		worker->stats.num_query_dnscrypt_crypted++;
   1127  1.1.1.2  christos 	}
   1128  1.1.1.2  christos #endif
   1129      1.1  christos #ifdef USE_DNSTAP
   1130      1.1  christos 	if(worker->dtenv.log_client_query_messages)
   1131      1.1  christos 		dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, c->type,
   1132      1.1  christos 			c->buffer);
   1133      1.1  christos #endif
   1134  1.1.1.2  christos 	acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
   1135      1.1  christos 		repinfo->addrlen);
   1136  1.1.1.2  christos 	acl = acl_get_control(acladdr);
   1137      1.1  christos 	if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
   1138      1.1  christos 	{
   1139      1.1  christos 		if(ret == 1)
   1140      1.1  christos 			goto send_reply;
   1141      1.1  christos 		return ret;
   1142      1.1  christos 	}
   1143      1.1  christos 	if((ret=worker_check_request(c->buffer, worker)) != 0) {
   1144      1.1  christos 		verbose(VERB_ALGO, "worker check request: bad query.");
   1145      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1146      1.1  christos 		if(ret != -1) {
   1147      1.1  christos 			LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1148      1.1  christos 			LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
   1149      1.1  christos 			return 1;
   1150      1.1  christos 		}
   1151      1.1  christos 		comm_point_drop_reply(repinfo);
   1152      1.1  christos 		return 0;
   1153      1.1  christos 	}
   1154  1.1.1.2  christos 
   1155      1.1  christos 	worker->stats.num_queries++;
   1156  1.1.1.2  christos 
   1157  1.1.1.2  christos 	/* check if this query should be dropped based on source ip rate limiting */
   1158  1.1.1.2  christos 	if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
   1159  1.1.1.2  christos 			*worker->env.now)) {
   1160  1.1.1.2  christos 		/* See if we are passed through with slip factor */
   1161  1.1.1.2  christos 		if(worker->env.cfg->ip_ratelimit_factor != 0 &&
   1162  1.1.1.2  christos 			ub_random_max(worker->env.rnd,
   1163  1.1.1.2  christos 						  worker->env.cfg->ip_ratelimit_factor) == 1) {
   1164  1.1.1.2  christos 
   1165  1.1.1.2  christos 			char addrbuf[128];
   1166  1.1.1.2  christos 			addr_to_str(&repinfo->addr, repinfo->addrlen,
   1167  1.1.1.2  christos 						addrbuf, sizeof(addrbuf));
   1168  1.1.1.2  christos 		  verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
   1169  1.1.1.2  christos 				  addrbuf);
   1170  1.1.1.2  christos 		} else {
   1171  1.1.1.2  christos 			worker->stats.num_queries_ip_ratelimited++;
   1172  1.1.1.2  christos 			comm_point_drop_reply(repinfo);
   1173  1.1.1.2  christos 			return 0;
   1174  1.1.1.2  christos 		}
   1175  1.1.1.2  christos 	}
   1176  1.1.1.2  christos 
   1177      1.1  christos 	/* see if query is in the cache */
   1178      1.1  christos 	if(!query_info_parse(&qinfo, c->buffer)) {
   1179      1.1  christos 		verbose(VERB_ALGO, "worker parse request: formerror.");
   1180      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1181  1.1.1.2  christos 		memset(&qinfo, 0, sizeof(qinfo)); /* zero qinfo.qname */
   1182      1.1  christos 		if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
   1183      1.1  christos 			comm_point_drop_reply(repinfo);
   1184      1.1  christos 			return 0;
   1185      1.1  christos 		}
   1186      1.1  christos 		sldns_buffer_rewind(c->buffer);
   1187      1.1  christos 		LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1188      1.1  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
   1189      1.1  christos 			LDNS_RCODE_FORMERR);
   1190      1.1  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1191      1.1  christos 		goto send_reply;
   1192      1.1  christos 	}
   1193      1.1  christos 	if(worker->env.cfg->log_queries) {
   1194      1.1  christos 		char ip[128];
   1195      1.1  christos 		addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
   1196      1.1  christos 		log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
   1197      1.1  christos 	}
   1198      1.1  christos 	if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
   1199      1.1  christos 		qinfo.qtype == LDNS_RR_TYPE_IXFR) {
   1200      1.1  christos 		verbose(VERB_ALGO, "worker request: refused zone transfer.");
   1201      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1202      1.1  christos 		sldns_buffer_rewind(c->buffer);
   1203      1.1  christos 		LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1204      1.1  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
   1205      1.1  christos 			LDNS_RCODE_REFUSED);
   1206      1.1  christos 		if(worker->stats.extended) {
   1207      1.1  christos 			worker->stats.qtype[qinfo.qtype]++;
   1208      1.1  christos 			server_stats_insrcode(&worker->stats, c->buffer);
   1209      1.1  christos 		}
   1210      1.1  christos 		goto send_reply;
   1211      1.1  christos 	}
   1212  1.1.1.2  christos 	if(qinfo.qtype == LDNS_RR_TYPE_OPT ||
   1213  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_TSIG ||
   1214  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_TKEY ||
   1215  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_MAILA ||
   1216  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_MAILB ||
   1217  1.1.1.2  christos 		(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
   1218  1.1.1.2  christos 		verbose(VERB_ALGO, "worker request: formerror for meta-type.");
   1219  1.1.1.2  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1220  1.1.1.2  christos 		if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
   1221  1.1.1.2  christos 			comm_point_drop_reply(repinfo);
   1222  1.1.1.2  christos 			return 0;
   1223  1.1.1.2  christos 		}
   1224  1.1.1.2  christos 		sldns_buffer_rewind(c->buffer);
   1225  1.1.1.2  christos 		LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1226  1.1.1.2  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
   1227  1.1.1.2  christos 			LDNS_RCODE_FORMERR);
   1228  1.1.1.2  christos 		if(worker->stats.extended) {
   1229  1.1.1.2  christos 			worker->stats.qtype[qinfo.qtype]++;
   1230  1.1.1.2  christos 			server_stats_insrcode(&worker->stats, c->buffer);
   1231  1.1.1.2  christos 		}
   1232  1.1.1.2  christos 		goto send_reply;
   1233  1.1.1.2  christos 	}
   1234      1.1  christos 	if((ret=parse_edns_from_pkt(c->buffer, &edns, worker->scratchpad)) != 0) {
   1235      1.1  christos 		struct edns_data reply_edns;
   1236      1.1  christos 		verbose(VERB_ALGO, "worker parse edns: formerror.");
   1237      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1238      1.1  christos 		memset(&reply_edns, 0, sizeof(reply_edns));
   1239      1.1  christos 		reply_edns.edns_present = 1;
   1240      1.1  christos 		reply_edns.udp_size = EDNS_ADVERTISED_SIZE;
   1241      1.1  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
   1242      1.1  christos 		error_encode(c->buffer, ret, &qinfo,
   1243      1.1  christos 			*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
   1244      1.1  christos 			sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
   1245      1.1  christos 		regional_free_all(worker->scratchpad);
   1246      1.1  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1247      1.1  christos 		goto send_reply;
   1248      1.1  christos 	}
   1249      1.1  christos 	if(edns.edns_present && edns.edns_version != 0) {
   1250      1.1  christos 		edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
   1251      1.1  christos 		edns.edns_version = EDNS_ADVERTISED_VERSION;
   1252      1.1  christos 		edns.udp_size = EDNS_ADVERTISED_SIZE;
   1253      1.1  christos 		edns.bits &= EDNS_DO;
   1254      1.1  christos 		edns.opt_list = NULL;
   1255      1.1  christos 		verbose(VERB_ALGO, "query with bad edns version.");
   1256      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1257      1.1  christos 		error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
   1258      1.1  christos 			*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
   1259      1.1  christos 			sldns_buffer_read_u16_at(c->buffer, 2), NULL);
   1260  1.1.1.2  christos 		if(sldns_buffer_capacity(c->buffer) >=
   1261  1.1.1.2  christos 			sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
   1262  1.1.1.2  christos 			attach_edns_record(c->buffer, &edns);
   1263      1.1  christos 		regional_free_all(worker->scratchpad);
   1264      1.1  christos 		goto send_reply;
   1265      1.1  christos 	}
   1266      1.1  christos 	if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
   1267      1.1  christos 		worker->daemon->cfg->harden_short_bufsize) {
   1268      1.1  christos 		verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
   1269      1.1  christos 			(int)edns.udp_size);
   1270      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1271      1.1  christos 		edns.udp_size = NORMAL_UDP_SIZE;
   1272      1.1  christos 	}
   1273      1.1  christos 	if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
   1274      1.1  christos 		c->type == comm_udp) {
   1275      1.1  christos 		verbose(VERB_QUERY,
   1276      1.1  christos 			"worker request: max UDP reply size modified"
   1277      1.1  christos 			" (%d to max-udp-size)", (int)edns.udp_size);
   1278      1.1  christos 		log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
   1279      1.1  christos 		edns.udp_size = worker->daemon->cfg->max_udp_size;
   1280      1.1  christos 	}
   1281      1.1  christos 	if(edns.udp_size < LDNS_HEADER_SIZE) {
   1282      1.1  christos 		verbose(VERB_ALGO, "worker request: edns is too small.");
   1283      1.1  christos 		log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen);
   1284      1.1  christos 		LDNS_QR_SET(sldns_buffer_begin(c->buffer));
   1285      1.1  christos 		LDNS_TC_SET(sldns_buffer_begin(c->buffer));
   1286      1.1  christos 		LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
   1287      1.1  christos 			LDNS_RCODE_SERVFAIL);
   1288      1.1  christos 		sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
   1289      1.1  christos 		sldns_buffer_write_at(c->buffer, 4,
   1290      1.1  christos 			(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
   1291      1.1  christos 		sldns_buffer_flip(c->buffer);
   1292      1.1  christos 		regional_free_all(worker->scratchpad);
   1293      1.1  christos 		goto send_reply;
   1294      1.1  christos 	}
   1295      1.1  christos 	if(worker->stats.extended)
   1296      1.1  christos 		server_stats_insquery(&worker->stats, c, qinfo.qtype,
   1297      1.1  christos 			qinfo.qclass, &edns, repinfo);
   1298      1.1  christos 	if(c->type != comm_udp)
   1299      1.1  christos 		edns.udp_size = 65535; /* max size for TCP replies */
   1300      1.1  christos 	if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
   1301      1.1  christos 		&edns, c->buffer)) {
   1302      1.1  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1303      1.1  christos 		regional_free_all(worker->scratchpad);
   1304      1.1  christos 		goto send_reply;
   1305      1.1  christos 	}
   1306  1.1.1.3  christos 	if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
   1307  1.1.1.3  christos 		LDNS_PACKET_NOTIFY) {
   1308  1.1.1.3  christos 		answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
   1309  1.1.1.3  christos 		regional_free_all(worker->scratchpad);
   1310  1.1.1.3  christos 		goto send_reply;
   1311  1.1.1.3  christos 	}
   1312  1.1.1.2  christos 	if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
   1313  1.1.1.2  christos 		&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
   1314  1.1.1.2  christos 		acladdr->taglen, acladdr->tag_actions,
   1315  1.1.1.2  christos 		acladdr->tag_actions_size, acladdr->tag_datas,
   1316  1.1.1.2  christos 		acladdr->tag_datas_size, worker->daemon->cfg->tagname,
   1317  1.1.1.2  christos 		worker->daemon->cfg->num_tags, acladdr->view)) {
   1318      1.1  christos 		regional_free_all(worker->scratchpad);
   1319      1.1  christos 		if(sldns_buffer_limit(c->buffer) == 0) {
   1320      1.1  christos 			comm_point_drop_reply(repinfo);
   1321      1.1  christos 			return 0;
   1322      1.1  christos 		}
   1323      1.1  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1324      1.1  christos 		goto send_reply;
   1325      1.1  christos 	}
   1326  1.1.1.3  christos 	if(worker->env.auth_zones &&
   1327  1.1.1.3  christos 		auth_zones_answer(worker->env.auth_zones, &worker->env,
   1328  1.1.1.3  christos 		&qinfo, &edns, c->buffer, worker->scratchpad)) {
   1329  1.1.1.3  christos 		regional_free_all(worker->scratchpad);
   1330  1.1.1.3  christos 		if(sldns_buffer_limit(c->buffer) == 0) {
   1331  1.1.1.3  christos 			comm_point_drop_reply(repinfo);
   1332  1.1.1.3  christos 			return 0;
   1333  1.1.1.3  christos 		}
   1334  1.1.1.3  christos 		/* set RA for everyone that can have recursion (based on
   1335  1.1.1.3  christos 		 * access control list) */
   1336  1.1.1.3  christos 		if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
   1337  1.1.1.3  christos 		   acl != acl_deny_non_local && acl != acl_refuse_non_local)
   1338  1.1.1.3  christos 			LDNS_RA_SET(sldns_buffer_begin(c->buffer));
   1339  1.1.1.3  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1340  1.1.1.3  christos 		goto send_reply;
   1341  1.1.1.3  christos 	}
   1342      1.1  christos 
   1343      1.1  christos 	/* We've looked in our local zones. If the answer isn't there, we
   1344      1.1  christos 	 * might need to bail out based on ACLs now. */
   1345      1.1  christos 	if((ret=deny_refuse_non_local(c, acl, worker, repinfo)) != -1)
   1346      1.1  christos 	{
   1347      1.1  christos 		regional_free_all(worker->scratchpad);
   1348      1.1  christos 		if(ret == 1)
   1349      1.1  christos 			goto send_reply;
   1350      1.1  christos 		return ret;
   1351      1.1  christos 	}
   1352      1.1  christos 
   1353      1.1  christos 	/* If this request does not have the recursion bit set, verify
   1354  1.1.1.3  christos 	 * ACLs allow the recursion bit to be treated as set. */
   1355  1.1.1.3  christos 	if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
   1356  1.1.1.3  christos 		acl == acl_allow_setrd ) {
   1357  1.1.1.3  christos 		LDNS_RD_SET(sldns_buffer_begin(c->buffer));
   1358  1.1.1.3  christos 	}
   1359  1.1.1.3  christos 
   1360  1.1.1.3  christos 	/* If this request does not have the recursion bit set, verify
   1361      1.1  christos 	 * ACLs allow the snooping. */
   1362      1.1  christos 	if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
   1363      1.1  christos 		acl != acl_allow_snoop ) {
   1364  1.1.1.3  christos 		error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
   1365  1.1.1.3  christos 			*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
   1366  1.1.1.3  christos 			sldns_buffer_read_u16_at(c->buffer, 2), NULL);
   1367      1.1  christos 		regional_free_all(worker->scratchpad);
   1368      1.1  christos 		server_stats_insrcode(&worker->stats, c->buffer);
   1369      1.1  christos 		log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
   1370      1.1  christos 			&repinfo->addr, repinfo->addrlen);
   1371      1.1  christos 		goto send_reply;
   1372      1.1  christos 	}
   1373  1.1.1.2  christos 
   1374  1.1.1.2  christos 	/* If we've found a local alias, replace the qname with the alias
   1375  1.1.1.2  christos 	 * target before resolving it. */
   1376  1.1.1.2  christos 	if(qinfo.local_alias) {
   1377  1.1.1.2  christos 		struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset;
   1378  1.1.1.2  christos 		struct packed_rrset_data* d = rrset->entry.data;
   1379  1.1.1.2  christos 
   1380  1.1.1.2  christos 		/* Sanity check: our current implementation only supports
   1381  1.1.1.2  christos 		 * a single CNAME RRset as a local alias. */
   1382  1.1.1.2  christos 		if(qinfo.local_alias->next ||
   1383  1.1.1.2  christos 			rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
   1384  1.1.1.2  christos 			d->count != 1) {
   1385  1.1.1.2  christos 			log_err("assumption failure: unexpected local alias");
   1386      1.1  christos 			regional_free_all(worker->scratchpad);
   1387  1.1.1.2  christos 			return 0; /* drop it */
   1388      1.1  christos 		}
   1389  1.1.1.2  christos 		qinfo.qname = d->rr_data[0] + 2;
   1390  1.1.1.2  christos 		qinfo.qname_len = d->rr_len[0] - 2;
   1391      1.1  christos 	}
   1392  1.1.1.2  christos 
   1393  1.1.1.2  christos 	/* If we may apply IP-based actions to the answer, build the client
   1394  1.1.1.2  christos 	 * information.  As this can be expensive, skip it if there is
   1395  1.1.1.2  christos 	 * absolutely no possibility of it. */
   1396  1.1.1.2  christos 	if(worker->daemon->use_response_ip &&
   1397  1.1.1.2  christos 		(qinfo.qtype == LDNS_RR_TYPE_A ||
   1398  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_AAAA ||
   1399  1.1.1.2  christos 		qinfo.qtype == LDNS_RR_TYPE_ANY)) {
   1400  1.1.1.2  christos 		cinfo_tmp.taglist = acladdr->taglist;
   1401  1.1.1.2  christos 		cinfo_tmp.taglen = acladdr->taglen;
   1402  1.1.1.2  christos 		cinfo_tmp.tag_actions = acladdr->tag_actions;
   1403  1.1.1.2  christos 		cinfo_tmp.tag_actions_size = acladdr->tag_actions_size;
   1404  1.1.1.2  christos 		cinfo_tmp.tag_datas = acladdr->tag_datas;
   1405  1.1.1.2  christos 		cinfo_tmp.tag_datas_size = acladdr->tag_datas_size;
   1406  1.1.1.2  christos 		cinfo_tmp.view = acladdr->view;
   1407  1.1.1.2  christos 		cinfo_tmp.respip_set = worker->daemon->respip_set;
   1408  1.1.1.2  christos 		cinfo = &cinfo_tmp;
   1409  1.1.1.2  christos 	}
   1410  1.1.1.2  christos 
   1411  1.1.1.2  christos lookup_cache:
   1412  1.1.1.2  christos 	/* Lookup the cache.  In case we chase an intermediate CNAME chain
   1413  1.1.1.2  christos 	 * this is a two-pass operation, and lookup_qinfo is different for
   1414  1.1.1.2  christos 	 * each pass.  We should still pass the original qinfo to
   1415  1.1.1.2  christos 	 * answer_from_cache(), however, since it's used to build the reply. */
   1416  1.1.1.2  christos 	if(!edns_bypass_cache_stage(edns.opt_list, &worker->env)) {
   1417  1.1.1.2  christos 		h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
   1418  1.1.1.2  christos 		if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
   1419  1.1.1.2  christos 			/* answer from cache - we have acquired a readlock on it */
   1420  1.1.1.3  christos 			if(answer_from_cache(worker, &qinfo,
   1421  1.1.1.2  christos 				cinfo, &need_drop, &alias_rrset, &partial_rep,
   1422  1.1.1.3  christos 				(struct reply_info*)e->data,
   1423  1.1.1.3  christos 				*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
   1424  1.1.1.3  christos 				sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
   1425  1.1.1.2  christos 				&edns)) {
   1426  1.1.1.2  christos 				/* prefetch it if the prefetch TTL expired.
   1427  1.1.1.2  christos 				 * Note that if there is more than one pass
   1428  1.1.1.2  christos 				 * its qname must be that used for cache
   1429  1.1.1.2  christos 				 * lookup. */
   1430  1.1.1.2  christos 				if((worker->env.cfg->prefetch || worker->env.cfg->serve_expired)
   1431  1.1.1.2  christos 					&& *worker->env.now >=
   1432  1.1.1.2  christos 					((struct reply_info*)e->data)->prefetch_ttl) {
   1433  1.1.1.2  christos 					time_t leeway = ((struct reply_info*)e->
   1434  1.1.1.2  christos 						data)->ttl - *worker->env.now;
   1435  1.1.1.2  christos 					if(((struct reply_info*)e->data)->ttl
   1436  1.1.1.2  christos 						< *worker->env.now)
   1437  1.1.1.2  christos 						leeway = 0;
   1438  1.1.1.2  christos 					lock_rw_unlock(&e->lock);
   1439  1.1.1.2  christos 					reply_and_prefetch(worker, lookup_qinfo,
   1440  1.1.1.2  christos 						sldns_buffer_read_u16_at(c->buffer, 2),
   1441  1.1.1.2  christos 						repinfo, leeway);
   1442  1.1.1.2  christos 					if(!partial_rep) {
   1443  1.1.1.2  christos 						rc = 0;
   1444  1.1.1.2  christos 						regional_free_all(worker->scratchpad);
   1445  1.1.1.2  christos 						goto send_reply_rc;
   1446  1.1.1.2  christos 					}
   1447  1.1.1.2  christos 				} else if(!partial_rep) {
   1448  1.1.1.2  christos 					lock_rw_unlock(&e->lock);
   1449  1.1.1.2  christos 					regional_free_all(worker->scratchpad);
   1450  1.1.1.2  christos 					goto send_reply;
   1451  1.1.1.2  christos 				} else {
   1452  1.1.1.2  christos 					/* Note that we've already released the
   1453  1.1.1.2  christos 					 * lock if we're here after prefetch. */
   1454  1.1.1.2  christos 					lock_rw_unlock(&e->lock);
   1455  1.1.1.2  christos 				}
   1456  1.1.1.2  christos 				/* We've found a partial reply ending with an
   1457  1.1.1.2  christos 				 * alias.  Replace the lookup qinfo for the
   1458  1.1.1.2  christos 				 * alias target and lookup the cache again to
   1459  1.1.1.2  christos 				 * (possibly) complete the reply.  As we're
   1460  1.1.1.2  christos 				 * passing the "base" reply, there will be no
   1461  1.1.1.2  christos 				 * more alias chasing. */
   1462  1.1.1.2  christos 				memset(&qinfo_tmp, 0, sizeof(qinfo_tmp));
   1463  1.1.1.2  christos 				get_cname_target(alias_rrset, &qinfo_tmp.qname,
   1464  1.1.1.2  christos 					&qinfo_tmp.qname_len);
   1465  1.1.1.2  christos 				if(!qinfo_tmp.qname) {
   1466  1.1.1.2  christos 					log_err("unexpected: invalid answer alias");
   1467  1.1.1.2  christos 					regional_free_all(worker->scratchpad);
   1468  1.1.1.2  christos 					return 0; /* drop query */
   1469  1.1.1.2  christos 				}
   1470  1.1.1.2  christos 				qinfo_tmp.qtype = qinfo.qtype;
   1471  1.1.1.2  christos 				qinfo_tmp.qclass = qinfo.qclass;
   1472  1.1.1.2  christos 				lookup_qinfo = &qinfo_tmp;
   1473  1.1.1.2  christos 				goto lookup_cache;
   1474  1.1.1.2  christos 			}
   1475  1.1.1.2  christos 			verbose(VERB_ALGO, "answer from the cache failed");
   1476  1.1.1.2  christos 			lock_rw_unlock(&e->lock);
   1477  1.1.1.2  christos 		}
   1478  1.1.1.2  christos 		if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
   1479  1.1.1.2  christos 			if(answer_norec_from_cache(worker, &qinfo,
   1480  1.1.1.2  christos 				*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
   1481  1.1.1.2  christos 				sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
   1482  1.1.1.2  christos 				&edns)) {
   1483  1.1.1.2  christos 				regional_free_all(worker->scratchpad);
   1484  1.1.1.2  christos 				goto send_reply;
   1485  1.1.1.2  christos 			}
   1486  1.1.1.2  christos 			verbose(VERB_ALGO, "answer norec from cache -- "
   1487  1.1.1.2  christos 				"need to validate or not primed");
   1488      1.1  christos 		}
   1489      1.1  christos 	}
   1490      1.1  christos 	sldns_buffer_rewind(c->buffer);
   1491      1.1  christos 	server_stats_querymiss(&worker->stats, worker);
   1492      1.1  christos 
   1493      1.1  christos 	if(verbosity >= VERB_CLIENT) {
   1494      1.1  christos 		if(c->type == comm_udp)
   1495      1.1  christos 			log_addr(VERB_CLIENT, "udp request from",
   1496      1.1  christos 				&repinfo->addr, repinfo->addrlen);
   1497      1.1  christos 		else	log_addr(VERB_CLIENT, "tcp request from",
   1498      1.1  christos 				&repinfo->addr, repinfo->addrlen);
   1499      1.1  christos 	}
   1500      1.1  christos 
   1501      1.1  christos 	/* grab a work request structure for this new request */
   1502  1.1.1.2  christos 	mesh_new_client(worker->env.mesh, &qinfo, cinfo,
   1503      1.1  christos 		sldns_buffer_read_u16_at(c->buffer, 2),
   1504      1.1  christos 		&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
   1505      1.1  christos 	regional_free_all(worker->scratchpad);
   1506      1.1  christos 	worker_mem_report(worker, NULL);
   1507      1.1  christos 	return 0;
   1508      1.1  christos 
   1509      1.1  christos send_reply:
   1510      1.1  christos 	rc = 1;
   1511      1.1  christos send_reply_rc:
   1512  1.1.1.2  christos 	if(need_drop) {
   1513  1.1.1.2  christos 		comm_point_drop_reply(repinfo);
   1514  1.1.1.2  christos 		return 0;
   1515  1.1.1.2  christos 	}
   1516      1.1  christos #ifdef USE_DNSTAP
   1517      1.1  christos 	if(worker->dtenv.log_client_response_messages)
   1518      1.1  christos 		dt_msg_send_client_response(&worker->dtenv, &repinfo->addr,
   1519      1.1  christos 			c->type, c->buffer);
   1520      1.1  christos #endif
   1521  1.1.1.2  christos 	if(worker->env.cfg->log_replies)
   1522  1.1.1.2  christos 	{
   1523  1.1.1.2  christos 		struct timeval tv = {0, 0};
   1524  1.1.1.2  christos 		log_reply_info(0, &qinfo, &repinfo->addr, repinfo->addrlen,
   1525  1.1.1.2  christos 			tv, 1, c->buffer);
   1526  1.1.1.2  christos 	}
   1527  1.1.1.2  christos #ifdef USE_DNSCRYPT
   1528  1.1.1.2  christos 	if(!dnsc_handle_uncurved_request(repinfo)) {
   1529  1.1.1.2  christos 		return 0;
   1530  1.1.1.2  christos 	}
   1531  1.1.1.2  christos #endif
   1532      1.1  christos 	return rc;
   1533      1.1  christos }
   1534      1.1  christos 
   1535      1.1  christos void
   1536      1.1  christos worker_sighandler(int sig, void* arg)
   1537      1.1  christos {
   1538      1.1  christos 	/* note that log, print, syscalls here give race conditions.
   1539      1.1  christos 	 * And cause hangups if the log-lock is held by the application. */
   1540      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1541      1.1  christos 	switch(sig) {
   1542      1.1  christos #ifdef SIGHUP
   1543      1.1  christos 		case SIGHUP:
   1544      1.1  christos 			comm_base_exit(worker->base);
   1545      1.1  christos 			break;
   1546      1.1  christos #endif
   1547      1.1  christos 		case SIGINT:
   1548      1.1  christos 			worker->need_to_exit = 1;
   1549      1.1  christos 			comm_base_exit(worker->base);
   1550      1.1  christos 			break;
   1551      1.1  christos #ifdef SIGQUIT
   1552      1.1  christos 		case SIGQUIT:
   1553      1.1  christos 			worker->need_to_exit = 1;
   1554      1.1  christos 			comm_base_exit(worker->base);
   1555      1.1  christos 			break;
   1556      1.1  christos #endif
   1557      1.1  christos 		case SIGTERM:
   1558      1.1  christos 			worker->need_to_exit = 1;
   1559      1.1  christos 			comm_base_exit(worker->base);
   1560      1.1  christos 			break;
   1561      1.1  christos 		default:
   1562      1.1  christos 			/* unknown signal, ignored */
   1563      1.1  christos 			break;
   1564      1.1  christos 	}
   1565      1.1  christos }
   1566      1.1  christos 
   1567      1.1  christos /** restart statistics timer for worker, if enabled */
   1568      1.1  christos static void
   1569      1.1  christos worker_restart_timer(struct worker* worker)
   1570      1.1  christos {
   1571      1.1  christos 	if(worker->env.cfg->stat_interval > 0) {
   1572      1.1  christos 		struct timeval tv;
   1573      1.1  christos #ifndef S_SPLINT_S
   1574      1.1  christos 		tv.tv_sec = worker->env.cfg->stat_interval;
   1575      1.1  christos 		tv.tv_usec = 0;
   1576      1.1  christos #endif
   1577      1.1  christos 		comm_timer_set(worker->stat_timer, &tv);
   1578      1.1  christos 	}
   1579      1.1  christos }
   1580      1.1  christos 
   1581      1.1  christos void worker_stat_timer_cb(void* arg)
   1582      1.1  christos {
   1583      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1584      1.1  christos 	server_stats_log(&worker->stats, worker, worker->thread_num);
   1585      1.1  christos 	mesh_stats(worker->env.mesh, "mesh has");
   1586      1.1  christos 	worker_mem_report(worker, NULL);
   1587  1.1.1.2  christos 	/* SHM is enabled, process data to SHM */
   1588  1.1.1.2  christos 	if (worker->daemon->cfg->shm_enable) {
   1589  1.1.1.2  christos 		shm_main_run(worker);
   1590  1.1.1.2  christos 	}
   1591      1.1  christos 	if(!worker->daemon->cfg->stat_cumulative) {
   1592      1.1  christos 		worker_stats_clear(worker);
   1593      1.1  christos 	}
   1594      1.1  christos 	/* start next timer */
   1595      1.1  christos 	worker_restart_timer(worker);
   1596      1.1  christos }
   1597      1.1  christos 
   1598      1.1  christos void worker_probe_timer_cb(void* arg)
   1599      1.1  christos {
   1600      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1601      1.1  christos 	struct timeval tv;
   1602      1.1  christos #ifndef S_SPLINT_S
   1603      1.1  christos 	tv.tv_sec = (time_t)autr_probe_timer(&worker->env);
   1604      1.1  christos 	tv.tv_usec = 0;
   1605      1.1  christos #endif
   1606      1.1  christos 	if(tv.tv_sec != 0)
   1607      1.1  christos 		comm_timer_set(worker->env.probe_timer, &tv);
   1608      1.1  christos }
   1609      1.1  christos 
   1610      1.1  christos struct worker*
   1611      1.1  christos worker_create(struct daemon* daemon, int id, int* ports, int n)
   1612      1.1  christos {
   1613      1.1  christos 	unsigned int seed;
   1614      1.1  christos 	struct worker* worker = (struct worker*)calloc(1,
   1615      1.1  christos 		sizeof(struct worker));
   1616      1.1  christos 	if(!worker)
   1617      1.1  christos 		return NULL;
   1618      1.1  christos 	worker->numports = n;
   1619      1.1  christos 	worker->ports = (int*)memdup(ports, sizeof(int)*n);
   1620      1.1  christos 	if(!worker->ports) {
   1621      1.1  christos 		free(worker);
   1622      1.1  christos 		return NULL;
   1623      1.1  christos 	}
   1624      1.1  christos 	worker->daemon = daemon;
   1625      1.1  christos 	worker->thread_num = id;
   1626      1.1  christos 	if(!(worker->cmd = tube_create())) {
   1627      1.1  christos 		free(worker->ports);
   1628      1.1  christos 		free(worker);
   1629      1.1  christos 		return NULL;
   1630      1.1  christos 	}
   1631      1.1  christos 	/* create random state here to avoid locking trouble in RAND_bytes */
   1632      1.1  christos 	seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
   1633      1.1  christos 		(((unsigned int)worker->thread_num)<<17);
   1634      1.1  christos 		/* shift thread_num so it does not match out pid bits */
   1635      1.1  christos 	if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
   1636      1.1  christos 		seed = 0;
   1637      1.1  christos 		log_err("could not init random numbers.");
   1638      1.1  christos 		tube_delete(worker->cmd);
   1639      1.1  christos 		free(worker->ports);
   1640      1.1  christos 		free(worker);
   1641      1.1  christos 		return NULL;
   1642      1.1  christos 	}
   1643      1.1  christos 	seed = 0;
   1644      1.1  christos #ifdef USE_DNSTAP
   1645      1.1  christos 	if(daemon->cfg->dnstap) {
   1646      1.1  christos 		log_assert(daemon->dtenv != NULL);
   1647      1.1  christos 		memcpy(&worker->dtenv, daemon->dtenv, sizeof(struct dt_env));
   1648      1.1  christos 		if(!dt_init(&worker->dtenv))
   1649      1.1  christos 			fatal_exit("dt_init failed");
   1650      1.1  christos 	}
   1651      1.1  christos #endif
   1652      1.1  christos 	return worker;
   1653      1.1  christos }
   1654      1.1  christos 
   1655      1.1  christos int
   1656      1.1  christos worker_init(struct worker* worker, struct config_file *cfg,
   1657      1.1  christos 	struct listen_port* ports, int do_sigs)
   1658      1.1  christos {
   1659      1.1  christos #ifdef USE_DNSTAP
   1660      1.1  christos 	struct dt_env* dtenv = &worker->dtenv;
   1661      1.1  christos #else
   1662      1.1  christos 	void* dtenv = NULL;
   1663      1.1  christos #endif
   1664      1.1  christos 	worker->need_to_exit = 0;
   1665      1.1  christos 	worker->base = comm_base_create(do_sigs);
   1666      1.1  christos 	if(!worker->base) {
   1667      1.1  christos 		log_err("could not create event handling base");
   1668      1.1  christos 		worker_delete(worker);
   1669      1.1  christos 		return 0;
   1670      1.1  christos 	}
   1671      1.1  christos 	comm_base_set_slow_accept_handlers(worker->base, &worker_stop_accept,
   1672      1.1  christos 		&worker_start_accept, worker);
   1673      1.1  christos 	if(do_sigs) {
   1674      1.1  christos #ifdef SIGHUP
   1675      1.1  christos 		ub_thread_sig_unblock(SIGHUP);
   1676      1.1  christos #endif
   1677      1.1  christos 		ub_thread_sig_unblock(SIGINT);
   1678      1.1  christos #ifdef SIGQUIT
   1679      1.1  christos 		ub_thread_sig_unblock(SIGQUIT);
   1680      1.1  christos #endif
   1681      1.1  christos 		ub_thread_sig_unblock(SIGTERM);
   1682      1.1  christos #ifndef LIBEVENT_SIGNAL_PROBLEM
   1683      1.1  christos 		worker->comsig = comm_signal_create(worker->base,
   1684      1.1  christos 			worker_sighandler, worker);
   1685      1.1  christos 		if(!worker->comsig
   1686      1.1  christos #ifdef SIGHUP
   1687      1.1  christos 			|| !comm_signal_bind(worker->comsig, SIGHUP)
   1688      1.1  christos #endif
   1689      1.1  christos #ifdef SIGQUIT
   1690      1.1  christos 			|| !comm_signal_bind(worker->comsig, SIGQUIT)
   1691      1.1  christos #endif
   1692      1.1  christos 			|| !comm_signal_bind(worker->comsig, SIGTERM)
   1693      1.1  christos 			|| !comm_signal_bind(worker->comsig, SIGINT)) {
   1694      1.1  christos 			log_err("could not create signal handlers");
   1695      1.1  christos 			worker_delete(worker);
   1696      1.1  christos 			return 0;
   1697      1.1  christos 		}
   1698      1.1  christos #endif /* LIBEVENT_SIGNAL_PROBLEM */
   1699      1.1  christos 		if(!daemon_remote_open_accept(worker->daemon->rc,
   1700      1.1  christos 			worker->daemon->rc_ports, worker)) {
   1701      1.1  christos 			worker_delete(worker);
   1702      1.1  christos 			return 0;
   1703      1.1  christos 		}
   1704      1.1  christos #ifdef UB_ON_WINDOWS
   1705      1.1  christos 		wsvc_setup_worker(worker);
   1706      1.1  christos #endif /* UB_ON_WINDOWS */
   1707      1.1  christos 	} else { /* !do_sigs */
   1708      1.1  christos 		worker->comsig = NULL;
   1709      1.1  christos 	}
   1710      1.1  christos 	worker->front = listen_create(worker->base, ports,
   1711      1.1  christos 		cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
   1712      1.1  christos 		worker->daemon->listen_sslctx, dtenv, worker_handle_request,
   1713      1.1  christos 		worker);
   1714      1.1  christos 	if(!worker->front) {
   1715      1.1  christos 		log_err("could not create listening sockets");
   1716      1.1  christos 		worker_delete(worker);
   1717      1.1  christos 		return 0;
   1718      1.1  christos 	}
   1719      1.1  christos 	worker->back = outside_network_create(worker->base,
   1720      1.1  christos 		cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
   1721      1.1  christos 		cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
   1722      1.1  christos 		cfg->do_tcp?cfg->outgoing_num_tcp:0,
   1723      1.1  christos 		worker->daemon->env->infra_cache, worker->rndstate,
   1724      1.1  christos 		cfg->use_caps_bits_for_id, worker->ports, worker->numports,
   1725      1.1  christos 		cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
   1726      1.1  christos 		&worker_alloc_cleanup, worker,
   1727  1.1.1.2  christos 		cfg->do_udp || cfg->udp_upstream_without_downstream,
   1728  1.1.1.2  christos 		worker->daemon->connect_sslctx, cfg->delay_close,
   1729      1.1  christos 		dtenv);
   1730      1.1  christos 	if(!worker->back) {
   1731      1.1  christos 		log_err("could not create outgoing sockets");
   1732      1.1  christos 		worker_delete(worker);
   1733      1.1  christos 		return 0;
   1734      1.1  christos 	}
   1735      1.1  christos 	/* start listening to commands */
   1736      1.1  christos 	if(!tube_setup_bg_listen(worker->cmd, worker->base,
   1737      1.1  christos 		&worker_handle_control_cmd, worker)) {
   1738      1.1  christos 		log_err("could not create control compt.");
   1739      1.1  christos 		worker_delete(worker);
   1740      1.1  christos 		return 0;
   1741      1.1  christos 	}
   1742      1.1  christos 	worker->stat_timer = comm_timer_create(worker->base,
   1743      1.1  christos 		worker_stat_timer_cb, worker);
   1744      1.1  christos 	if(!worker->stat_timer) {
   1745      1.1  christos 		log_err("could not create statistics timer");
   1746      1.1  christos 	}
   1747      1.1  christos 
   1748      1.1  christos 	/* we use the msg_buffer_size as a good estimate for what the
   1749      1.1  christos 	 * user wants for memory usage sizes */
   1750      1.1  christos 	worker->scratchpad = regional_create_custom(cfg->msg_buffer_size);
   1751      1.1  christos 	if(!worker->scratchpad) {
   1752      1.1  christos 		log_err("malloc failure");
   1753      1.1  christos 		worker_delete(worker);
   1754      1.1  christos 		return 0;
   1755      1.1  christos 	}
   1756      1.1  christos 
   1757      1.1  christos 	server_stats_init(&worker->stats, cfg);
   1758      1.1  christos 	alloc_init(&worker->alloc, &worker->daemon->superalloc,
   1759      1.1  christos 		worker->thread_num);
   1760      1.1  christos 	alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
   1761      1.1  christos 	worker->env = *worker->daemon->env;
   1762      1.1  christos 	comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
   1763      1.1  christos 	if(worker->thread_num == 0)
   1764      1.1  christos 		log_set_time(worker->env.now);
   1765      1.1  christos 	worker->env.worker = worker;
   1766  1.1.1.3  christos 	worker->env.worker_base = worker->base;
   1767      1.1  christos 	worker->env.send_query = &worker_send_query;
   1768      1.1  christos 	worker->env.alloc = &worker->alloc;
   1769  1.1.1.3  christos 	worker->env.outnet = worker->back;
   1770      1.1  christos 	worker->env.rnd = worker->rndstate;
   1771  1.1.1.2  christos 	/* If case prefetch is triggered, the corresponding mesh will clear
   1772  1.1.1.2  christos 	 * the scratchpad for the module env in the middle of request handling.
   1773  1.1.1.2  christos 	 * It would be prone to a use-after-free kind of bug, so we avoid
   1774  1.1.1.2  christos 	 * sharing it with worker's own scratchpad at the cost of having
   1775  1.1.1.2  christos 	 * one more pad per worker. */
   1776  1.1.1.2  christos 	worker->env.scratch = regional_create_custom(cfg->msg_buffer_size);
   1777  1.1.1.2  christos 	if(!worker->env.scratch) {
   1778  1.1.1.2  christos 		log_err("malloc failure");
   1779  1.1.1.2  christos 		worker_delete(worker);
   1780  1.1.1.2  christos 		return 0;
   1781  1.1.1.2  christos 	}
   1782      1.1  christos 	worker->env.mesh = mesh_create(&worker->daemon->mods, &worker->env);
   1783      1.1  christos 	worker->env.detach_subs = &mesh_detach_subs;
   1784      1.1  christos 	worker->env.attach_sub = &mesh_attach_sub;
   1785  1.1.1.2  christos 	worker->env.add_sub = &mesh_add_sub;
   1786      1.1  christos 	worker->env.kill_sub = &mesh_state_delete;
   1787      1.1  christos 	worker->env.detect_cycle = &mesh_detect_cycle;
   1788      1.1  christos 	worker->env.scratch_buffer = sldns_buffer_new(cfg->msg_buffer_size);
   1789      1.1  christos 	if(!(worker->env.fwds = forwards_create()) ||
   1790      1.1  christos 		!forwards_apply_cfg(worker->env.fwds, cfg)) {
   1791      1.1  christos 		log_err("Could not set forward zones");
   1792      1.1  christos 		worker_delete(worker);
   1793      1.1  christos 		return 0;
   1794      1.1  christos 	}
   1795      1.1  christos 	if(!(worker->env.hints = hints_create()) ||
   1796      1.1  christos 		!hints_apply_cfg(worker->env.hints, cfg)) {
   1797      1.1  christos 		log_err("Could not set root or stub hints");
   1798      1.1  christos 		worker_delete(worker);
   1799      1.1  christos 		return 0;
   1800      1.1  christos 	}
   1801      1.1  christos 	/* one probe timer per process -- if we have 5011 anchors */
   1802      1.1  christos 	if(autr_get_num_anchors(worker->env.anchors) > 0
   1803      1.1  christos #ifndef THREADS_DISABLED
   1804      1.1  christos 		&& worker->thread_num == 0
   1805      1.1  christos #endif
   1806      1.1  christos 		) {
   1807      1.1  christos 		struct timeval tv;
   1808      1.1  christos 		tv.tv_sec = 0;
   1809      1.1  christos 		tv.tv_usec = 0;
   1810      1.1  christos 		worker->env.probe_timer = comm_timer_create(worker->base,
   1811      1.1  christos 			worker_probe_timer_cb, worker);
   1812      1.1  christos 		if(!worker->env.probe_timer) {
   1813      1.1  christos 			log_err("could not create 5011-probe timer");
   1814      1.1  christos 		} else {
   1815      1.1  christos 			/* let timer fire, then it can reset itself */
   1816      1.1  christos 			comm_timer_set(worker->env.probe_timer, &tv);
   1817      1.1  christos 		}
   1818      1.1  christos 	}
   1819  1.1.1.3  christos 	/* zone transfer tasks, setup once per process, if any */
   1820  1.1.1.3  christos 	if(worker->env.auth_zones
   1821  1.1.1.3  christos #ifndef THREADS_DISABLED
   1822  1.1.1.3  christos 		&& worker->thread_num == 0
   1823  1.1.1.3  christos #endif
   1824  1.1.1.3  christos 		) {
   1825  1.1.1.3  christos 		auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
   1826  1.1.1.3  christos 	}
   1827      1.1  christos 	if(!worker->env.mesh || !worker->env.scratch_buffer) {
   1828      1.1  christos 		worker_delete(worker);
   1829      1.1  christos 		return 0;
   1830      1.1  christos 	}
   1831      1.1  christos 	worker_mem_report(worker, NULL);
   1832      1.1  christos 	/* if statistics enabled start timer */
   1833      1.1  christos 	if(worker->env.cfg->stat_interval > 0) {
   1834      1.1  christos 		verbose(VERB_ALGO, "set statistics interval %d secs",
   1835      1.1  christos 			worker->env.cfg->stat_interval);
   1836      1.1  christos 		worker_restart_timer(worker);
   1837      1.1  christos 	}
   1838      1.1  christos 	return 1;
   1839      1.1  christos }
   1840      1.1  christos 
   1841      1.1  christos void
   1842      1.1  christos worker_work(struct worker* worker)
   1843      1.1  christos {
   1844      1.1  christos 	comm_base_dispatch(worker->base);
   1845      1.1  christos }
   1846      1.1  christos 
   1847      1.1  christos void
   1848      1.1  christos worker_delete(struct worker* worker)
   1849      1.1  christos {
   1850      1.1  christos 	if(!worker)
   1851      1.1  christos 		return;
   1852      1.1  christos 	if(worker->env.mesh && verbosity >= VERB_OPS) {
   1853      1.1  christos 		server_stats_log(&worker->stats, worker, worker->thread_num);
   1854      1.1  christos 		mesh_stats(worker->env.mesh, "mesh has");
   1855      1.1  christos 		worker_mem_report(worker, NULL);
   1856      1.1  christos 	}
   1857      1.1  christos 	outside_network_quit_prepare(worker->back);
   1858      1.1  christos 	mesh_delete(worker->env.mesh);
   1859      1.1  christos 	sldns_buffer_free(worker->env.scratch_buffer);
   1860      1.1  christos 	forwards_delete(worker->env.fwds);
   1861      1.1  christos 	hints_delete(worker->env.hints);
   1862      1.1  christos 	listen_delete(worker->front);
   1863      1.1  christos 	outside_network_delete(worker->back);
   1864      1.1  christos 	comm_signal_delete(worker->comsig);
   1865      1.1  christos 	tube_delete(worker->cmd);
   1866      1.1  christos 	comm_timer_delete(worker->stat_timer);
   1867      1.1  christos 	comm_timer_delete(worker->env.probe_timer);
   1868      1.1  christos 	free(worker->ports);
   1869      1.1  christos 	if(worker->thread_num == 0) {
   1870      1.1  christos 		log_set_time(NULL);
   1871      1.1  christos #ifdef UB_ON_WINDOWS
   1872      1.1  christos 		wsvc_desetup_worker(worker);
   1873      1.1  christos #endif /* UB_ON_WINDOWS */
   1874      1.1  christos 	}
   1875      1.1  christos 	comm_base_delete(worker->base);
   1876      1.1  christos 	ub_randfree(worker->rndstate);
   1877      1.1  christos 	alloc_clear(&worker->alloc);
   1878  1.1.1.2  christos 	regional_destroy(worker->env.scratch);
   1879      1.1  christos 	regional_destroy(worker->scratchpad);
   1880      1.1  christos 	free(worker);
   1881      1.1  christos }
   1882      1.1  christos 
   1883      1.1  christos struct outbound_entry*
   1884  1.1.1.2  christos worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
   1885  1.1.1.2  christos 	int want_dnssec, int nocaps, struct sockaddr_storage* addr,
   1886  1.1.1.2  christos 	socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
   1887  1.1.1.3  christos 	char* tls_auth_name, struct module_qstate* q)
   1888      1.1  christos {
   1889      1.1  christos 	struct worker* worker = q->env->worker;
   1890      1.1  christos 	struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
   1891      1.1  christos 		q->region, sizeof(*e));
   1892      1.1  christos 	if(!e)
   1893      1.1  christos 		return NULL;
   1894      1.1  christos 	e->qstate = q;
   1895  1.1.1.2  christos 	e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
   1896  1.1.1.2  christos 		want_dnssec, nocaps, q->env->cfg->tcp_upstream,
   1897  1.1.1.3  christos 		ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
   1898  1.1.1.2  christos 		worker_handle_service_reply, e, worker->back->udp_buff, q->env);
   1899      1.1  christos 	if(!e->qsent) {
   1900      1.1  christos 		return NULL;
   1901      1.1  christos 	}
   1902      1.1  christos 	return e;
   1903      1.1  christos }
   1904      1.1  christos 
   1905      1.1  christos void
   1906      1.1  christos worker_alloc_cleanup(void* arg)
   1907      1.1  christos {
   1908      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1909      1.1  christos 	slabhash_clear(&worker->env.rrset_cache->table);
   1910      1.1  christos 	slabhash_clear(worker->env.msg_cache);
   1911      1.1  christos }
   1912      1.1  christos 
   1913      1.1  christos void worker_stats_clear(struct worker* worker)
   1914      1.1  christos {
   1915      1.1  christos 	server_stats_init(&worker->stats, worker->env.cfg);
   1916      1.1  christos 	mesh_stats_clear(worker->env.mesh);
   1917      1.1  christos 	worker->back->unwanted_replies = 0;
   1918      1.1  christos 	worker->back->num_tcp_outgoing = 0;
   1919      1.1  christos }
   1920      1.1  christos 
   1921      1.1  christos void worker_start_accept(void* arg)
   1922      1.1  christos {
   1923      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1924      1.1  christos 	listen_start_accept(worker->front);
   1925      1.1  christos 	if(worker->thread_num == 0)
   1926      1.1  christos 		daemon_remote_start_accept(worker->daemon->rc);
   1927      1.1  christos }
   1928      1.1  christos 
   1929      1.1  christos void worker_stop_accept(void* arg)
   1930      1.1  christos {
   1931      1.1  christos 	struct worker* worker = (struct worker*)arg;
   1932      1.1  christos 	listen_stop_accept(worker->front);
   1933      1.1  christos 	if(worker->thread_num == 0)
   1934      1.1  christos 		daemon_remote_stop_accept(worker->daemon->rc);
   1935      1.1  christos }
   1936      1.1  christos 
   1937      1.1  christos /* --- fake callbacks for fptr_wlist to work --- */
   1938  1.1.1.2  christos struct outbound_entry* libworker_send_query(
   1939  1.1.1.2  christos 	struct query_info* ATTR_UNUSED(qinfo),
   1940  1.1.1.2  christos 	uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
   1941  1.1.1.2  christos 	int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
   1942  1.1.1.2  christos 	struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
   1943  1.1.1.2  christos 	uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
   1944  1.1.1.3  christos 	int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
   1945  1.1.1.3  christos 	struct module_qstate* ATTR_UNUSED(q))
   1946      1.1  christos {
   1947      1.1  christos 	log_assert(0);
   1948      1.1  christos 	return 0;
   1949      1.1  christos }
   1950      1.1  christos 
   1951      1.1  christos int libworker_handle_reply(struct comm_point* ATTR_UNUSED(c),
   1952      1.1  christos 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
   1953      1.1  christos         struct comm_reply* ATTR_UNUSED(reply_info))
   1954      1.1  christos {
   1955      1.1  christos 	log_assert(0);
   1956      1.1  christos 	return 0;
   1957      1.1  christos }
   1958      1.1  christos 
   1959      1.1  christos int libworker_handle_service_reply(struct comm_point* ATTR_UNUSED(c),
   1960      1.1  christos 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
   1961      1.1  christos         struct comm_reply* ATTR_UNUSED(reply_info))
   1962      1.1  christos {
   1963      1.1  christos 	log_assert(0);
   1964      1.1  christos 	return 0;
   1965      1.1  christos }
   1966      1.1  christos 
   1967      1.1  christos void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
   1968      1.1  christos         uint8_t* ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len),
   1969      1.1  christos         int ATTR_UNUSED(error), void* ATTR_UNUSED(arg))
   1970      1.1  christos {
   1971      1.1  christos 	log_assert(0);
   1972      1.1  christos }
   1973      1.1  christos 
   1974      1.1  christos void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
   1975      1.1  christos         sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
   1976      1.1  christos 	char* ATTR_UNUSED(why_bogus))
   1977      1.1  christos {
   1978      1.1  christos 	log_assert(0);
   1979      1.1  christos }
   1980      1.1  christos 
   1981      1.1  christos void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
   1982      1.1  christos         sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
   1983      1.1  christos 	char* ATTR_UNUSED(why_bogus))
   1984      1.1  christos {
   1985      1.1  christos 	log_assert(0);
   1986      1.1  christos }
   1987      1.1  christos 
   1988      1.1  christos void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
   1989      1.1  christos         sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
   1990      1.1  christos 	char* ATTR_UNUSED(why_bogus))
   1991      1.1  christos {
   1992      1.1  christos 	log_assert(0);
   1993      1.1  christos }
   1994      1.1  christos 
   1995      1.1  christos int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
   1996      1.1  christos {
   1997      1.1  christos 	log_assert(0);
   1998      1.1  christos 	return 0;
   1999      1.1  christos }
   2000      1.1  christos 
   2001      1.1  christos int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
   2002      1.1  christos {
   2003      1.1  christos         log_assert(0);
   2004      1.1  christos         return 0;
   2005      1.1  christos }
   2006      1.1  christos 
   2007      1.1  christos int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
   2008      1.1  christos {
   2009      1.1  christos         log_assert(0);
   2010      1.1  christos         return 0;
   2011      1.1  christos }
   2012      1.1  christos 
   2013