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