xref: /netbsd-src/external/mpl/bind/dist/lib/ns/client.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /*	$NetBSD: client.c,v 1.11 2020/08/03 17:23:43 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #include <inttypes.h>
15 #include <stdbool.h>
16 
17 #include <isc/aes.h>
18 #include <isc/atomic.h>
19 #include <isc/formatcheck.h>
20 #include <isc/fuzz.h>
21 #include <isc/hmac.h>
22 #include <isc/mutex.h>
23 #include <isc/nonce.h>
24 #include <isc/once.h>
25 #include <isc/platform.h>
26 #include <isc/print.h>
27 #include <isc/random.h>
28 #include <isc/safe.h>
29 #include <isc/serial.h>
30 #include <isc/siphash.h>
31 #include <isc/stats.h>
32 #include <isc/stdio.h>
33 #include <isc/string.h>
34 #include <isc/task.h>
35 #include <isc/timer.h>
36 #include <isc/util.h>
37 
38 #include <dns/adb.h>
39 #include <dns/badcache.h>
40 #include <dns/cache.h>
41 #include <dns/db.h>
42 #include <dns/dispatch.h>
43 #include <dns/dnstap.h>
44 #include <dns/edns.h>
45 #include <dns/events.h>
46 #include <dns/message.h>
47 #include <dns/peer.h>
48 #include <dns/rcode.h>
49 #include <dns/rdata.h>
50 #include <dns/rdataclass.h>
51 #include <dns/rdatalist.h>
52 #include <dns/rdataset.h>
53 #include <dns/resolver.h>
54 #include <dns/stats.h>
55 #include <dns/tsig.h>
56 #include <dns/view.h>
57 #include <dns/zone.h>
58 
59 #include <ns/client.h>
60 #include <ns/interfacemgr.h>
61 #include <ns/log.h>
62 #include <ns/notify.h>
63 #include <ns/server.h>
64 #include <ns/stats.h>
65 #include <ns/update.h>
66 
67 /***
68  *** Client
69  ***/
70 
71 /*! \file
72  * Client Routines
73  *
74  * Important note!
75  *
76  * All client state changes, other than that from idle to listening, occur
77  * as a result of events.  This guarantees serialization and avoids the
78  * need for locking.
79  *
80  * If a routine is ever created that allows someone other than the client's
81  * task to change the client, then the client will have to be locked.
82  */
83 
84 #ifdef NS_CLIENT_TRACE
85 #define CTRACE(m)                                                         \
86 	ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
87 		      ISC_LOG_DEBUG(3), "%s", (m))
88 #define MTRACE(m)                                                          \
89 	isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, \
90 		      ISC_LOG_DEBUG(3), "clientmgr @%p: %s", manager, (m))
91 #else /* ifdef NS_CLIENT_TRACE */
92 #define CTRACE(m) ((void)/*LINTED*/(m))
93 #define MTRACE(m) ((void)/*LINTED*/(m))
94 #endif /* ifdef NS_CLIENT_TRACE */
95 
96 #define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
97 
98 #define COOKIE_SIZE 24U /* 8 + 4 + 4 + 8 */
99 #define ECS_SIZE    20U /* 2 + 1 + 1 + [0..16] */
100 
101 #define WANTNSID(x)	(((x)->attributes & NS_CLIENTATTR_WANTNSID) != 0)
102 #define WANTEXPIRE(x)	(((x)->attributes & NS_CLIENTATTR_WANTEXPIRE) != 0)
103 #define WANTPAD(x)	(((x)->attributes & NS_CLIENTATTR_WANTPAD) != 0)
104 #define USEKEEPALIVE(x) (((x)->attributes & NS_CLIENTATTR_USEKEEPALIVE) != 0)
105 
106 #define MANAGER_MAGIC	 ISC_MAGIC('N', 'S', 'C', 'm')
107 #define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC)
108 
109 /*
110  * Enable ns_client_dropport() by default.
111  */
112 #ifndef NS_CLIENT_DROPPORT
113 #define NS_CLIENT_DROPPORT 1
114 #endif /* ifndef NS_CLIENT_DROPPORT */
115 
116 #define CLIENT_NMCTXS_PERCPU 8
117 /*%<
118  * Number of 'mctx pools' for clients. (Should this be configurable?)
119  * When enabling threads, we use a pool of memory contexts shared by
120  * client objects, since concurrent access to a shared context would cause
121  * heavy contentions.  The above constant is expected to be enough for
122  * completely avoiding contentions among threads for an authoritative-only
123  * server.
124  */
125 
126 #define CLIENT_NTASKS_PERCPU 32
127 /*%<
128  * Number of tasks to be used by clients - those are used only when recursing
129  */
130 
131 #if (defined(_WIN32) && !defined(_WIN64)) || !defined(_LP64)
132 LIBNS_EXTERNAL_DATA atomic_uint_fast32_t ns_client_requests;
133 #else  /* if defined(_WIN32) && !defined(_WIN64) */
134 LIBNS_EXTERNAL_DATA atomic_uint_fast64_t ns_client_requests;
135 #endif /* if defined(_WIN32) && !defined(_WIN64) */
136 
137 static void
138 clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp);
139 static void
140 clientmgr_detach(ns_clientmgr_t **mp);
141 static void
142 clientmgr_destroy(ns_clientmgr_t *manager);
143 static void
144 ns_client_endrequest(ns_client_t *client);
145 static void
146 ns_client_dumpmessage(ns_client_t *client, const char *reason);
147 static void
148 compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
149 	       const unsigned char *secret, isc_buffer_t *buf);
150 static void
151 get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp);
152 static void
153 get_clienttask(ns_clientmgr_t *manager, isc_task_t **taskp);
154 
155 void
156 ns_client_recursing(ns_client_t *client) {
157 	REQUIRE(NS_CLIENT_VALID(client));
158 	REQUIRE(client->state == NS_CLIENTSTATE_WORKING);
159 
160 	LOCK(&client->manager->reclock);
161 	client->state = NS_CLIENTSTATE_RECURSING;
162 	ISC_LIST_APPEND(client->manager->recursing, client, rlink);
163 	UNLOCK(&client->manager->reclock);
164 }
165 
166 void
167 ns_client_killoldestquery(ns_client_t *client) {
168 	ns_client_t *oldest;
169 	REQUIRE(NS_CLIENT_VALID(client));
170 
171 	LOCK(&client->manager->reclock);
172 	oldest = ISC_LIST_HEAD(client->manager->recursing);
173 	if (oldest != NULL) {
174 		ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink);
175 		ns_query_cancel(oldest);
176 		ns_stats_increment(client->sctx->nsstats,
177 				   ns_statscounter_reclimitdropped);
178 	}
179 	UNLOCK(&client->manager->reclock);
180 }
181 
182 void
183 ns_client_settimeout(ns_client_t *client, unsigned int seconds) {
184 	UNUSED(client);
185 	UNUSED(seconds);
186 	/* XXXWPK TODO use netmgr to set timeout */
187 }
188 
189 static void
190 ns_client_endrequest(ns_client_t *client) {
191 	INSIST(client->nupdates == 0);
192 	INSIST(client->state == NS_CLIENTSTATE_WORKING ||
193 	       client->state == NS_CLIENTSTATE_RECURSING);
194 
195 	CTRACE("endrequest");
196 
197 	if (client->state == NS_CLIENTSTATE_RECURSING) {
198 		LOCK(&client->manager->reclock);
199 		if (ISC_LINK_LINKED(client, rlink)) {
200 			ISC_LIST_UNLINK(client->manager->recursing, client,
201 					rlink);
202 		}
203 		UNLOCK(&client->manager->reclock);
204 	}
205 
206 	if (client->cleanup != NULL) {
207 		(client->cleanup)(client);
208 		client->cleanup = NULL;
209 	}
210 
211 	if (client->view != NULL) {
212 #ifdef ENABLE_AFL
213 		if (client->sctx->fuzztype == isc_fuzz_resolver) {
214 			dns_cache_clean(client->view->cache, INT_MAX);
215 			dns_adb_flush(client->view->adb);
216 		}
217 #endif /* ifdef ENABLE_AFL */
218 		dns_view_detach(&client->view);
219 	}
220 	if (client->opt != NULL) {
221 		INSIST(dns_rdataset_isassociated(client->opt));
222 		dns_rdataset_disassociate(client->opt);
223 		dns_message_puttemprdataset(client->message, &client->opt);
224 	}
225 
226 	client->signer = NULL;
227 	client->udpsize = 512;
228 	client->extflags = 0;
229 	client->ednsversion = -1;
230 	dns_ecs_init(&client->ecs);
231 	dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE);
232 
233 	/*
234 	 * Clean up from recursion - normally this would be done in
235 	 * fetch_callback(), but if we're shutting down and canceling then
236 	 * it might not have happened.
237 	 */
238 	if (client->recursionquota != NULL) {
239 		isc_quota_detach(&client->recursionquota);
240 		if (client->query.prefetch == NULL) {
241 			ns_stats_decrement(client->sctx->nsstats,
242 					   ns_statscounter_recursclients);
243 		}
244 	}
245 
246 	/*
247 	 * Clear all client attributes that are specific to the request
248 	 */
249 	client->attributes = 0;
250 #ifdef ENABLE_AFL
251 	if (client->sctx->fuzznotify != NULL &&
252 	    (client->sctx->fuzztype == isc_fuzz_client ||
253 	     client->sctx->fuzztype == isc_fuzz_tcpclient ||
254 	     client->sctx->fuzztype == isc_fuzz_resolver))
255 	{
256 		client->sctx->fuzznotify();
257 	}
258 #endif /* ENABLE_AFL */
259 }
260 
261 void
262 ns_client_drop(ns_client_t *client, isc_result_t result) {
263 	REQUIRE(NS_CLIENT_VALID(client));
264 	REQUIRE(client->state == NS_CLIENTSTATE_WORKING ||
265 		client->state == NS_CLIENTSTATE_RECURSING);
266 
267 	CTRACE("drop");
268 	if (result != ISC_R_SUCCESS) {
269 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
270 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
271 			      "request failed: %s", isc_result_totext(result));
272 	}
273 }
274 
275 static void
276 client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
277 	ns_client_t *client = cbarg;
278 
279 	REQUIRE(client->handle == handle);
280 
281 	CTRACE("senddone");
282 	if (result != ISC_R_SUCCESS) {
283 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
284 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
285 			      "send failed: %s", isc_result_totext(result));
286 	}
287 
288 	isc_nmhandle_unref(handle);
289 }
290 
291 static void
292 client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer,
293 		    unsigned char **datap) {
294 	unsigned char *data;
295 	uint32_t bufsize;
296 
297 	REQUIRE(datap != NULL);
298 
299 	if (TCP_CLIENT(client)) {
300 		INSIST(client->tcpbuf == NULL);
301 		client->tcpbuf = isc_mem_get(client->mctx,
302 					     NS_CLIENT_TCP_BUFFER_SIZE);
303 		data = client->tcpbuf;
304 		isc_buffer_init(buffer, data, NS_CLIENT_TCP_BUFFER_SIZE);
305 	} else {
306 		data = client->sendbuf;
307 		if ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) == 0) {
308 			if (client->view != NULL) {
309 				bufsize = client->view->nocookieudp;
310 			} else {
311 				bufsize = 512;
312 			}
313 		} else {
314 			bufsize = client->udpsize;
315 		}
316 		if (bufsize > client->udpsize) {
317 			bufsize = client->udpsize;
318 		}
319 		if (bufsize > NS_CLIENT_SEND_BUFFER_SIZE) {
320 			bufsize = NS_CLIENT_SEND_BUFFER_SIZE;
321 		}
322 		isc_buffer_init(buffer, data, bufsize);
323 	}
324 	*datap = data;
325 }
326 
327 static isc_result_t
328 client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) {
329 	isc_region_t r;
330 
331 	isc_buffer_usedregion(buffer, &r);
332 
333 	INSIST(client->handle != NULL);
334 
335 	return (isc_nm_send(client->handle, &r, client_senddone, client));
336 }
337 
338 void
339 ns_client_sendraw(ns_client_t *client, dns_message_t *message) {
340 	isc_result_t result;
341 	unsigned char *data;
342 	isc_buffer_t buffer;
343 	isc_region_t r;
344 	isc_region_t *mr;
345 
346 	REQUIRE(NS_CLIENT_VALID(client));
347 
348 	CTRACE("sendraw");
349 
350 	mr = dns_message_getrawmessage(message);
351 	if (mr == NULL) {
352 		result = ISC_R_UNEXPECTEDEND;
353 		goto done;
354 	}
355 
356 	client_allocsendbuf(client, &buffer, &data);
357 
358 	if (mr->length > isc_buffer_length(&buffer)) {
359 		result = ISC_R_NOSPACE;
360 		goto done;
361 	}
362 
363 	/*
364 	 * Copy message to buffer and fixup id.
365 	 */
366 	isc_buffer_availableregion(&buffer, &r);
367 	result = isc_buffer_copyregion(&buffer, mr);
368 	if (result != ISC_R_SUCCESS) {
369 		goto done;
370 	}
371 	r.base[0] = (client->message->id >> 8) & 0xff;
372 	r.base[1] = client->message->id & 0xff;
373 
374 	result = client_sendpkg(client, &buffer);
375 	if (result == ISC_R_SUCCESS) {
376 		return;
377 	}
378 
379 done:
380 	if (client->tcpbuf != NULL) {
381 		isc_mem_put(client->mctx, client->tcpbuf,
382 			    NS_CLIENT_TCP_BUFFER_SIZE);
383 		client->tcpbuf = NULL;
384 	}
385 
386 	ns_client_drop(client, result);
387 	isc_nmhandle_unref(client->handle);
388 }
389 
390 void
391 ns_client_send(ns_client_t *client) {
392 	isc_result_t result;
393 	unsigned char *data;
394 	isc_buffer_t buffer = { .magic = 0 };
395 	isc_region_t r;
396 	dns_compress_t cctx;
397 	bool cleanup_cctx = false;
398 	unsigned int render_opts;
399 	unsigned int preferred_glue;
400 	bool opt_included = false;
401 	size_t respsize;
402 	dns_aclenv_t *env;
403 #ifdef HAVE_DNSTAP
404 	unsigned char zone[DNS_NAME_MAXWIRE];
405 	dns_dtmsgtype_t dtmsgtype;
406 	isc_region_t zr;
407 #endif /* HAVE_DNSTAP */
408 
409 	/*
410 	 * XXXWPK TODO
411 	 * Delay the response according to the -T delay option
412 	 */
413 
414 	REQUIRE(NS_CLIENT_VALID(client));
415 	/*
416 	 * We need to do it to make sure the client and handle
417 	 * won't disappear from under us with client_senddone.
418 	 */
419 
420 	env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
421 
422 	CTRACE("send");
423 
424 	if (client->message->opcode == dns_opcode_query &&
425 	    (client->attributes & NS_CLIENTATTR_RA) != 0)
426 	{
427 		client->message->flags |= DNS_MESSAGEFLAG_RA;
428 	}
429 
430 	if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) {
431 		render_opts = 0;
432 	} else {
433 		render_opts = DNS_MESSAGERENDER_OMITDNSSEC;
434 	}
435 
436 	preferred_glue = 0;
437 	if (client->view != NULL) {
438 		if (client->view->preferred_glue == dns_rdatatype_a) {
439 			preferred_glue = DNS_MESSAGERENDER_PREFER_A;
440 		} else if (client->view->preferred_glue == dns_rdatatype_aaaa) {
441 			preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
442 		}
443 	}
444 	if (preferred_glue == 0) {
445 		if (isc_sockaddr_pf(&client->peeraddr) == AF_INET) {
446 			preferred_glue = DNS_MESSAGERENDER_PREFER_A;
447 		} else {
448 			preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA;
449 		}
450 	}
451 
452 	/*
453 	 * Create an OPT for our reply.
454 	 */
455 	if ((client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
456 		result = ns_client_addopt(client, client->message,
457 					  &client->opt);
458 		if (result != ISC_R_SUCCESS) {
459 			goto done;
460 		}
461 	}
462 
463 	client_allocsendbuf(client, &buffer, &data);
464 
465 	result = dns_compress_init(&cctx, -1, client->mctx);
466 	if (result != ISC_R_SUCCESS) {
467 		goto done;
468 	}
469 	if (client->peeraddr_valid && client->view != NULL) {
470 		isc_netaddr_t netaddr;
471 		dns_name_t *name = NULL;
472 
473 		isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
474 		if (client->message->tsigkey != NULL) {
475 			name = &client->message->tsigkey->name;
476 		}
477 
478 		if (client->view->nocasecompress == NULL ||
479 		    !dns_acl_allowed(&netaddr, name,
480 				     client->view->nocasecompress, env))
481 		{
482 			dns_compress_setsensitive(&cctx, true);
483 		}
484 
485 		if (!client->view->msgcompression) {
486 			dns_compress_disable(&cctx);
487 		}
488 	}
489 	cleanup_cctx = true;
490 
491 	result = dns_message_renderbegin(client->message, &cctx, &buffer);
492 	if (result != ISC_R_SUCCESS) {
493 		goto done;
494 	}
495 
496 	if (client->opt != NULL) {
497 		result = dns_message_setopt(client->message, client->opt);
498 		opt_included = true;
499 		client->opt = NULL;
500 		if (result != ISC_R_SUCCESS) {
501 			goto done;
502 		}
503 	}
504 	result = dns_message_rendersection(client->message,
505 					   DNS_SECTION_QUESTION, 0);
506 	if (result == ISC_R_NOSPACE) {
507 		client->message->flags |= DNS_MESSAGEFLAG_TC;
508 		goto renderend;
509 	}
510 	if (result != ISC_R_SUCCESS) {
511 		goto done;
512 	}
513 	/*
514 	 * Stop after the question if TC was set for rate limiting.
515 	 */
516 	if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) {
517 		goto renderend;
518 	}
519 	result = dns_message_rendersection(client->message, DNS_SECTION_ANSWER,
520 					   DNS_MESSAGERENDER_PARTIAL |
521 						   render_opts);
522 	if (result == ISC_R_NOSPACE) {
523 		client->message->flags |= DNS_MESSAGEFLAG_TC;
524 		goto renderend;
525 	}
526 	if (result != ISC_R_SUCCESS) {
527 		goto done;
528 	}
529 	result = dns_message_rendersection(
530 		client->message, DNS_SECTION_AUTHORITY,
531 		DNS_MESSAGERENDER_PARTIAL | render_opts);
532 	if (result == ISC_R_NOSPACE) {
533 		client->message->flags |= DNS_MESSAGEFLAG_TC;
534 		goto renderend;
535 	}
536 	if (result != ISC_R_SUCCESS) {
537 		goto done;
538 	}
539 	result = dns_message_rendersection(client->message,
540 					   DNS_SECTION_ADDITIONAL,
541 					   preferred_glue | render_opts);
542 	if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) {
543 		goto done;
544 	}
545 renderend:
546 	result = dns_message_renderend(client->message);
547 	if (result != ISC_R_SUCCESS) {
548 		goto done;
549 	}
550 
551 #ifdef HAVE_DNSTAP
552 	memset(&zr, 0, sizeof(zr));
553 	if (((client->message->flags & DNS_MESSAGEFLAG_AA) != 0) &&
554 	    (client->query.authzone != NULL))
555 	{
556 		isc_buffer_t b;
557 		dns_name_t *zo = dns_zone_getorigin(client->query.authzone);
558 
559 		isc_buffer_init(&b, zone, sizeof(zone));
560 		dns_compress_setmethods(&cctx, DNS_COMPRESS_NONE);
561 		result = dns_name_towire(zo, &cctx, &b);
562 		if (result == ISC_R_SUCCESS) {
563 			isc_buffer_usedregion(&b, &zr);
564 		}
565 	}
566 
567 	if (client->message->opcode == dns_opcode_update) {
568 		dtmsgtype = DNS_DTTYPE_UR;
569 	} else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
570 		dtmsgtype = DNS_DTTYPE_CR;
571 	} else {
572 		dtmsgtype = DNS_DTTYPE_AR;
573 	}
574 #endif /* HAVE_DNSTAP */
575 
576 	if (cleanup_cctx) {
577 		dns_compress_invalidate(&cctx);
578 		cleanup_cctx = false;
579 	}
580 
581 	if (client->sendcb != NULL) {
582 		client->sendcb(&buffer);
583 	} else if (TCP_CLIENT(client)) {
584 		isc_buffer_usedregion(&buffer, &r);
585 #ifdef HAVE_DNSTAP
586 		if (client->view != NULL) {
587 			dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
588 				    &client->destsockaddr, true, &zr,
589 				    &client->requesttime, NULL, &buffer);
590 		}
591 #endif /* HAVE_DNSTAP */
592 
593 		respsize = isc_buffer_usedlength(&buffer);
594 
595 		isc_nmhandle_ref(client->handle);
596 		result = client_sendpkg(client, &buffer);
597 		if (result != ISC_R_SUCCESS) {
598 			/* We won't get a callback to clean it up */
599 			isc_nmhandle_unref(client->handle);
600 		}
601 
602 		switch (isc_sockaddr_pf(&client->peeraddr)) {
603 		case AF_INET:
604 			isc_stats_increment(client->sctx->tcpoutstats4,
605 					    ISC_MIN((int)respsize / 16, 256));
606 			break;
607 		case AF_INET6:
608 			isc_stats_increment(client->sctx->tcpoutstats6,
609 					    ISC_MIN((int)respsize / 16, 256));
610 			break;
611 		default:
612 			INSIST(0);
613 			ISC_UNREACHABLE();
614 		}
615 	} else {
616 #ifdef HAVE_DNSTAP
617 		/*
618 		 * Log dnstap data first, because client_sendpkg() may
619 		 * leave client->view set to NULL.
620 		 */
621 		if (client->view != NULL) {
622 			dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
623 				    &client->destsockaddr, false, &zr,
624 				    &client->requesttime, NULL, &buffer);
625 		}
626 #endif /* HAVE_DNSTAP */
627 
628 		respsize = isc_buffer_usedlength(&buffer);
629 
630 		isc_nmhandle_ref(client->handle);
631 		result = client_sendpkg(client, &buffer);
632 		if (result != ISC_R_SUCCESS) {
633 			/* We won't get a callback to clean it up */
634 			isc_nmhandle_unref(client->handle);
635 		}
636 
637 		switch (isc_sockaddr_pf(&client->peeraddr)) {
638 		case AF_INET:
639 			isc_stats_increment(client->sctx->udpoutstats4,
640 					    ISC_MIN((int)respsize / 16, 256));
641 			break;
642 		case AF_INET6:
643 			isc_stats_increment(client->sctx->udpoutstats6,
644 					    ISC_MIN((int)respsize / 16, 256));
645 			break;
646 		default:
647 			INSIST(0);
648 			ISC_UNREACHABLE();
649 		}
650 	}
651 
652 	/* update statistics (XXXJT: is it okay to access message->xxxkey?) */
653 	ns_stats_increment(client->sctx->nsstats, ns_statscounter_response);
654 
655 	dns_rcodestats_increment(client->sctx->rcodestats,
656 				 client->message->rcode);
657 	if (opt_included) {
658 		ns_stats_increment(client->sctx->nsstats,
659 				   ns_statscounter_edns0out);
660 	}
661 	if (client->message->tsigkey != NULL) {
662 		ns_stats_increment(client->sctx->nsstats,
663 				   ns_statscounter_tsigout);
664 	}
665 	if (client->message->sig0key != NULL) {
666 		ns_stats_increment(client->sctx->nsstats,
667 				   ns_statscounter_sig0out);
668 	}
669 	if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) {
670 		ns_stats_increment(client->sctx->nsstats,
671 				   ns_statscounter_truncatedresp);
672 	}
673 
674 	if (result == ISC_R_SUCCESS) {
675 		return;
676 	}
677 
678 done:
679 	if (client->tcpbuf != NULL) {
680 		isc_mem_put(client->mctx, client->tcpbuf,
681 			    NS_CLIENT_TCP_BUFFER_SIZE);
682 		client->tcpbuf = NULL;
683 	}
684 
685 	if (cleanup_cctx) {
686 		dns_compress_invalidate(&cctx);
687 	}
688 }
689 
690 #if NS_CLIENT_DROPPORT
691 #define DROPPORT_NO	  0
692 #define DROPPORT_REQUEST  1
693 #define DROPPORT_RESPONSE 2
694 /*%
695  * ns_client_dropport determines if certain requests / responses
696  * should be dropped based on the port number.
697  *
698  * Returns:
699  * \li	0:	Don't drop.
700  * \li	1:	Drop request.
701  * \li	2:	Drop (error) response.
702  */
703 static int
704 ns_client_dropport(in_port_t port) {
705 	switch (port) {
706 	case 7:	 /* echo */
707 	case 13: /* daytime */
708 	case 19: /* chargen */
709 	case 37: /* time */
710 		return (DROPPORT_REQUEST);
711 	case 464: /* kpasswd */
712 		return (DROPPORT_RESPONSE);
713 	}
714 	return (DROPPORT_NO);
715 }
716 #endif /* if NS_CLIENT_DROPPORT */
717 
718 void
719 ns_client_error(ns_client_t *client, isc_result_t result) {
720 	dns_rcode_t rcode;
721 	dns_message_t *message;
722 
723 	REQUIRE(NS_CLIENT_VALID(client));
724 
725 	CTRACE("error");
726 
727 	message = client->message;
728 
729 	if (client->rcode_override == -1) {
730 		rcode = dns_result_torcode(result);
731 	} else {
732 		rcode = (dns_rcode_t)(client->rcode_override & 0xfff);
733 	}
734 
735 #if NS_CLIENT_DROPPORT
736 	/*
737 	 * Don't send FORMERR to ports on the drop port list.
738 	 */
739 	if (rcode == dns_rcode_formerr &&
740 	    ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) !=
741 		    DROPPORT_NO)
742 	{
743 		char buf[64];
744 		isc_buffer_t b;
745 
746 		isc_buffer_init(&b, buf, sizeof(buf) - 1);
747 		if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) {
748 			isc_buffer_putstr(&b, "UNKNOWN RCODE");
749 		}
750 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
751 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
752 			      "dropped error (%.*s) response: suspicious port",
753 			      (int)isc_buffer_usedlength(&b), buf);
754 		ns_client_drop(client, ISC_R_SUCCESS);
755 		return;
756 	}
757 #endif /* if NS_CLIENT_DROPPORT */
758 
759 	/*
760 	 * Try to rate limit error responses.
761 	 */
762 	if (client->view != NULL && client->view->rrl != NULL) {
763 		bool wouldlog;
764 		char log_buf[DNS_RRL_LOG_BUF_LEN];
765 		dns_rrl_result_t rrl_result;
766 		int loglevel;
767 
768 		INSIST(rcode != dns_rcode_noerror &&
769 		       rcode != dns_rcode_nxdomain);
770 		if ((client->sctx->options & NS_SERVER_LOGQUERIES) != 0) {
771 			loglevel = DNS_RRL_LOG_DROP;
772 		} else {
773 			loglevel = ISC_LOG_DEBUG(1);
774 		}
775 		wouldlog = isc_log_wouldlog(ns_lctx, loglevel);
776 		rrl_result = dns_rrl(
777 			client->view, &client->peeraddr, TCP_CLIENT(client),
778 			dns_rdataclass_in, dns_rdatatype_none, NULL, result,
779 			client->now, wouldlog, log_buf, sizeof(log_buf));
780 		if (rrl_result != DNS_RRL_RESULT_OK) {
781 			/*
782 			 * Log dropped errors in the query category
783 			 * so that they are not lost in silence.
784 			 * Starts of rate-limited bursts are logged in
785 			 * NS_LOGCATEGORY_RRL.
786 			 */
787 			if (wouldlog) {
788 				ns_client_log(client,
789 					      NS_LOGCATEGORY_QUERY_ERRORS,
790 					      NS_LOGMODULE_CLIENT, loglevel,
791 					      "%s", log_buf);
792 			}
793 			/*
794 			 * Some error responses cannot be 'slipped',
795 			 * so don't try to slip any error responses.
796 			 */
797 			if (!client->view->rrl->log_only) {
798 				ns_stats_increment(client->sctx->nsstats,
799 						   ns_statscounter_ratedropped);
800 				ns_stats_increment(client->sctx->nsstats,
801 						   ns_statscounter_dropped);
802 				ns_client_drop(client, DNS_R_DROP);
803 				return;
804 			}
805 		}
806 	}
807 
808 	/*
809 	 * Message may be an in-progress reply that we had trouble
810 	 * with, in which case QR will be set.  We need to clear QR before
811 	 * calling dns_message_reply() to avoid triggering an assertion.
812 	 */
813 	message->flags &= ~DNS_MESSAGEFLAG_QR;
814 	/*
815 	 * AA and AD shouldn't be set.
816 	 */
817 	message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD);
818 	result = dns_message_reply(message, true);
819 	if (result != ISC_R_SUCCESS) {
820 		/*
821 		 * It could be that we've got a query with a good header,
822 		 * but a bad question section, so we try again with
823 		 * want_question_section set to false.
824 		 */
825 		result = dns_message_reply(message, false);
826 		if (result != ISC_R_SUCCESS) {
827 			ns_client_drop(client, result);
828 			return;
829 		}
830 	}
831 	message->rcode = rcode;
832 
833 	if (rcode == dns_rcode_formerr) {
834 		/*
835 		 * FORMERR loop avoidance:  If we sent a FORMERR message
836 		 * with the same ID to the same client less than two
837 		 * seconds ago, assume that we are in an infinite error
838 		 * packet dialog with a server for some protocol whose
839 		 * error responses look enough like DNS queries to
840 		 * elicit a FORMERR response.  Drop a packet to break
841 		 * the loop.
842 		 */
843 		if (isc_sockaddr_equal(&client->peeraddr,
844 				       &client->formerrcache.addr) &&
845 		    message->id == client->formerrcache.id &&
846 		    (isc_time_seconds(&client->requesttime) -
847 		     client->formerrcache.time) < 2)
848 		{
849 			/* Drop packet. */
850 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
851 				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
852 				      "possible error packet loop, "
853 				      "FORMERR dropped");
854 			ns_client_drop(client, result);
855 			return;
856 		}
857 		client->formerrcache.addr = client->peeraddr;
858 		client->formerrcache.time =
859 			isc_time_seconds(&client->requesttime);
860 		client->formerrcache.id = message->id;
861 	} else if (rcode == dns_rcode_servfail && client->query.qname != NULL &&
862 		   client->view != NULL && client->view->fail_ttl != 0 &&
863 		   ((client->attributes & NS_CLIENTATTR_NOSETFC) == 0))
864 	{
865 		/*
866 		 * SERVFAIL caching: store qname/qtype of failed queries
867 		 */
868 		isc_time_t expire;
869 		isc_interval_t i;
870 		uint32_t flags = 0;
871 
872 		if ((message->flags & DNS_MESSAGEFLAG_CD) != 0) {
873 			flags = NS_FAILCACHE_CD;
874 		}
875 
876 		isc_interval_set(&i, client->view->fail_ttl, 0);
877 		result = isc_time_nowplusinterval(&expire, &i);
878 		if (result == ISC_R_SUCCESS) {
879 			dns_badcache_add(
880 				client->view->failcache, client->query.qname,
881 				client->query.qtype, true, flags, &expire);
882 		}
883 	}
884 
885 	ns_client_send(client);
886 }
887 
888 isc_result_t
889 ns_client_addopt(ns_client_t *client, dns_message_t *message,
890 		 dns_rdataset_t **opt) {
891 	unsigned char ecs[ECS_SIZE];
892 	char nsid[BUFSIZ], *nsidp;
893 	unsigned char cookie[COOKIE_SIZE];
894 	isc_result_t result;
895 	dns_view_t *view;
896 	dns_resolver_t *resolver;
897 	uint16_t udpsize;
898 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
899 	int count = 0;
900 	unsigned int flags;
901 	unsigned char expire[4];
902 	unsigned char advtimo[2];
903 	dns_aclenv_t *env;
904 
905 	REQUIRE(NS_CLIENT_VALID(client));
906 	REQUIRE(opt != NULL && *opt == NULL);
907 	REQUIRE(message != NULL);
908 
909 	env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
910 	view = client->view;
911 	resolver = (view != NULL) ? view->resolver : NULL;
912 	if (resolver != NULL) {
913 		udpsize = dns_resolver_getudpsize(resolver);
914 	} else {
915 		udpsize = client->sctx->udpsize;
916 	}
917 
918 	flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE;
919 
920 	/* Set EDNS options if applicable */
921 	if (WANTNSID(client)) {
922 		if (client->sctx->server_id != NULL) {
923 			nsidp = client->sctx->server_id;
924 		} else if (client->sctx->gethostname != NULL) {
925 			result = client->sctx->gethostname(nsid, sizeof(nsid));
926 			if (result != ISC_R_SUCCESS) {
927 				goto no_nsid;
928 			}
929 			nsidp = nsid;
930 		} else {
931 			goto no_nsid;
932 		}
933 
934 		INSIST(count < DNS_EDNSOPTIONS);
935 		ednsopts[count].code = DNS_OPT_NSID;
936 		ednsopts[count].length = (uint16_t)strlen(nsidp);
937 		ednsopts[count].value = (unsigned char *)nsidp;
938 		count++;
939 	}
940 no_nsid:
941 	if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0) {
942 		isc_buffer_t buf;
943 		isc_stdtime_t now;
944 		uint32_t nonce;
945 
946 		isc_buffer_init(&buf, cookie, sizeof(cookie));
947 		isc_stdtime_get(&now);
948 
949 		isc_random_buf(&nonce, sizeof(nonce));
950 
951 		compute_cookie(client, now, nonce, client->sctx->secret, &buf);
952 
953 		INSIST(count < DNS_EDNSOPTIONS);
954 		ednsopts[count].code = DNS_OPT_COOKIE;
955 		ednsopts[count].length = COOKIE_SIZE;
956 		ednsopts[count].value = cookie;
957 		count++;
958 	}
959 	if ((client->attributes & NS_CLIENTATTR_HAVEEXPIRE) != 0) {
960 		isc_buffer_t buf;
961 
962 		INSIST(count < DNS_EDNSOPTIONS);
963 
964 		isc_buffer_init(&buf, expire, sizeof(expire));
965 		isc_buffer_putuint32(&buf, client->expire);
966 		ednsopts[count].code = DNS_OPT_EXPIRE;
967 		ednsopts[count].length = 4;
968 		ednsopts[count].value = expire;
969 		count++;
970 	}
971 	if (((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) &&
972 	    (client->ecs.addr.family == AF_INET ||
973 	     client->ecs.addr.family == AF_INET6 ||
974 	     client->ecs.addr.family == AF_UNSPEC))
975 	{
976 		isc_buffer_t buf;
977 		uint8_t addr[16];
978 		uint32_t plen, addrl;
979 		uint16_t family = 0;
980 
981 		/* Add CLIENT-SUBNET option. */
982 
983 		plen = client->ecs.source;
984 
985 		/* Round up prefix len to a multiple of 8 */
986 		addrl = (plen + 7) / 8;
987 
988 		switch (client->ecs.addr.family) {
989 		case AF_UNSPEC:
990 			INSIST(plen == 0);
991 			family = 0;
992 			break;
993 		case AF_INET:
994 			INSIST(plen <= 32);
995 			family = 1;
996 			memmove(addr, &client->ecs.addr.type, addrl);
997 			break;
998 		case AF_INET6:
999 			INSIST(plen <= 128);
1000 			family = 2;
1001 			memmove(addr, &client->ecs.addr.type, addrl);
1002 			break;
1003 		default:
1004 			INSIST(0);
1005 			ISC_UNREACHABLE();
1006 		}
1007 
1008 		isc_buffer_init(&buf, ecs, sizeof(ecs));
1009 		/* family */
1010 		isc_buffer_putuint16(&buf, family);
1011 		/* source prefix-length */
1012 		isc_buffer_putuint8(&buf, client->ecs.source);
1013 		/* scope prefix-length */
1014 		isc_buffer_putuint8(&buf, client->ecs.scope);
1015 
1016 		/* address */
1017 		if (addrl > 0) {
1018 			/* Mask off last address byte */
1019 			if ((plen % 8) != 0) {
1020 				addr[addrl - 1] &= ~0U << (8 - (plen % 8));
1021 			}
1022 			isc_buffer_putmem(&buf, addr, (unsigned)addrl);
1023 		}
1024 
1025 		ednsopts[count].code = DNS_OPT_CLIENT_SUBNET;
1026 		ednsopts[count].length = addrl + 4;
1027 		ednsopts[count].value = ecs;
1028 		count++;
1029 	}
1030 	if (TCP_CLIENT(client) && USEKEEPALIVE(client)) {
1031 		isc_buffer_t buf;
1032 		uint32_t adv;
1033 
1034 		INSIST(count < DNS_EDNSOPTIONS);
1035 
1036 		isc_nm_tcp_gettimeouts(isc_nmhandle_netmgr(client->handle),
1037 				       NULL, NULL, NULL, &adv);
1038 		isc_buffer_init(&buf, advtimo, sizeof(advtimo));
1039 		isc_buffer_putuint16(&buf, (uint16_t)adv);
1040 		ednsopts[count].code = DNS_OPT_TCP_KEEPALIVE;
1041 		ednsopts[count].length = 2;
1042 		ednsopts[count].value = advtimo;
1043 		count++;
1044 	}
1045 
1046 	/* Padding must be added last */
1047 	if ((view != NULL) && (view->padding > 0) && WANTPAD(client) &&
1048 	    (TCP_CLIENT(client) ||
1049 	     ((client->attributes & NS_CLIENTATTR_HAVECOOKIE) != 0)))
1050 	{
1051 		isc_netaddr_t netaddr;
1052 		int match;
1053 
1054 		isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1055 		result = dns_acl_match(&netaddr, NULL, view->pad_acl, env,
1056 				       &match, NULL);
1057 		if (result == ISC_R_SUCCESS && match > 0) {
1058 			INSIST(count < DNS_EDNSOPTIONS);
1059 
1060 			ednsopts[count].code = DNS_OPT_PAD;
1061 			ednsopts[count].length = 0;
1062 			ednsopts[count].value = NULL;
1063 			count++;
1064 
1065 			dns_message_setpadding(message, view->padding);
1066 		}
1067 	}
1068 
1069 	result = dns_message_buildopt(message, opt, 0, udpsize, flags, ednsopts,
1070 				      count);
1071 	return (result);
1072 }
1073 
1074 static void
1075 compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce,
1076 	       const unsigned char *secret, isc_buffer_t *buf) {
1077 	unsigned char digest[ISC_MAX_MD_SIZE] ISC_NONSTRING = { 0 };
1078 	STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_SIPHASH24_TAG_LENGTH, "You need "
1079 								   "to "
1080 								   "increase "
1081 								   "the digest "
1082 								   "buffer.");
1083 	STATIC_ASSERT(ISC_MAX_MD_SIZE >= ISC_AES_BLOCK_LENGTH, "You need to "
1084 							       "increase the "
1085 							       "digest "
1086 							       "buffer.");
1087 
1088 	switch (client->sctx->cookiealg) {
1089 	case ns_cookiealg_siphash24: {
1090 		unsigned char input[16 + 16] ISC_NONSTRING = { 0 };
1091 		size_t inputlen = 0;
1092 		isc_netaddr_t netaddr;
1093 		unsigned char *cp;
1094 
1095 		cp = isc_buffer_used(buf);
1096 		isc_buffer_putmem(buf, client->cookie, 8);
1097 		isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1);
1098 		isc_buffer_putuint24(buf, 0); /* Reserved */
1099 		isc_buffer_putuint32(buf, when);
1100 
1101 		memmove(input, cp, 16);
1102 
1103 		isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1104 		switch (netaddr.family) {
1105 		case AF_INET:
1106 			cp = (unsigned char *)&netaddr.type.in;
1107 			memmove(input + 16, cp, 4);
1108 			inputlen = 20;
1109 			break;
1110 		case AF_INET6:
1111 			cp = (unsigned char *)&netaddr.type.in6;
1112 			memmove(input + 16, cp, 16);
1113 			inputlen = 32;
1114 			break;
1115 		default:
1116 			INSIST(0);
1117 			ISC_UNREACHABLE();
1118 		}
1119 
1120 		isc_siphash24(secret, input, inputlen, digest);
1121 		isc_buffer_putmem(buf, digest, 8);
1122 		break;
1123 	}
1124 	case ns_cookiealg_aes: {
1125 		unsigned char input[4 + 4 + 16] ISC_NONSTRING = { 0 };
1126 		isc_netaddr_t netaddr;
1127 		unsigned char *cp;
1128 		unsigned int i;
1129 
1130 		cp = isc_buffer_used(buf);
1131 		isc_buffer_putmem(buf, client->cookie, 8);
1132 		isc_buffer_putuint32(buf, nonce);
1133 		isc_buffer_putuint32(buf, when);
1134 		memmove(input, cp, 16);
1135 		isc_aes128_crypt(secret, input, digest);
1136 		for (i = 0; i < 8; i++) {
1137 			input[i] = digest[i] ^ digest[i + 8];
1138 		}
1139 		isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1140 		switch (netaddr.family) {
1141 		case AF_INET:
1142 			cp = (unsigned char *)&netaddr.type.in;
1143 			memmove(input + 8, cp, 4);
1144 			memset(input + 12, 0, 4);
1145 			isc_aes128_crypt(secret, input, digest);
1146 			break;
1147 		case AF_INET6:
1148 			cp = (unsigned char *)&netaddr.type.in6;
1149 			memmove(input + 8, cp, 16);
1150 			isc_aes128_crypt(secret, input, digest);
1151 			for (i = 0; i < 8; i++) {
1152 				input[i + 8] = digest[i] ^ digest[i + 8];
1153 			}
1154 			isc_aes128_crypt(client->sctx->secret, input + 8,
1155 					 digest);
1156 			break;
1157 		default:
1158 			INSIST(0);
1159 			ISC_UNREACHABLE();
1160 		}
1161 		for (i = 0; i < 8; i++) {
1162 			digest[i] ^= digest[i + 8];
1163 		}
1164 		isc_buffer_putmem(buf, digest, 8);
1165 		break;
1166 	}
1167 
1168 	default:
1169 		INSIST(0);
1170 		ISC_UNREACHABLE();
1171 	}
1172 }
1173 
1174 static void
1175 process_cookie(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1176 	ns_altsecret_t *altsecret;
1177 	unsigned char dbuf[COOKIE_SIZE];
1178 	unsigned char *old;
1179 	isc_stdtime_t now;
1180 	uint32_t when;
1181 	uint32_t nonce;
1182 	isc_buffer_t db;
1183 
1184 	/*
1185 	 * If we have already seen a cookie option skip this cookie option.
1186 	 */
1187 	if ((!client->sctx->answercookie) ||
1188 	    (client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0)
1189 	{
1190 		isc_buffer_forward(buf, (unsigned int)optlen);
1191 		return;
1192 	}
1193 
1194 	client->attributes |= NS_CLIENTATTR_WANTCOOKIE;
1195 
1196 	ns_stats_increment(client->sctx->nsstats, ns_statscounter_cookiein);
1197 
1198 	if (optlen != COOKIE_SIZE) {
1199 		/*
1200 		 * Not our token.
1201 		 */
1202 		INSIST(optlen >= 8U);
1203 		memmove(client->cookie, isc_buffer_current(buf), 8);
1204 		isc_buffer_forward(buf, (unsigned int)optlen);
1205 
1206 		if (optlen == 8U) {
1207 			ns_stats_increment(client->sctx->nsstats,
1208 					   ns_statscounter_cookienew);
1209 		} else {
1210 			ns_stats_increment(client->sctx->nsstats,
1211 					   ns_statscounter_cookiebadsize);
1212 		}
1213 		return;
1214 	}
1215 
1216 	/*
1217 	 * Process all of the incoming buffer.
1218 	 */
1219 	old = isc_buffer_current(buf);
1220 	memmove(client->cookie, old, 8);
1221 	isc_buffer_forward(buf, 8);
1222 	nonce = isc_buffer_getuint32(buf);
1223 	when = isc_buffer_getuint32(buf);
1224 	isc_buffer_forward(buf, 8);
1225 
1226 	/*
1227 	 * Allow for a 5 minute clock skew between servers sharing a secret.
1228 	 * Only accept COOKIE if we have talked to the client in the last hour.
1229 	 */
1230 	isc_stdtime_get(&now);
1231 	if (isc_serial_gt(when, (now + 300)) || /* In the future. */
1232 	    isc_serial_lt(when, (now - 3600)))
1233 	{ /* In the past. */
1234 		ns_stats_increment(client->sctx->nsstats,
1235 				   ns_statscounter_cookiebadtime);
1236 		return;
1237 	}
1238 
1239 	isc_buffer_init(&db, dbuf, sizeof(dbuf));
1240 	compute_cookie(client, when, nonce, client->sctx->secret, &db);
1241 
1242 	if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
1243 		ns_stats_increment(client->sctx->nsstats,
1244 				   ns_statscounter_cookiematch);
1245 		client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
1246 		return;
1247 	}
1248 
1249 	for (altsecret = ISC_LIST_HEAD(client->sctx->altsecrets);
1250 	     altsecret != NULL; altsecret = ISC_LIST_NEXT(altsecret, link))
1251 	{
1252 		isc_buffer_init(&db, dbuf, sizeof(dbuf));
1253 		compute_cookie(client, when, nonce, altsecret->secret, &db);
1254 		if (isc_safe_memequal(old, dbuf, COOKIE_SIZE)) {
1255 			ns_stats_increment(client->sctx->nsstats,
1256 					   ns_statscounter_cookiematch);
1257 			client->attributes |= NS_CLIENTATTR_HAVECOOKIE;
1258 			return;
1259 		}
1260 	}
1261 
1262 	ns_stats_increment(client->sctx->nsstats,
1263 			   ns_statscounter_cookienomatch);
1264 }
1265 
1266 static isc_result_t
1267 process_ecs(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1268 	uint16_t family;
1269 	uint8_t addrlen, addrbytes, scope, *paddr;
1270 	isc_netaddr_t caddr;
1271 
1272 	/*
1273 	 * If we have already seen a ECS option skip this ECS option.
1274 	 */
1275 	if ((client->attributes & NS_CLIENTATTR_HAVEECS) != 0) {
1276 		isc_buffer_forward(buf, (unsigned int)optlen);
1277 		return (ISC_R_SUCCESS);
1278 	}
1279 
1280 	/*
1281 	 * XXXMUKS: Is there any need to repeat these checks here
1282 	 * (except query's scope length) when they are done in the OPT
1283 	 * RDATA fromwire code?
1284 	 */
1285 
1286 	if (optlen < 4U) {
1287 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1288 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1289 			      "EDNS client-subnet option too short");
1290 		return (DNS_R_FORMERR);
1291 	}
1292 
1293 	family = isc_buffer_getuint16(buf);
1294 	addrlen = isc_buffer_getuint8(buf);
1295 	scope = isc_buffer_getuint8(buf);
1296 	optlen -= 4;
1297 
1298 	if (scope != 0U) {
1299 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1300 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1301 			      "EDNS client-subnet option: invalid scope");
1302 		return (DNS_R_OPTERR);
1303 	}
1304 
1305 	memset(&caddr, 0, sizeof(caddr));
1306 	switch (family) {
1307 	case 0:
1308 		/*
1309 		 * XXXMUKS: In queries, if FAMILY is set to 0, SOURCE
1310 		 * PREFIX-LENGTH must be 0 and ADDRESS should not be
1311 		 * present as the address and prefix lengths don't make
1312 		 * sense because the family is unknown.
1313 		 */
1314 		if (addrlen != 0U) {
1315 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1316 				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1317 				      "EDNS client-subnet option: invalid "
1318 				      "address length (%u) for FAMILY=0",
1319 				      addrlen);
1320 			return (DNS_R_OPTERR);
1321 		}
1322 		caddr.family = AF_UNSPEC;
1323 		break;
1324 	case 1:
1325 		if (addrlen > 32U) {
1326 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1327 				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1328 				      "EDNS client-subnet option: invalid "
1329 				      "address length (%u) for IPv4",
1330 				      addrlen);
1331 			return (DNS_R_OPTERR);
1332 		}
1333 		caddr.family = AF_INET;
1334 		break;
1335 	case 2:
1336 		if (addrlen > 128U) {
1337 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1338 				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1339 				      "EDNS client-subnet option: invalid "
1340 				      "address length (%u) for IPv6",
1341 				      addrlen);
1342 			return (DNS_R_OPTERR);
1343 		}
1344 		caddr.family = AF_INET6;
1345 		break;
1346 	default:
1347 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1348 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1349 			      "EDNS client-subnet option: invalid family");
1350 		return (DNS_R_OPTERR);
1351 	}
1352 
1353 	addrbytes = (addrlen + 7) / 8;
1354 	if (isc_buffer_remaininglength(buf) < addrbytes) {
1355 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1356 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2),
1357 			      "EDNS client-subnet option: address too short");
1358 		return (DNS_R_OPTERR);
1359 	}
1360 
1361 	paddr = (uint8_t *)&caddr.type;
1362 	if (addrbytes != 0U) {
1363 		memmove(paddr, isc_buffer_current(buf), addrbytes);
1364 		isc_buffer_forward(buf, addrbytes);
1365 		optlen -= addrbytes;
1366 
1367 		if ((addrlen % 8) != 0) {
1368 			uint8_t bits = ~0U << (8 - (addrlen % 8));
1369 			bits &= paddr[addrbytes - 1];
1370 			if (bits != paddr[addrbytes - 1]) {
1371 				return (DNS_R_OPTERR);
1372 			}
1373 		}
1374 	}
1375 
1376 	memmove(&client->ecs.addr, &caddr, sizeof(caddr));
1377 	client->ecs.source = addrlen;
1378 	client->ecs.scope = 0;
1379 	client->attributes |= NS_CLIENTATTR_HAVEECS;
1380 
1381 	isc_buffer_forward(buf, (unsigned int)optlen);
1382 	return (ISC_R_SUCCESS);
1383 }
1384 
1385 static isc_result_t
1386 process_keytag(ns_client_t *client, isc_buffer_t *buf, size_t optlen) {
1387 	if (optlen == 0 || (optlen % 2) != 0) {
1388 		isc_buffer_forward(buf, (unsigned int)optlen);
1389 		return (DNS_R_OPTERR);
1390 	}
1391 
1392 	/* Silently drop additional keytag options. */
1393 	if (client->keytag != NULL) {
1394 		isc_buffer_forward(buf, (unsigned int)optlen);
1395 		return (ISC_R_SUCCESS);
1396 	}
1397 
1398 	client->keytag = isc_mem_get(client->mctx, optlen);
1399 	{
1400 		client->keytag_len = (uint16_t)optlen;
1401 		memmove(client->keytag, isc_buffer_current(buf), optlen);
1402 	}
1403 	isc_buffer_forward(buf, (unsigned int)optlen);
1404 	return (ISC_R_SUCCESS);
1405 }
1406 
1407 static isc_result_t
1408 process_opt(ns_client_t *client, dns_rdataset_t *opt) {
1409 	dns_rdata_t rdata;
1410 	isc_buffer_t optbuf;
1411 	isc_result_t result;
1412 	uint16_t optcode;
1413 	uint16_t optlen;
1414 
1415 	/*
1416 	 * Set the client's UDP buffer size.
1417 	 */
1418 	client->udpsize = opt->rdclass;
1419 
1420 	/*
1421 	 * If the requested UDP buffer size is less than 512,
1422 	 * ignore it and use 512.
1423 	 */
1424 	if (client->udpsize < 512) {
1425 		client->udpsize = 512;
1426 	}
1427 
1428 	/*
1429 	 * Get the flags out of the OPT record.
1430 	 */
1431 	client->extflags = (uint16_t)(opt->ttl & 0xFFFF);
1432 
1433 	/*
1434 	 * Do we understand this version of EDNS?
1435 	 *
1436 	 * XXXRTH need library support for this!
1437 	 */
1438 	client->ednsversion = (opt->ttl & 0x00FF0000) >> 16;
1439 	if (client->ednsversion > DNS_EDNS_VERSION) {
1440 		ns_stats_increment(client->sctx->nsstats,
1441 				   ns_statscounter_badednsver);
1442 		result = ns_client_addopt(client, client->message,
1443 					  &client->opt);
1444 		if (result == ISC_R_SUCCESS) {
1445 			result = DNS_R_BADVERS;
1446 		}
1447 		ns_client_error(client, result);
1448 		return (result);
1449 	}
1450 
1451 	/* Check for NSID request */
1452 	result = dns_rdataset_first(opt);
1453 	if (result == ISC_R_SUCCESS) {
1454 		dns_rdata_init(&rdata);
1455 		dns_rdataset_current(opt, &rdata);
1456 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
1457 		isc_buffer_add(&optbuf, rdata.length);
1458 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
1459 			optcode = isc_buffer_getuint16(&optbuf);
1460 			optlen = isc_buffer_getuint16(&optbuf);
1461 			switch (optcode) {
1462 			case DNS_OPT_NSID:
1463 				if (!WANTNSID(client)) {
1464 					ns_stats_increment(
1465 						client->sctx->nsstats,
1466 						ns_statscounter_nsidopt);
1467 				}
1468 				client->attributes |= NS_CLIENTATTR_WANTNSID;
1469 				isc_buffer_forward(&optbuf, optlen);
1470 				break;
1471 			case DNS_OPT_COOKIE:
1472 				process_cookie(client, &optbuf, optlen);
1473 				break;
1474 			case DNS_OPT_EXPIRE:
1475 				if (!WANTEXPIRE(client)) {
1476 					ns_stats_increment(
1477 						client->sctx->nsstats,
1478 						ns_statscounter_expireopt);
1479 				}
1480 				client->attributes |= NS_CLIENTATTR_WANTEXPIRE;
1481 				isc_buffer_forward(&optbuf, optlen);
1482 				break;
1483 			case DNS_OPT_CLIENT_SUBNET:
1484 				result = process_ecs(client, &optbuf, optlen);
1485 				if (result != ISC_R_SUCCESS) {
1486 					ns_client_error(client, result);
1487 					return (result);
1488 				}
1489 				ns_stats_increment(client->sctx->nsstats,
1490 						   ns_statscounter_ecsopt);
1491 				break;
1492 			case DNS_OPT_TCP_KEEPALIVE:
1493 				if (!USEKEEPALIVE(client)) {
1494 					ns_stats_increment(
1495 						client->sctx->nsstats,
1496 						ns_statscounter_keepaliveopt);
1497 				}
1498 				client->attributes |=
1499 					NS_CLIENTATTR_USEKEEPALIVE;
1500 				isc_buffer_forward(&optbuf, optlen);
1501 				break;
1502 			case DNS_OPT_PAD:
1503 				client->attributes |= NS_CLIENTATTR_WANTPAD;
1504 				ns_stats_increment(client->sctx->nsstats,
1505 						   ns_statscounter_padopt);
1506 				isc_buffer_forward(&optbuf, optlen);
1507 				break;
1508 			case DNS_OPT_KEY_TAG:
1509 				result = process_keytag(client, &optbuf,
1510 							optlen);
1511 				if (result != ISC_R_SUCCESS) {
1512 					ns_client_error(client, result);
1513 					return (result);
1514 				}
1515 				ns_stats_increment(client->sctx->nsstats,
1516 						   ns_statscounter_keytagopt);
1517 				break;
1518 			default:
1519 				ns_stats_increment(client->sctx->nsstats,
1520 						   ns_statscounter_otheropt);
1521 				isc_buffer_forward(&optbuf, optlen);
1522 				break;
1523 			}
1524 		}
1525 	}
1526 
1527 	ns_stats_increment(client->sctx->nsstats, ns_statscounter_edns0in);
1528 	client->attributes |= NS_CLIENTATTR_WANTOPT;
1529 
1530 	return (result);
1531 }
1532 
1533 void
1534 ns__client_reset_cb(void *client0) {
1535 	ns_client_t *client = client0;
1536 
1537 	ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
1538 		      ISC_LOG_DEBUG(3), "reset client");
1539 
1540 	/*
1541 	 * We never started processing this client, possible if we're
1542 	 * shutting down, just exit.
1543 	 */
1544 	if (client->state == NS_CLIENTSTATE_READY) {
1545 		return;
1546 	}
1547 
1548 	ns_client_endrequest(client);
1549 	if (client->tcpbuf != NULL) {
1550 		isc_mem_put(client->mctx, client->tcpbuf,
1551 			    NS_CLIENT_TCP_BUFFER_SIZE);
1552 	}
1553 
1554 	if (client->keytag != NULL) {
1555 		isc_mem_put(client->mctx, client->keytag, client->keytag_len);
1556 		client->keytag_len = 0;
1557 	}
1558 
1559 	client->state = NS_CLIENTSTATE_READY;
1560 	INSIST(client->recursionquota == NULL);
1561 }
1562 
1563 void
1564 ns__client_put_cb(void *client0) {
1565 	ns_client_t *client = client0;
1566 
1567 	ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
1568 		      ISC_LOG_DEBUG(3), "freeing client");
1569 
1570 	/*
1571 	 * Call this first because it requires a valid client.
1572 	 */
1573 	ns_query_free(client);
1574 
1575 	client->magic = 0;
1576 	client->shuttingdown = true;
1577 
1578 	if (client->manager != NULL) {
1579 		clientmgr_detach(&client->manager);
1580 	}
1581 
1582 	isc_mem_put(client->mctx, client->sendbuf, NS_CLIENT_SEND_BUFFER_SIZE);
1583 	if (client->opt != NULL) {
1584 		INSIST(dns_rdataset_isassociated(client->opt));
1585 		dns_rdataset_disassociate(client->opt);
1586 		dns_message_puttemprdataset(client->message, &client->opt);
1587 	}
1588 
1589 	dns_message_destroy(&client->message);
1590 
1591 	/*
1592 	 * Detaching the task must be done after unlinking from
1593 	 * the manager's lists because the manager accesses
1594 	 * client->task.
1595 	 */
1596 	if (client->task != NULL) {
1597 		isc_task_detach(&client->task);
1598 	}
1599 
1600 	/*
1601 	 * Destroy the fetchlock mutex that was created in
1602 	 * ns_query_init().
1603 	 */
1604 	isc_mutex_destroy(&client->query.fetchlock);
1605 
1606 	if (client->sctx != NULL) {
1607 		ns_server_detach(&client->sctx);
1608 	}
1609 
1610 	if (client->mctx != NULL) {
1611 		isc_mem_detach(&client->mctx);
1612 	}
1613 }
1614 
1615 /*
1616  * Handle an incoming request event from the socket (UDP case)
1617  * or tcpmsg (TCP case).
1618  */
1619 void
1620 ns__client_request(isc_nmhandle_t *handle, isc_region_t *region, void *arg) {
1621 	ns_client_t *client;
1622 	ns_clientmgr_t *mgr;
1623 	ns_interface_t *ifp;
1624 	isc_result_t result;
1625 	isc_result_t sigresult = ISC_R_SUCCESS;
1626 	isc_buffer_t *buffer;
1627 	isc_buffer_t tbuffer;
1628 	dns_rdataset_t *opt;
1629 	const dns_name_t *signame;
1630 	bool ra; /* Recursion available. */
1631 	isc_netaddr_t netaddr;
1632 	int match;
1633 	dns_messageid_t id;
1634 	unsigned int flags;
1635 	bool notimp;
1636 	size_t reqsize;
1637 	dns_aclenv_t *env;
1638 #ifdef HAVE_DNSTAP
1639 	dns_dtmsgtype_t dtmsgtype;
1640 #endif /* ifdef HAVE_DNSTAP */
1641 	ifp = (ns_interface_t *)arg;
1642 
1643 	mgr = ifp->clientmgr;
1644 	if (mgr == NULL) {
1645 		/* The interface was shut down in the meantime, just bail */
1646 		return;
1647 	}
1648 
1649 	REQUIRE(VALID_MANAGER(mgr));
1650 
1651 	client = isc_nmhandle_getdata(handle);
1652 	if (client == NULL) {
1653 		client = isc_nmhandle_getextra(handle);
1654 
1655 		result = ns__client_setup(client, mgr, true);
1656 		if (result != ISC_R_SUCCESS) {
1657 			return;
1658 		}
1659 
1660 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1661 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
1662 			      "allocate new client");
1663 	} else {
1664 		result = ns__client_setup(client, NULL, false);
1665 		if (result != ISC_R_SUCCESS) {
1666 			return;
1667 		}
1668 	}
1669 
1670 	client->state = NS_CLIENTSTATE_READY;
1671 
1672 	isc_task_pause(client->task);
1673 	if (client->handle == NULL) {
1674 		isc_nmhandle_setdata(handle, client, ns__client_reset_cb,
1675 				     ns__client_put_cb);
1676 		client->handle = handle;
1677 	}
1678 	if (isc_nmhandle_is_stream(handle)) {
1679 		client->attributes |= NS_CLIENTATTR_TCP;
1680 	}
1681 
1682 	INSIST(client->recursionquota == NULL);
1683 
1684 	INSIST(client->state == NS_CLIENTSTATE_READY);
1685 
1686 	(void)atomic_fetch_add_relaxed(&ns_client_requests, 1);
1687 
1688 	isc_buffer_init(&tbuffer, region->base, region->length);
1689 	isc_buffer_add(&tbuffer, region->length);
1690 	buffer = &tbuffer;
1691 
1692 	client->peeraddr = isc_nmhandle_peeraddr(client->handle);
1693 
1694 	client->peeraddr_valid = true;
1695 
1696 	reqsize = isc_buffer_usedlength(buffer);
1697 
1698 	client->state = NS_CLIENTSTATE_WORKING;
1699 
1700 	TIME_NOW(&client->requesttime);
1701 	client->tnow = client->requesttime;
1702 	client->now = isc_time_seconds(&client->tnow);
1703 
1704 	isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
1705 
1706 #if NS_CLIENT_DROPPORT
1707 	if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) ==
1708 	    DROPPORT_REQUEST)
1709 	{
1710 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1711 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
1712 			      "dropped request: suspicious port");
1713 		isc_task_unpause(client->task);
1714 		return;
1715 	}
1716 #endif /* if NS_CLIENT_DROPPORT */
1717 
1718 	env = ns_interfacemgr_getaclenv(client->manager->interface->mgr);
1719 	if (client->sctx->blackholeacl != NULL &&
1720 	    (dns_acl_match(&netaddr, NULL, client->sctx->blackholeacl, env,
1721 			   &match, NULL) == ISC_R_SUCCESS) &&
1722 	    match > 0)
1723 	{
1724 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
1725 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
1726 			      "dropped request: blackholed peer");
1727 		isc_task_unpause(client->task);
1728 		return;
1729 	}
1730 
1731 	ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
1732 		      ISC_LOG_DEBUG(3), "%s request",
1733 		      TCP_CLIENT(client) ? "TCP" : "UDP");
1734 
1735 	result = dns_message_peekheader(buffer, &id, &flags);
1736 	if (result != ISC_R_SUCCESS) {
1737 		/*
1738 		 * There isn't enough header to determine whether
1739 		 * this was a request or a response.  Drop it.
1740 		 */
1741 		isc_task_unpause(client->task);
1742 		return;
1743 	}
1744 
1745 	/*
1746 	 * The client object handles requests, not responses.
1747 	 * If this is a UDP response, forward it to the dispatcher.
1748 	 * If it's a TCP response, discard it here.
1749 	 */
1750 	if ((flags & DNS_MESSAGEFLAG_QR) != 0) {
1751 		CTRACE("unexpected response");
1752 		isc_task_unpause(client->task);
1753 		return;
1754 	}
1755 
1756 	/*
1757 	 * Update some statistics counters.  Don't count responses.
1758 	 */
1759 	if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) {
1760 		ns_stats_increment(client->sctx->nsstats,
1761 				   ns_statscounter_requestv4);
1762 	} else {
1763 		ns_stats_increment(client->sctx->nsstats,
1764 				   ns_statscounter_requestv6);
1765 	}
1766 	if (TCP_CLIENT(client)) {
1767 		ns_stats_increment(client->sctx->nsstats,
1768 				   ns_statscounter_requesttcp);
1769 		switch (isc_sockaddr_pf(&client->peeraddr)) {
1770 		case AF_INET:
1771 			isc_stats_increment(client->sctx->tcpinstats4,
1772 					    ISC_MIN((int)reqsize / 16, 18));
1773 			break;
1774 		case AF_INET6:
1775 			isc_stats_increment(client->sctx->tcpinstats6,
1776 					    ISC_MIN((int)reqsize / 16, 18));
1777 			break;
1778 		default:
1779 			INSIST(0);
1780 			ISC_UNREACHABLE();
1781 		}
1782 	} else {
1783 		switch (isc_sockaddr_pf(&client->peeraddr)) {
1784 		case AF_INET:
1785 			isc_stats_increment(client->sctx->udpinstats4,
1786 					    ISC_MIN((int)reqsize / 16, 18));
1787 			break;
1788 		case AF_INET6:
1789 			isc_stats_increment(client->sctx->udpinstats6,
1790 					    ISC_MIN((int)reqsize / 16, 18));
1791 			break;
1792 		default:
1793 			INSIST(0);
1794 			ISC_UNREACHABLE();
1795 		}
1796 	}
1797 
1798 	/*
1799 	 * It's a request.  Parse it.
1800 	 */
1801 	result = dns_message_parse(client->message, buffer, 0);
1802 	if (result != ISC_R_SUCCESS) {
1803 		/*
1804 		 * Parsing the request failed.  Send a response
1805 		 * (typically FORMERR or SERVFAIL).
1806 		 */
1807 		if (result == DNS_R_OPTERR) {
1808 			(void)ns_client_addopt(client, client->message,
1809 					       &client->opt);
1810 		}
1811 
1812 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1813 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
1814 			      "message parsing failed: %s",
1815 			      isc_result_totext(result));
1816 		if (result == ISC_R_NOSPACE) {
1817 			result = DNS_R_FORMERR;
1818 		}
1819 		ns_client_error(client, result);
1820 		isc_task_unpause(client->task);
1821 		return;
1822 	}
1823 
1824 	/*
1825 	 * Disable pipelined TCP query processing if necessary.
1826 	 */
1827 	if (TCP_CLIENT(client) &&
1828 	    (client->message->opcode != dns_opcode_query ||
1829 	     (client->sctx->keepresporder != NULL &&
1830 	      dns_acl_allowed(&netaddr, NULL, client->sctx->keepresporder,
1831 			      env))))
1832 	{
1833 		isc_nm_tcpdns_sequential(handle);
1834 	}
1835 
1836 	dns_opcodestats_increment(client->sctx->opcodestats,
1837 				  client->message->opcode);
1838 	switch (client->message->opcode) {
1839 	case dns_opcode_query:
1840 	case dns_opcode_update:
1841 	case dns_opcode_notify:
1842 		notimp = false;
1843 		break;
1844 	case dns_opcode_iquery:
1845 	default:
1846 		notimp = true;
1847 		break;
1848 	}
1849 
1850 	client->message->rcode = dns_rcode_noerror;
1851 
1852 	/*
1853 	 * Deal with EDNS.
1854 	 */
1855 	if ((client->sctx->options & NS_SERVER_NOEDNS) != 0) {
1856 		opt = NULL;
1857 	} else {
1858 		opt = dns_message_getopt(client->message);
1859 	}
1860 
1861 	client->ecs.source = 0;
1862 	client->ecs.scope = 0;
1863 
1864 	if (opt != NULL) {
1865 		/*
1866 		 * Are returning FORMERR to all EDNS queries?
1867 		 * Simulate a STD13 compliant server.
1868 		 */
1869 		if ((client->sctx->options & NS_SERVER_EDNSFORMERR) != 0) {
1870 			ns_client_error(client, DNS_R_FORMERR);
1871 			isc_task_unpause(client->task);
1872 			return;
1873 		}
1874 
1875 		/*
1876 		 * Are returning NOTIMP to all EDNS queries?
1877 		 */
1878 		if ((client->sctx->options & NS_SERVER_EDNSNOTIMP) != 0) {
1879 			ns_client_error(client, DNS_R_NOTIMP);
1880 			isc_task_unpause(client->task);
1881 			return;
1882 		}
1883 
1884 		/*
1885 		 * Are returning REFUSED to all EDNS queries?
1886 		 */
1887 		if ((client->sctx->options & NS_SERVER_EDNSREFUSED) != 0) {
1888 			ns_client_error(client, DNS_R_REFUSED);
1889 			isc_task_unpause(client->task);
1890 			return;
1891 		}
1892 
1893 		/*
1894 		 * Are we dropping all EDNS queries?
1895 		 */
1896 		if ((client->sctx->options & NS_SERVER_DROPEDNS) != 0) {
1897 			ns_client_drop(client, ISC_R_SUCCESS);
1898 			isc_task_unpause(client->task);
1899 			return;
1900 		}
1901 
1902 		result = process_opt(client, opt);
1903 		if (result != ISC_R_SUCCESS) {
1904 			isc_task_unpause(client->task);
1905 			return;
1906 		}
1907 	}
1908 
1909 	if (client->message->rdclass == 0) {
1910 		if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 &&
1911 		    client->message->opcode == dns_opcode_query &&
1912 		    client->message->counts[DNS_SECTION_QUESTION] == 0U)
1913 		{
1914 			result = dns_message_reply(client->message, true);
1915 			if (result != ISC_R_SUCCESS) {
1916 				ns_client_error(client, result);
1917 				isc_task_unpause(client->task);
1918 				return;
1919 			}
1920 
1921 			if (notimp) {
1922 				client->message->rcode = dns_rcode_notimp;
1923 			}
1924 
1925 			ns_client_send(client);
1926 			isc_task_unpause(client->task);
1927 			return;
1928 		}
1929 
1930 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1931 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
1932 			      "message class could not be determined");
1933 		ns_client_dumpmessage(client, "message class could not be "
1934 					      "determined");
1935 		ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
1936 		isc_task_unpause(client->task);
1937 		return;
1938 	}
1939 
1940 	/*
1941 	 * Determine the destination address.  If the receiving interface is
1942 	 * bound to a specific address, we simply use it regardless of the
1943 	 * address family.  All IPv4 queries should fall into this case.
1944 	 * Otherwise, if this is a TCP query, get the address from the
1945 	 * receiving socket (this needs a system call and can be heavy).
1946 	 * For IPv6 UDP queries, we get this from the pktinfo structure (if
1947 	 * supported).
1948 	 *
1949 	 * If all the attempts fail (this can happen due to memory shortage,
1950 	 * etc), we regard this as an error for safety.
1951 	 */
1952 	if ((client->manager->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0)
1953 	{
1954 		isc_netaddr_fromsockaddr(&client->destaddr,
1955 					 &client->manager->interface->addr);
1956 	} else {
1957 		isc_sockaddr_t sockaddr =
1958 			isc_nmhandle_localaddr(client->handle);
1959 		isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr);
1960 	}
1961 
1962 	isc_sockaddr_fromnetaddr(&client->destsockaddr, &client->destaddr, 0);
1963 
1964 	result = client->sctx->matchingview(&netaddr, &client->destaddr,
1965 					    client->message, env, &sigresult,
1966 					    &client->view);
1967 	if (result != ISC_R_SUCCESS) {
1968 		char classname[DNS_RDATACLASS_FORMATSIZE];
1969 
1970 		/*
1971 		 * Do a dummy TSIG verification attempt so that the
1972 		 * response will have a TSIG if the query did, as
1973 		 * required by RFC2845.
1974 		 */
1975 		isc_buffer_t b;
1976 		isc_region_t *r;
1977 
1978 		dns_message_resetsig(client->message);
1979 
1980 		r = dns_message_getrawmessage(client->message);
1981 		isc_buffer_init(&b, r->base, r->length);
1982 		isc_buffer_add(&b, r->length);
1983 		(void)dns_tsig_verify(&b, client->message, NULL, NULL);
1984 
1985 		dns_rdataclass_format(client->message->rdclass, classname,
1986 				      sizeof(classname));
1987 		ns_client_log(client, NS_LOGCATEGORY_CLIENT,
1988 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
1989 			      "no matching view in class '%s'", classname);
1990 		ns_client_dumpmessage(client, "no matching view in class");
1991 		ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED);
1992 		isc_task_unpause(client->task);
1993 		return;
1994 	}
1995 
1996 	ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
1997 		      ISC_LOG_DEBUG(5), "using view '%s'", client->view->name);
1998 
1999 	/*
2000 	 * Check for a signature.  We log bad signatures regardless of
2001 	 * whether they ultimately cause the request to be rejected or
2002 	 * not.  We do not log the lack of a signature unless we are
2003 	 * debugging.
2004 	 */
2005 	client->signer = NULL;
2006 	dns_name_init(&client->signername, NULL);
2007 	result = dns_message_signer(client->message, &client->signername);
2008 	if (result != ISC_R_NOTFOUND) {
2009 		signame = NULL;
2010 		if (dns_message_gettsig(client->message, &signame) != NULL) {
2011 			ns_stats_increment(client->sctx->nsstats,
2012 					   ns_statscounter_tsigin);
2013 		} else {
2014 			ns_stats_increment(client->sctx->nsstats,
2015 					   ns_statscounter_sig0in);
2016 		}
2017 	}
2018 	if (result == ISC_R_SUCCESS) {
2019 		char namebuf[DNS_NAME_FORMATSIZE];
2020 		dns_name_format(&client->signername, namebuf, sizeof(namebuf));
2021 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2022 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2023 			      "request has valid signature: %s", namebuf);
2024 		client->signer = &client->signername;
2025 	} else if (result == ISC_R_NOTFOUND) {
2026 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2027 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2028 			      "request is not signed");
2029 	} else if (result == DNS_R_NOIDENTITY) {
2030 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2031 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2032 			      "request is signed by a nonauthoritative key");
2033 	} else {
2034 		char tsigrcode[64];
2035 		isc_buffer_t b;
2036 		dns_rcode_t status;
2037 		isc_result_t tresult;
2038 
2039 		/* There is a signature, but it is bad. */
2040 		ns_stats_increment(client->sctx->nsstats,
2041 				   ns_statscounter_invalidsig);
2042 		signame = NULL;
2043 		if (dns_message_gettsig(client->message, &signame) != NULL) {
2044 			char namebuf[DNS_NAME_FORMATSIZE];
2045 			char cnamebuf[DNS_NAME_FORMATSIZE];
2046 			dns_name_format(signame, namebuf, sizeof(namebuf));
2047 			status = client->message->tsigstatus;
2048 			isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
2049 			tresult = dns_tsigrcode_totext(status, &b);
2050 			INSIST(tresult == ISC_R_SUCCESS);
2051 			tsigrcode[isc_buffer_usedlength(&b)] = '\0';
2052 			if (client->message->tsigkey->generated) {
2053 				dns_name_format(
2054 					client->message->tsigkey->creator,
2055 					cnamebuf, sizeof(cnamebuf));
2056 				ns_client_log(
2057 					client, DNS_LOGCATEGORY_SECURITY,
2058 					NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
2059 					"request has invalid signature: "
2060 					"TSIG %s (%s): %s (%s)",
2061 					namebuf, cnamebuf,
2062 					isc_result_totext(result), tsigrcode);
2063 			} else {
2064 				ns_client_log(
2065 					client, DNS_LOGCATEGORY_SECURITY,
2066 					NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
2067 					"request has invalid signature: "
2068 					"TSIG %s: %s (%s)",
2069 					namebuf, isc_result_totext(result),
2070 					tsigrcode);
2071 			}
2072 		} else {
2073 			status = client->message->sig0status;
2074 			isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1);
2075 			tresult = dns_tsigrcode_totext(status, &b);
2076 			INSIST(tresult == ISC_R_SUCCESS);
2077 			tsigrcode[isc_buffer_usedlength(&b)] = '\0';
2078 			ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2079 				      NS_LOGMODULE_CLIENT, ISC_LOG_ERROR,
2080 				      "request has invalid signature: %s (%s)",
2081 				      isc_result_totext(result), tsigrcode);
2082 		}
2083 
2084 		/*
2085 		 * Accept update messages signed by unknown keys so that
2086 		 * update forwarding works transparently through slaves
2087 		 * that don't have all the same keys as the master.
2088 		 */
2089 		if (!(client->message->tsigstatus == dns_tsigerror_badkey &&
2090 		      client->message->opcode == dns_opcode_update))
2091 		{
2092 			ns_client_error(client, sigresult);
2093 			isc_task_unpause(client->task);
2094 			return;
2095 		}
2096 	}
2097 
2098 	/*
2099 	 * Decide whether recursive service is available to this client.
2100 	 * We do this here rather than in the query code so that we can
2101 	 * set the RA bit correctly on all kinds of responses, not just
2102 	 * responses to ordinary queries.  Note if you can't query the
2103 	 * cache there is no point in setting RA.
2104 	 */
2105 	ra = false;
2106 	if (client->view->resolver != NULL && client->view->recursion &&
2107 	    ns_client_checkaclsilent(client, NULL, client->view->recursionacl,
2108 				     true) == ISC_R_SUCCESS &&
2109 	    ns_client_checkaclsilent(client, NULL, client->view->cacheacl,
2110 				     true) == ISC_R_SUCCESS &&
2111 	    ns_client_checkaclsilent(client, &client->destaddr,
2112 				     client->view->recursiononacl,
2113 				     true) == ISC_R_SUCCESS &&
2114 	    ns_client_checkaclsilent(client, &client->destaddr,
2115 				     client->view->cacheonacl,
2116 				     true) == ISC_R_SUCCESS)
2117 	{
2118 		ra = true;
2119 	}
2120 
2121 	if (ra) {
2122 		client->attributes |= NS_CLIENTATTR_RA;
2123 	}
2124 
2125 	ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT,
2126 		      ISC_LOG_DEBUG(3),
2127 		      ra ? "recursion available" : "recursion not available");
2128 
2129 	/*
2130 	 * Adjust maximum UDP response size for this client.
2131 	 */
2132 	if (client->udpsize > 512) {
2133 		dns_peer_t *peer = NULL;
2134 		uint16_t udpsize = client->view->maxudp;
2135 		(void)dns_peerlist_peerbyaddr(client->view->peers, &netaddr,
2136 					      &peer);
2137 		if (peer != NULL) {
2138 			dns_peer_getmaxudp(peer, &udpsize);
2139 		}
2140 		if (client->udpsize > udpsize) {
2141 			client->udpsize = udpsize;
2142 		}
2143 	}
2144 
2145 	/*
2146 	 * Dispatch the request.
2147 	 */
2148 	switch (client->message->opcode) {
2149 	case dns_opcode_query:
2150 		CTRACE("query");
2151 #ifdef HAVE_DNSTAP
2152 		if (ra && (client->message->flags & DNS_MESSAGEFLAG_RD) != 0) {
2153 			dtmsgtype = DNS_DTTYPE_CQ;
2154 		} else {
2155 			dtmsgtype = DNS_DTTYPE_AQ;
2156 		}
2157 
2158 		dns_dt_send(client->view, dtmsgtype, &client->peeraddr,
2159 			    &client->destsockaddr, TCP_CLIENT(client), NULL,
2160 			    &client->requesttime, NULL, buffer);
2161 #endif /* HAVE_DNSTAP */
2162 
2163 		isc_nmhandle_ref(client->handle);
2164 		ns_query_start(client);
2165 		break;
2166 	case dns_opcode_update:
2167 		CTRACE("update");
2168 #ifdef HAVE_DNSTAP
2169 		dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr,
2170 			    &client->destsockaddr, TCP_CLIENT(client), NULL,
2171 			    &client->requesttime, NULL, buffer);
2172 #endif /* HAVE_DNSTAP */
2173 		ns_client_settimeout(client, 60);
2174 		isc_nmhandle_ref(client->handle);
2175 		ns_update_start(client, sigresult);
2176 		break;
2177 	case dns_opcode_notify:
2178 		CTRACE("notify");
2179 		ns_client_settimeout(client, 60);
2180 		isc_nmhandle_ref(client->handle);
2181 		ns_notify_start(client);
2182 		break;
2183 	case dns_opcode_iquery:
2184 		CTRACE("iquery");
2185 		ns_client_error(client, DNS_R_NOTIMP);
2186 		break;
2187 	default:
2188 		CTRACE("unknown opcode");
2189 		ns_client_error(client, DNS_R_NOTIMP);
2190 	}
2191 
2192 	isc_task_unpause(client->task);
2193 }
2194 
2195 isc_result_t
2196 ns__client_tcpconn(isc_nmhandle_t *handle, isc_result_t result, void *arg) {
2197 	ns_interface_t *ifp = (ns_interface_t *)arg;
2198 	dns_aclenv_t *env = ns_interfacemgr_getaclenv(ifp->mgr);
2199 	ns_server_t *sctx = ns_interfacemgr_getserver(ifp->mgr);
2200 	unsigned int tcpquota;
2201 	isc_sockaddr_t peeraddr;
2202 	isc_netaddr_t netaddr;
2203 	int match;
2204 
2205 	UNUSED(result);
2206 
2207 	if (handle != NULL) {
2208 		peeraddr = isc_nmhandle_peeraddr(handle);
2209 		isc_netaddr_fromsockaddr(&netaddr, &peeraddr);
2210 
2211 		if (sctx->blackholeacl != NULL &&
2212 		    (dns_acl_match(&netaddr, NULL, sctx->blackholeacl, env,
2213 				   &match, NULL) == ISC_R_SUCCESS) &&
2214 		    match > 0)
2215 		{
2216 			return (ISC_R_CONNREFUSED);
2217 		}
2218 	}
2219 
2220 	tcpquota = isc_quota_getused(&sctx->tcpquota);
2221 	ns_stats_update_if_greater(sctx->nsstats, ns_statscounter_tcphighwater,
2222 				   tcpquota);
2223 
2224 	return (ISC_R_SUCCESS);
2225 }
2226 
2227 static void
2228 get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) {
2229 	isc_mem_t *clientmctx;
2230 	MTRACE("clientmctx");
2231 
2232 	int tid = isc_nm_tid();
2233 	if (tid < 0) {
2234 		tid = isc_random_uniform(manager->ncpus);
2235 	}
2236 	int rand = isc_random_uniform(CLIENT_NMCTXS_PERCPU);
2237 	int nextmctx = (rand * manager->ncpus) + tid;
2238 	clientmctx = manager->mctxpool[nextmctx];
2239 
2240 	isc_mem_attach(clientmctx, mctxp);
2241 }
2242 
2243 static void
2244 get_clienttask(ns_clientmgr_t *manager, isc_task_t **taskp) {
2245 	MTRACE("clienttask");
2246 
2247 	int tid = isc_nm_tid();
2248 	if (tid < 0) {
2249 		tid = isc_random_uniform(manager->ncpus);
2250 	}
2251 
2252 	int rand = isc_random_uniform(CLIENT_NTASKS_PERCPU);
2253 	int nexttask = (rand * manager->ncpus) + tid;
2254 	isc_task_attach(manager->taskpool[nexttask], taskp);
2255 }
2256 
2257 isc_result_t
2258 ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
2259 	isc_result_t result;
2260 
2261 	/*
2262 	 * Caller must be holding the manager lock.
2263 	 *
2264 	 * Note: creating a client does not add the client to the
2265 	 * manager's client list or set the client's manager pointer.
2266 	 * The caller is responsible for that.
2267 	 */
2268 
2269 	REQUIRE(NS_CLIENT_VALID(client) || (new &&client != NULL));
2270 	REQUIRE(VALID_MANAGER(mgr) || !new);
2271 
2272 	if (new) {
2273 		*client = (ns_client_t){ .magic = 0 };
2274 
2275 		get_clientmctx(mgr, &client->mctx);
2276 		clientmgr_attach(mgr, &client->manager);
2277 		ns_server_attach(mgr->sctx, &client->sctx);
2278 		get_clienttask(mgr, &client->task);
2279 
2280 		result = dns_message_create(client->mctx,
2281 					    DNS_MESSAGE_INTENTPARSE,
2282 					    &client->message);
2283 		if (result != ISC_R_SUCCESS) {
2284 			goto cleanup;
2285 		}
2286 
2287 		client->sendbuf = isc_mem_get(client->mctx,
2288 					      NS_CLIENT_SEND_BUFFER_SIZE);
2289 		/*
2290 		 * Set magic earlier than usual because ns_query_init()
2291 		 * and the functions it calls will require it.
2292 		 */
2293 		client->magic = NS_CLIENT_MAGIC;
2294 		result = ns_query_init(client);
2295 		if (result != ISC_R_SUCCESS) {
2296 			goto cleanup;
2297 		}
2298 	} else {
2299 		ns_clientmgr_t *oldmgr = client->manager;
2300 		ns_server_t *sctx = client->sctx;
2301 		isc_task_t *task = client->task;
2302 		unsigned char *sendbuf = client->sendbuf;
2303 		dns_message_t *message = client->message;
2304 		isc_mem_t *oldmctx = client->mctx;
2305 		ns_query_t query = client->query;
2306 
2307 		/*
2308 		 * Retain these values from the existing client, but
2309 		 * zero every thing else.
2310 		 */
2311 #ifndef __lint__
2312 /* XXX: bug ? */
2313 		*client = (ns_client_t){ .magic = 0,
2314 					 .mctx = oldmctx,
2315 					 .manager = oldmgr,
2316 					 .sctx = sctx,
2317 					 .task = task,
2318 					 .sendbuf = sendbuf,
2319 					 .message = message,
2320 					 .query = query };
2321 #endif
2322 	}
2323 
2324 	client->state = NS_CLIENTSTATE_INACTIVE;
2325 	client->udpsize = 512;
2326 	client->ednsversion = -1;
2327 	dns_name_init(&client->signername, NULL);
2328 	dns_ecs_init(&client->ecs);
2329 	isc_sockaddr_any(&client->formerrcache.addr);
2330 	client->formerrcache.time = 0;
2331 	client->formerrcache.id = 0;
2332 	ISC_LINK_INIT(client, rlink);
2333 	client->rcode_override = -1; /* not set */
2334 
2335 	client->magic = NS_CLIENT_MAGIC;
2336 
2337 	CTRACE("client_setup");
2338 
2339 	return (ISC_R_SUCCESS);
2340 
2341 cleanup:
2342 	if (client->sendbuf != NULL) {
2343 		isc_mem_put(client->mctx, client->sendbuf,
2344 			    NS_CLIENT_SEND_BUFFER_SIZE);
2345 	}
2346 
2347 	if (client->message != NULL) {
2348 		dns_message_destroy(&client->message);
2349 	}
2350 
2351 	if (client->task != NULL) {
2352 		isc_task_detach(&client->task);
2353 	}
2354 
2355 	if (client->manager != NULL) {
2356 		clientmgr_detach(&client->manager);
2357 	}
2358 	if (client->mctx != NULL) {
2359 		isc_mem_detach(&client->mctx);
2360 	}
2361 	if (client->sctx != NULL) {
2362 		ns_server_detach(&client->sctx);
2363 	}
2364 
2365 	return (result);
2366 }
2367 
2368 bool
2369 ns_client_shuttingdown(ns_client_t *client) {
2370 	return (client->shuttingdown);
2371 }
2372 
2373 /***
2374  *** Client Manager
2375  ***/
2376 
2377 static void
2378 clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp) {
2379 	int32_t oldrefs;
2380 
2381 	REQUIRE(VALID_MANAGER(source));
2382 	REQUIRE(targetp != NULL && *targetp == NULL);
2383 
2384 	oldrefs = isc_refcount_increment0(&source->references);
2385 	isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
2386 		      ISC_LOG_DEBUG(3), "clientmgr @%p attach: %d", source,
2387 		      oldrefs + 1);
2388 
2389 	*targetp = source;
2390 }
2391 
2392 static void
2393 clientmgr_detach(ns_clientmgr_t **mp) {
2394 	int32_t oldrefs;
2395 	ns_clientmgr_t *mgr = *mp;
2396 	*mp = NULL;
2397 
2398 	oldrefs = isc_refcount_decrement(&mgr->references);
2399 	isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT,
2400 		      ISC_LOG_DEBUG(3), "clientmgr @%p detach: %d", mgr,
2401 		      oldrefs - 1);
2402 	if (oldrefs == 1) {
2403 		clientmgr_destroy(mgr);
2404 	}
2405 }
2406 
2407 static void
2408 clientmgr_destroy(ns_clientmgr_t *manager) {
2409 	int i;
2410 
2411 	MTRACE("clientmgr_destroy");
2412 
2413 	isc_refcount_destroy(&manager->references);
2414 	manager->magic = 0;
2415 
2416 	for (i = 0; i < manager->ncpus * CLIENT_NMCTXS_PERCPU; i++) {
2417 		isc_mem_detach(&manager->mctxpool[i]);
2418 	}
2419 	isc_mem_put(manager->mctx, manager->mctxpool,
2420 		    manager->ncpus * CLIENT_NMCTXS_PERCPU *
2421 			    sizeof(isc_mem_t *));
2422 
2423 	if (manager->interface != NULL) {
2424 		ns_interface_detach(&manager->interface);
2425 	}
2426 
2427 	isc_mutex_destroy(&manager->lock);
2428 	isc_mutex_destroy(&manager->reclock);
2429 
2430 	if (manager->excl != NULL) {
2431 		isc_task_detach(&manager->excl);
2432 	}
2433 
2434 	for (i = 0; i < manager->ncpus * CLIENT_NTASKS_PERCPU; i++) {
2435 		if (manager->taskpool[i] != NULL) {
2436 			isc_task_detach(&manager->taskpool[i]);
2437 		}
2438 	}
2439 	isc_mem_put(manager->mctx, manager->taskpool,
2440 		    manager->ncpus * CLIENT_NTASKS_PERCPU *
2441 			    sizeof(isc_task_t *));
2442 	ns_server_detach(&manager->sctx);
2443 
2444 	isc_mem_put(manager->mctx, manager, sizeof(*manager));
2445 }
2446 
2447 isc_result_t
2448 ns_clientmgr_create(isc_mem_t *mctx, ns_server_t *sctx, isc_taskmgr_t *taskmgr,
2449 		    isc_timermgr_t *timermgr, ns_interface_t *interface,
2450 		    int ncpus, ns_clientmgr_t **managerp) {
2451 	ns_clientmgr_t *manager;
2452 	isc_result_t result;
2453 	int i;
2454 	int npools;
2455 
2456 	manager = isc_mem_get(mctx, sizeof(*manager));
2457 	*manager = (ns_clientmgr_t){ .magic = 0 };
2458 
2459 	isc_mutex_init(&manager->lock);
2460 	isc_mutex_init(&manager->reclock);
2461 
2462 	manager->excl = NULL;
2463 	result = isc_taskmgr_excltask(taskmgr, &manager->excl);
2464 	if (result != ISC_R_SUCCESS) {
2465 		goto cleanup_reclock;
2466 	}
2467 
2468 	manager->mctx = mctx;
2469 	manager->taskmgr = taskmgr;
2470 	manager->timermgr = timermgr;
2471 	manager->ncpus = ncpus;
2472 
2473 	ns_interface_attach(interface, &manager->interface);
2474 
2475 	manager->exiting = false;
2476 	int ntasks = CLIENT_NTASKS_PERCPU * manager->ncpus;
2477 	manager->taskpool = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
2478 	for (i = 0; i < ntasks; i++) {
2479 		manager->taskpool[i] = NULL;
2480 		result = isc_task_create_bound(manager->taskmgr, 20,
2481 					       &manager->taskpool[i],
2482 					       i % CLIENT_NTASKS_PERCPU);
2483 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
2484 	}
2485 	isc_refcount_init(&manager->references, 1);
2486 	manager->sctx = NULL;
2487 	ns_server_attach(sctx, &manager->sctx);
2488 
2489 	ISC_LIST_INIT(manager->recursing);
2490 
2491 	npools = CLIENT_NMCTXS_PERCPU * manager->ncpus;
2492 	manager->mctxpool = isc_mem_get(manager->mctx,
2493 					npools * sizeof(isc_mem_t *));
2494 	for (i = 0; i < npools; i++) {
2495 		manager->mctxpool[i] = NULL;
2496 		isc_mem_create(&manager->mctxpool[i]);
2497 		isc_mem_setname(manager->mctxpool[i], "client", NULL);
2498 	}
2499 
2500 	manager->magic = MANAGER_MAGIC;
2501 
2502 	MTRACE("create");
2503 
2504 	*managerp = manager;
2505 
2506 	return (ISC_R_SUCCESS);
2507 
2508 cleanup_reclock:
2509 	isc_mutex_destroy(&manager->reclock);
2510 	isc_mutex_destroy(&manager->lock);
2511 
2512 	isc_mem_put(manager->mctx, manager, sizeof(*manager));
2513 
2514 	return (result);
2515 }
2516 
2517 void
2518 ns_clientmgr_destroy(ns_clientmgr_t **managerp) {
2519 	isc_result_t result;
2520 	ns_clientmgr_t *manager;
2521 	bool unlock = false;
2522 
2523 	REQUIRE(managerp != NULL);
2524 	manager = *managerp;
2525 	*managerp = NULL;
2526 	REQUIRE(VALID_MANAGER(manager));
2527 
2528 	MTRACE("destroy");
2529 
2530 	/*
2531 	 * Check for success because we may already be task-exclusive
2532 	 * at this point.  Only if we succeed at obtaining an exclusive
2533 	 * lock now will we need to relinquish it later.
2534 	 */
2535 	result = isc_task_beginexclusive(manager->excl);
2536 	if (result == ISC_R_SUCCESS) {
2537 		unlock = true;
2538 	}
2539 
2540 	manager->exiting = true;
2541 
2542 	if (unlock) {
2543 		isc_task_endexclusive(manager->excl);
2544 	}
2545 
2546 	if (isc_refcount_decrement(&manager->references) == 1) {
2547 		clientmgr_destroy(manager);
2548 	}
2549 }
2550 
2551 isc_sockaddr_t *
2552 ns_client_getsockaddr(ns_client_t *client) {
2553 	return (&client->peeraddr);
2554 }
2555 
2556 isc_sockaddr_t *
2557 ns_client_getdestaddr(ns_client_t *client) {
2558 	return (&client->destsockaddr);
2559 }
2560 
2561 isc_result_t
2562 ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr,
2563 			 dns_acl_t *acl, bool default_allow) {
2564 	isc_result_t result;
2565 	dns_aclenv_t *env =
2566 		ns_interfacemgr_getaclenv(client->manager->interface->mgr);
2567 	isc_netaddr_t tmpnetaddr;
2568 	int match;
2569 
2570 	if (acl == NULL) {
2571 		if (default_allow) {
2572 			goto allow;
2573 		} else {
2574 			goto deny;
2575 		}
2576 	}
2577 
2578 	if (netaddr == NULL) {
2579 		isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr);
2580 		netaddr = &tmpnetaddr;
2581 	}
2582 
2583 	result = dns_acl_match(netaddr, client->signer, acl, env, &match, NULL);
2584 	if (result != ISC_R_SUCCESS) {
2585 		goto deny; /* Internal error, already logged. */
2586 	}
2587 
2588 	if (match > 0) {
2589 		goto allow;
2590 	}
2591 	goto deny; /* Negative match or no match. */
2592 
2593 allow:
2594 	return (ISC_R_SUCCESS);
2595 
2596 deny:
2597 	return (DNS_R_REFUSED);
2598 }
2599 
2600 isc_result_t
2601 ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr,
2602 		   const char *opname, dns_acl_t *acl, bool default_allow,
2603 		   int log_level) {
2604 	isc_result_t result;
2605 	isc_netaddr_t netaddr;
2606 
2607 	if (sockaddr != NULL) {
2608 		isc_netaddr_fromsockaddr(&netaddr, sockaddr);
2609 	}
2610 
2611 	result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
2612 					  acl, default_allow);
2613 
2614 	if (result == ISC_R_SUCCESS) {
2615 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2616 			      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
2617 			      "%s approved", opname);
2618 	} else {
2619 		ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
2620 			      NS_LOGMODULE_CLIENT, log_level, "%s denied",
2621 			      opname);
2622 	}
2623 	return (result);
2624 }
2625 
2626 static void
2627 ns_client_name(ns_client_t *client, char *peerbuf, size_t len) {
2628 	if (client->peeraddr_valid) {
2629 		isc_sockaddr_format(&client->peeraddr, peerbuf,
2630 				    (unsigned int)len);
2631 	} else {
2632 		snprintf(peerbuf, len, "@%p", client);
2633 	}
2634 }
2635 
2636 void
2637 ns_client_logv(ns_client_t *client, isc_logcategory_t *category,
2638 	       isc_logmodule_t *module, int level, const char *fmt,
2639 	       va_list ap) {
2640 	char msgbuf[4096];
2641 	char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE];
2642 	char peerbuf[ISC_SOCKADDR_FORMATSIZE];
2643 	const char *viewname = "";
2644 	const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = "";
2645 	const char *signer = "", *qname = "";
2646 	dns_name_t *q = NULL;
2647 
2648 	REQUIRE(client != NULL);
2649 
2650 	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
2651 
2652 	if (client->signer != NULL) {
2653 		dns_name_format(client->signer, signerbuf, sizeof(signerbuf));
2654 		sep1 = "/key ";
2655 		signer = signerbuf;
2656 	}
2657 
2658 	q = client->query.origqname != NULL ? client->query.origqname
2659 					    : client->query.qname;
2660 	if (q != NULL) {
2661 		dns_name_format(q, qnamebuf, sizeof(qnamebuf));
2662 		sep2 = " (";
2663 		sep3 = ")";
2664 		qname = qnamebuf;
2665 	}
2666 
2667 	if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 &&
2668 	    strcmp(client->view->name, "_default") != 0)
2669 	{
2670 		sep4 = ": view ";
2671 		viewname = client->view->name;
2672 	}
2673 
2674 	if (client->peeraddr_valid) {
2675 		isc_sockaddr_format(&client->peeraddr, peerbuf,
2676 				    sizeof(peerbuf));
2677 	} else {
2678 		snprintf(peerbuf, sizeof(peerbuf), "(no-peer)");
2679 	}
2680 
2681 	isc_log_write(ns_lctx, category, module, level,
2682 		      "client @%p %s%s%s%s%s%s%s%s: %s", client, peerbuf, sep1,
2683 		      signer, sep2, qname, sep3, sep4, viewname, msgbuf);
2684 }
2685 
2686 void
2687 ns_client_log(ns_client_t *client, isc_logcategory_t *category,
2688 	      isc_logmodule_t *module, int level, const char *fmt, ...) {
2689 	va_list ap;
2690 
2691 	if (!isc_log_wouldlog(ns_lctx, level)) {
2692 		return;
2693 	}
2694 
2695 	va_start(ap, fmt);
2696 	ns_client_logv(client, category, module, level, fmt, ap);
2697 	va_end(ap);
2698 }
2699 
2700 void
2701 ns_client_aclmsg(const char *msg, const dns_name_t *name, dns_rdatatype_t type,
2702 		 dns_rdataclass_t rdclass, char *buf, size_t len) {
2703 	char namebuf[DNS_NAME_FORMATSIZE];
2704 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
2705 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
2706 
2707 	dns_name_format(name, namebuf, sizeof(namebuf));
2708 	dns_rdatatype_format(type, typebuf, sizeof(typebuf));
2709 	dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf));
2710 	(void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf,
2711 		       classbuf);
2712 }
2713 
2714 static void
2715 ns_client_dumpmessage(ns_client_t *client, const char *reason) {
2716 	isc_buffer_t buffer;
2717 	char *buf = NULL;
2718 	int len = 1024;
2719 	isc_result_t result;
2720 
2721 	if (!isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1))) {
2722 		return;
2723 	}
2724 
2725 	/*
2726 	 * Note that these are multiline debug messages.  We want a newline
2727 	 * to appear in the log after each message.
2728 	 */
2729 
2730 	do {
2731 		buf = isc_mem_get(client->mctx, len);
2732 		isc_buffer_init(&buffer, buf, len);
2733 		result = dns_message_totext(
2734 			client->message, &dns_master_style_debug, 0, &buffer);
2735 		if (result == ISC_R_NOSPACE) {
2736 			isc_mem_put(client->mctx, buf, len);
2737 			len += 1024;
2738 		} else if (result == ISC_R_SUCCESS) {
2739 			ns_client_log(client, NS_LOGCATEGORY_CLIENT,
2740 				      NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
2741 				      "%s\n%.*s", reason,
2742 				      (int)isc_buffer_usedlength(&buffer), buf);
2743 		}
2744 	} while (result == ISC_R_NOSPACE);
2745 
2746 	if (buf != NULL) {
2747 		isc_mem_put(client->mctx, buf, len);
2748 	}
2749 }
2750 
2751 void
2752 ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) {
2753 	ns_client_t *client;
2754 	char namebuf[DNS_NAME_FORMATSIZE];
2755 	char original[DNS_NAME_FORMATSIZE];
2756 	char peerbuf[ISC_SOCKADDR_FORMATSIZE];
2757 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
2758 	char classbuf[DNS_RDATACLASS_FORMATSIZE];
2759 	const char *name;
2760 	const char *sep;
2761 	const char *origfor;
2762 	dns_rdataset_t *rdataset;
2763 
2764 	REQUIRE(VALID_MANAGER(manager));
2765 
2766 	LOCK(&manager->reclock);
2767 	client = ISC_LIST_HEAD(manager->recursing);
2768 	while (client != NULL) {
2769 		INSIST(client->state == NS_CLIENTSTATE_RECURSING);
2770 
2771 		ns_client_name(client, peerbuf, sizeof(peerbuf));
2772 		if (client->view != NULL &&
2773 		    strcmp(client->view->name, "_bind") != 0 &&
2774 		    strcmp(client->view->name, "_default") != 0)
2775 		{
2776 			name = client->view->name;
2777 			sep = ": view ";
2778 		} else {
2779 			name = "";
2780 			sep = "";
2781 		}
2782 
2783 		LOCK(&client->query.fetchlock);
2784 		INSIST(client->query.qname != NULL);
2785 		dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
2786 		if (client->query.qname != client->query.origqname &&
2787 		    client->query.origqname != NULL)
2788 		{
2789 			origfor = " for ";
2790 			dns_name_format(client->query.origqname, original,
2791 					sizeof(original));
2792 		} else {
2793 			origfor = "";
2794 			original[0] = '\0';
2795 		}
2796 		rdataset = ISC_LIST_HEAD(client->query.qname->list);
2797 		if (rdataset == NULL && client->query.origqname != NULL) {
2798 			rdataset = ISC_LIST_HEAD(client->query.origqname->list);
2799 		}
2800 		if (rdataset != NULL) {
2801 			dns_rdatatype_format(rdataset->type, typebuf,
2802 					     sizeof(typebuf));
2803 			dns_rdataclass_format(rdataset->rdclass, classbuf,
2804 					      sizeof(classbuf));
2805 		} else {
2806 			strlcpy(typebuf, "-", sizeof(typebuf));
2807 			strlcpy(classbuf, "-", sizeof(classbuf));
2808 		}
2809 		UNLOCK(&client->query.fetchlock);
2810 		fprintf(f,
2811 			"; client %s%s%s: id %u '%s/%s/%s'%s%s "
2812 			"requesttime %u\n",
2813 			peerbuf, sep, name, client->message->id, namebuf,
2814 			typebuf, classbuf, origfor, original,
2815 			isc_time_seconds(&client->requesttime));
2816 		client = ISC_LIST_NEXT(client, rlink);
2817 	}
2818 	UNLOCK(&manager->reclock);
2819 }
2820 
2821 void
2822 ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) {
2823 	LOCK(&client->query.fetchlock);
2824 	if (client->query.restarts > 0) {
2825 		/*
2826 		 * client->query.qname was dynamically allocated.
2827 		 */
2828 		dns_message_puttempname(client->message, &client->query.qname);
2829 	}
2830 	client->query.qname = name;
2831 	client->query.attributes &= ~NS_QUERYATTR_REDIRECT;
2832 	UNLOCK(&client->query.fetchlock);
2833 }
2834 
2835 isc_result_t
2836 ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) {
2837 	ns_client_t *client = (ns_client_t *)ci->data;
2838 
2839 	REQUIRE(NS_CLIENT_VALID(client));
2840 	REQUIRE(addrp != NULL);
2841 
2842 	*addrp = &client->peeraddr;
2843 	return (ISC_R_SUCCESS);
2844 }
2845 
2846 dns_rdataset_t *
2847 ns_client_newrdataset(ns_client_t *client) {
2848 	dns_rdataset_t *rdataset;
2849 	isc_result_t result;
2850 
2851 	REQUIRE(NS_CLIENT_VALID(client));
2852 
2853 	rdataset = NULL;
2854 	result = dns_message_gettemprdataset(client->message, &rdataset);
2855 	if (result != ISC_R_SUCCESS) {
2856 		return (NULL);
2857 	}
2858 
2859 	return (rdataset);
2860 }
2861 
2862 void
2863 ns_client_putrdataset(ns_client_t *client, dns_rdataset_t **rdatasetp) {
2864 	dns_rdataset_t *rdataset;
2865 
2866 	REQUIRE(NS_CLIENT_VALID(client));
2867 	REQUIRE(rdatasetp != NULL);
2868 
2869 	rdataset = *rdatasetp;
2870 
2871 	if (rdataset != NULL) {
2872 		if (dns_rdataset_isassociated(rdataset)) {
2873 			dns_rdataset_disassociate(rdataset);
2874 		}
2875 		dns_message_puttemprdataset(client->message, rdatasetp);
2876 	}
2877 }
2878 
2879 isc_result_t
2880 ns_client_newnamebuf(ns_client_t *client) {
2881 	isc_buffer_t *dbuf;
2882 
2883 	CTRACE("ns_client_newnamebuf");
2884 
2885 	dbuf = NULL;
2886 	isc_buffer_allocate(client->mctx, &dbuf, 1024);
2887 	ISC_LIST_APPEND(client->query.namebufs, dbuf, link);
2888 
2889 	CTRACE("ns_client_newnamebuf: done");
2890 	return (ISC_R_SUCCESS);
2891 }
2892 
2893 dns_name_t *
2894 ns_client_newname(ns_client_t *client, isc_buffer_t *dbuf, isc_buffer_t *nbuf) {
2895 	dns_name_t *name;
2896 	isc_region_t r;
2897 	isc_result_t result;
2898 
2899 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) == 0);
2900 
2901 	CTRACE("ns_client_newname");
2902 
2903 	name = NULL;
2904 	result = dns_message_gettempname(client->message, &name);
2905 	if (result != ISC_R_SUCCESS) {
2906 		CTRACE("ns_client_newname: "
2907 		       "dns_message_gettempname failed: done");
2908 		return (NULL);
2909 	}
2910 	isc_buffer_availableregion(dbuf, &r);
2911 	isc_buffer_init(nbuf, r.base, r.length);
2912 	dns_name_init(name, NULL);
2913 	dns_name_setbuffer(name, nbuf);
2914 	client->query.attributes |= NS_QUERYATTR_NAMEBUFUSED;
2915 
2916 	CTRACE("ns_client_newname: done");
2917 	return (name);
2918 }
2919 
2920 isc_buffer_t *
2921 ns_client_getnamebuf(ns_client_t *client) {
2922 	isc_buffer_t *dbuf;
2923 	isc_result_t result;
2924 	isc_region_t r;
2925 
2926 	CTRACE("ns_client_getnamebuf");
2927 
2928 	/*%
2929 	 * Return a name buffer with space for a maximal name, allocating
2930 	 * a new one if necessary.
2931 	 */
2932 	if (ISC_LIST_EMPTY(client->query.namebufs)) {
2933 		result = ns_client_newnamebuf(client);
2934 		if (result != ISC_R_SUCCESS) {
2935 			CTRACE("ns_client_getnamebuf: "
2936 			       "ns_client_newnamebuf failed: done");
2937 			return (NULL);
2938 		}
2939 	}
2940 
2941 	dbuf = ISC_LIST_TAIL(client->query.namebufs);
2942 	INSIST(dbuf != NULL);
2943 	isc_buffer_availableregion(dbuf, &r);
2944 	if (r.length < DNS_NAME_MAXWIRE) {
2945 		result = ns_client_newnamebuf(client);
2946 		if (result != ISC_R_SUCCESS) {
2947 			CTRACE("ns_client_getnamebuf: "
2948 			       "ns_client_newnamebuf failed: done");
2949 			return (NULL);
2950 		}
2951 		dbuf = ISC_LIST_TAIL(client->query.namebufs);
2952 		isc_buffer_availableregion(dbuf, &r);
2953 		INSIST(r.length >= 255);
2954 	}
2955 	CTRACE("ns_client_getnamebuf: done");
2956 	return (dbuf);
2957 }
2958 
2959 void
2960 ns_client_keepname(ns_client_t *client, dns_name_t *name, isc_buffer_t *dbuf) {
2961 	isc_region_t r;
2962 
2963 	CTRACE("ns_client_keepname");
2964 
2965 	/*%
2966 	 * 'name' is using space in 'dbuf', but 'dbuf' has not yet been
2967 	 * adjusted to take account of that.  We do the adjustment.
2968 	 */
2969 	REQUIRE((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) != 0);
2970 
2971 	dns_name_toregion(name, &r);
2972 	isc_buffer_add(dbuf, r.length);
2973 	dns_name_setbuffer(name, NULL);
2974 	client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
2975 }
2976 
2977 void
2978 ns_client_releasename(ns_client_t *client, dns_name_t **namep) {
2979 	dns_name_t *name = *namep;
2980 
2981 	/*%
2982 	 * 'name' is no longer needed.  Return it to our pool of temporary
2983 	 * names.  If it is using a name buffer, relinquish its exclusive
2984 	 * rights on the buffer.
2985 	 */
2986 
2987 	CTRACE("ns_client_releasename");
2988 	if (dns_name_hasbuffer(name)) {
2989 		INSIST((client->query.attributes & NS_QUERYATTR_NAMEBUFUSED) !=
2990 		       0);
2991 		client->query.attributes &= ~NS_QUERYATTR_NAMEBUFUSED;
2992 	}
2993 	dns_message_puttempname(client->message, namep);
2994 	CTRACE("ns_client_releasename: done");
2995 }
2996 
2997 isc_result_t
2998 ns_client_newdbversion(ns_client_t *client, unsigned int n) {
2999 	unsigned int i;
3000 	ns_dbversion_t *dbversion;
3001 
3002 	for (i = 0; i < n; i++) {
3003 		dbversion = isc_mem_get(client->mctx, sizeof(*dbversion));
3004 		{
3005 			dbversion->db = NULL;
3006 			dbversion->version = NULL;
3007 			ISC_LIST_INITANDAPPEND(client->query.freeversions,
3008 					       dbversion, link);
3009 		}
3010 	}
3011 
3012 	return (ISC_R_SUCCESS);
3013 }
3014 
3015 static inline ns_dbversion_t *
3016 client_getdbversion(ns_client_t *client) {
3017 	isc_result_t result;
3018 	ns_dbversion_t *dbversion;
3019 
3020 	if (ISC_LIST_EMPTY(client->query.freeversions)) {
3021 		result = ns_client_newdbversion(client, 1);
3022 		if (result != ISC_R_SUCCESS) {
3023 			return (NULL);
3024 		}
3025 	}
3026 	dbversion = ISC_LIST_HEAD(client->query.freeversions);
3027 	INSIST(dbversion != NULL);
3028 	ISC_LIST_UNLINK(client->query.freeversions, dbversion, link);
3029 
3030 	return (dbversion);
3031 }
3032 
3033 ns_dbversion_t *
3034 ns_client_findversion(ns_client_t *client, dns_db_t *db) {
3035 	ns_dbversion_t *dbversion;
3036 
3037 	for (dbversion = ISC_LIST_HEAD(client->query.activeversions);
3038 	     dbversion != NULL; dbversion = ISC_LIST_NEXT(dbversion, link))
3039 	{
3040 		if (dbversion->db == db) {
3041 			break;
3042 		}
3043 	}
3044 
3045 	if (dbversion == NULL) {
3046 		/*
3047 		 * This is a new zone for this query.  Add it to
3048 		 * the active list.
3049 		 */
3050 		dbversion = client_getdbversion(client);
3051 		if (dbversion == NULL) {
3052 			return (NULL);
3053 		}
3054 		dns_db_attach(db, &dbversion->db);
3055 		dns_db_currentversion(db, &dbversion->version);
3056 		dbversion->acl_checked = false;
3057 		dbversion->queryok = false;
3058 		ISC_LIST_APPEND(client->query.activeversions, dbversion, link);
3059 	}
3060 
3061 	return (dbversion);
3062 }
3063