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