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