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