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