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