client.c revision 267654
1/* 2 * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id$ */ 19 20#include <config.h> 21 22#include <isc/formatcheck.h> 23#include <isc/mutex.h> 24#include <isc/once.h> 25#include <isc/platform.h> 26#include <isc/print.h> 27#include <isc/queue.h> 28#include <isc/stats.h> 29#include <isc/stdio.h> 30#include <isc/string.h> 31#include <isc/task.h> 32#include <isc/timer.h> 33#include <isc/util.h> 34 35#include <dns/db.h> 36#include <dns/dispatch.h> 37#include <dns/events.h> 38#include <dns/message.h> 39#include <dns/peer.h> 40#include <dns/rcode.h> 41#include <dns/rdata.h> 42#include <dns/rdataclass.h> 43#include <dns/rdatalist.h> 44#include <dns/rdataset.h> 45#include <dns/resolver.h> 46#include <dns/stats.h> 47#include <dns/tsig.h> 48#include <dns/view.h> 49#include <dns/zone.h> 50 51#include <named/interfacemgr.h> 52#include <named/log.h> 53#include <named/notify.h> 54#include <named/os.h> 55#include <named/server.h> 56#include <named/update.h> 57 58/*** 59 *** Client 60 ***/ 61 62/*! \file 63 * Client Routines 64 * 65 * Important note! 66 * 67 * All client state changes, other than that from idle to listening, occur 68 * as a result of events. This guarantees serialization and avoids the 69 * need for locking. 70 * 71 * If a routine is ever created that allows someone other than the client's 72 * task to change the client, then the client will have to be locked. 73 */ 74 75#define NS_CLIENT_TRACE 76#ifdef NS_CLIENT_TRACE 77#define CTRACE(m) ns_client_log(client, \ 78 NS_LOGCATEGORY_CLIENT, \ 79 NS_LOGMODULE_CLIENT, \ 80 ISC_LOG_DEBUG(3), \ 81 "%s", (m)) 82#define MTRACE(m) isc_log_write(ns_g_lctx, \ 83 NS_LOGCATEGORY_GENERAL, \ 84 NS_LOGMODULE_CLIENT, \ 85 ISC_LOG_DEBUG(3), \ 86 "clientmgr @%p: %s", manager, (m)) 87#else 88#define CTRACE(m) ((void)(m)) 89#define MTRACE(m) ((void)(m)) 90#endif 91 92#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) 93 94#define TCP_BUFFER_SIZE (65535 + 2) 95#define SEND_BUFFER_SIZE 4096 96#define RECV_BUFFER_SIZE 4096 97 98#ifdef ISC_PLATFORM_USETHREADS 99#define NMCTXS 100 100/*%< 101 * Number of 'mctx pools' for clients. (Should this be configurable?) 102 * When enabling threads, we use a pool of memory contexts shared by 103 * client objects, since concurrent access to a shared context would cause 104 * heavy contentions. The above constant is expected to be enough for 105 * completely avoiding contentions among threads for an authoritative-only 106 * server. 107 */ 108#else 109#define NMCTXS 0 110/*%< 111 * If named with built without thread, simply share manager's context. Using 112 * a separate context in this case would simply waste memory. 113 */ 114#endif 115 116/*% nameserver client manager structure */ 117struct ns_clientmgr { 118 /* Unlocked. */ 119 unsigned int magic; 120 121 /* The queue object has its own locks */ 122 client_queue_t inactive; /*%< To be recycled */ 123 124 isc_mem_t * mctx; 125 isc_taskmgr_t * taskmgr; 126 isc_timermgr_t * timermgr; 127 128 /* Lock covers manager state. */ 129 isc_mutex_t lock; 130 isc_boolean_t exiting; 131 132 /* Lock covers the clients list */ 133 isc_mutex_t listlock; 134 client_list_t clients; /*%< All active clients */ 135 136 /* Lock covers the recursing list */ 137 isc_mutex_t reclock; 138 client_list_t recursing; /*%< Recursing clients */ 139 140#if NMCTXS > 0 141 /*%< mctx pool for clients. */ 142 unsigned int nextmctx; 143 isc_mem_t * mctxpool[NMCTXS]; 144#endif 145}; 146 147#define MANAGER_MAGIC ISC_MAGIC('N', 'S', 'C', 'm') 148#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, MANAGER_MAGIC) 149 150/*! 151 * Client object states. Ordering is significant: higher-numbered 152 * states are generally "more active", meaning that the client can 153 * have more dynamically allocated data, outstanding events, etc. 154 * In the list below, any such properties listed for state N 155 * also apply to any state > N. 156 * 157 * To force the client into a less active state, set client->newstate 158 * to that state and call exit_check(). This will cause any 159 * activities defined for higher-numbered states to be aborted. 160 */ 161 162#define NS_CLIENTSTATE_FREED 0 163/*%< 164 * The client object no longer exists. 165 */ 166 167#define NS_CLIENTSTATE_INACTIVE 1 168/*%< 169 * The client object exists and has a task and timer. 170 * Its "query" struct and sendbuf are initialized. 171 * It is on the client manager's list of inactive clients. 172 * It has a message and OPT, both in the reset state. 173 */ 174 175#define NS_CLIENTSTATE_READY 2 176/*%< 177 * The client object is either a TCP or a UDP one, and 178 * it is associated with a network interface. It is on the 179 * client manager's list of active clients. 180 * 181 * If it is a TCP client object, it has a TCP listener socket 182 * and an outstanding TCP listen request. 183 * 184 * If it is a UDP client object, it has a UDP listener socket 185 * and an outstanding UDP receive request. 186 */ 187 188#define NS_CLIENTSTATE_READING 3 189/*%< 190 * The client object is a TCP client object that has received 191 * a connection. It has a tcpsocket, tcpmsg, TCP quota, and an 192 * outstanding TCP read request. This state is not used for 193 * UDP client objects. 194 */ 195 196#define NS_CLIENTSTATE_WORKING 4 197/*%< 198 * The client object has received a request and is working 199 * on it. It has a view, and it may have any of a non-reset OPT, 200 * recursion quota, and an outstanding write request. 201 */ 202 203#define NS_CLIENTSTATE_RECURSING 5 204/*%< 205 * The client object is recursing. It will be on the 'recursing' 206 * list. 207 */ 208 209#define NS_CLIENTSTATE_MAX 9 210/*%< 211 * Sentinel value used to indicate "no state". When client->newstate 212 * has this value, we are not attempting to exit the current state. 213 * Must be greater than any valid state. 214 */ 215 216/* 217 * Enable ns_client_dropport() by default. 218 */ 219#ifndef NS_CLIENT_DROPPORT 220#define NS_CLIENT_DROPPORT 1 221#endif 222 223unsigned int ns_client_requests; 224 225static void client_read(ns_client_t *client); 226static void client_accept(ns_client_t *client); 227static void client_udprecv(ns_client_t *client); 228static void clientmgr_destroy(ns_clientmgr_t *manager); 229static isc_boolean_t exit_check(ns_client_t *client); 230static void ns_client_endrequest(ns_client_t *client); 231static void client_start(isc_task_t *task, isc_event_t *event); 232static void client_request(isc_task_t *task, isc_event_t *event); 233static void ns_client_dumpmessage(ns_client_t *client, const char *reason); 234static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, 235 dns_dispatch_t *disp, isc_boolean_t tcp); 236 237void 238ns_client_recursing(ns_client_t *client) { 239 REQUIRE(NS_CLIENT_VALID(client)); 240 REQUIRE(client->state == NS_CLIENTSTATE_WORKING); 241 242 LOCK(&client->manager->reclock); 243 client->newstate = client->state = NS_CLIENTSTATE_RECURSING; 244 ISC_LIST_APPEND(client->manager->recursing, client, rlink); 245 UNLOCK(&client->manager->reclock); 246} 247 248void 249ns_client_killoldestquery(ns_client_t *client) { 250 ns_client_t *oldest; 251 REQUIRE(NS_CLIENT_VALID(client)); 252 253 LOCK(&client->manager->reclock); 254 oldest = ISC_LIST_HEAD(client->manager->recursing); 255 if (oldest != NULL) { 256 ISC_LIST_UNLINK(client->manager->recursing, oldest, rlink); 257 UNLOCK(&client->manager->reclock); 258 ns_query_cancel(oldest); 259 } else 260 UNLOCK(&client->manager->reclock); 261} 262 263void 264ns_client_settimeout(ns_client_t *client, unsigned int seconds) { 265 isc_result_t result; 266 isc_interval_t interval; 267 268 isc_interval_set(&interval, seconds, 0); 269 result = isc_timer_reset(client->timer, isc_timertype_once, NULL, 270 &interval, ISC_FALSE); 271 client->timerset = ISC_TRUE; 272 if (result != ISC_R_SUCCESS) { 273 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 274 NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, 275 "setting timeout: %s", 276 isc_result_totext(result)); 277 /* Continue anyway. */ 278 } 279} 280 281/*% 282 * Check for a deactivation or shutdown request and take appropriate 283 * action. Returns ISC_TRUE if either is in progress; in this case 284 * the caller must no longer use the client object as it may have been 285 * freed. 286 */ 287static isc_boolean_t 288exit_check(ns_client_t *client) { 289 isc_boolean_t destroy_manager = ISC_FALSE; 290 ns_clientmgr_t *manager = NULL; 291 292 REQUIRE(NS_CLIENT_VALID(client)); 293 manager = client->manager; 294 295 if (client->state <= client->newstate) 296 return (ISC_FALSE); /* Business as usual. */ 297 298 INSIST(client->newstate < NS_CLIENTSTATE_RECURSING); 299 300 /* 301 * We need to detach from the view early when shutting down 302 * the server to break the following vicious circle: 303 * 304 * - The resolver will not shut down until the view refcount is zero 305 * - The view refcount does not go to zero until all clients detach 306 * - The client does not detach from the view until references is zero 307 * - references does not go to zero until the resolver has shut down 308 * 309 * Keep the view attached until any outstanding updates complete. 310 */ 311 if (client->nupdates == 0 && 312 client->newstate == NS_CLIENTSTATE_FREED && client->view != NULL) 313 dns_view_detach(&client->view); 314 315 if (client->state == NS_CLIENTSTATE_WORKING || 316 client->state == NS_CLIENTSTATE_RECURSING) 317 { 318 INSIST(client->newstate <= NS_CLIENTSTATE_READING); 319 /* 320 * Let the update processing complete. 321 */ 322 if (client->nupdates > 0) 323 return (ISC_TRUE); 324 325 /* 326 * We are trying to abort request processing. 327 */ 328 if (client->nsends > 0) { 329 isc_socket_t *socket; 330 if (TCP_CLIENT(client)) 331 socket = client->tcpsocket; 332 else 333 socket = client->udpsocket; 334 isc_socket_cancel(socket, client->task, 335 ISC_SOCKCANCEL_SEND); 336 } 337 338 if (! (client->nsends == 0 && client->nrecvs == 0 && 339 client->references == 0)) 340 { 341 /* 342 * Still waiting for I/O cancel completion. 343 * or lingering references. 344 */ 345 return (ISC_TRUE); 346 } 347 348 /* 349 * I/O cancel is complete. Burn down all state 350 * related to the current request. Ensure that 351 * the client is no longer on the recursing list. 352 * 353 * We need to check whether the client is still linked, 354 * because it may already have been removed from the 355 * recursing list by ns_client_killoldestquery() 356 */ 357 if (client->state == NS_CLIENTSTATE_RECURSING) { 358 LOCK(&manager->reclock); 359 if (ISC_LINK_LINKED(client, rlink)) 360 ISC_LIST_UNLINK(manager->recursing, 361 client, rlink); 362 UNLOCK(&manager->reclock); 363 } 364 ns_client_endrequest(client); 365 366 client->state = NS_CLIENTSTATE_READING; 367 INSIST(client->recursionquota == NULL); 368 369 if (NS_CLIENTSTATE_READING == client->newstate) { 370 client_read(client); 371 client->newstate = NS_CLIENTSTATE_MAX; 372 return (ISC_TRUE); /* We're done. */ 373 } 374 } 375 376 if (client->state == NS_CLIENTSTATE_READING) { 377 /* 378 * We are trying to abort the current TCP connection, 379 * if any. 380 */ 381 INSIST(client->recursionquota == NULL); 382 INSIST(client->newstate <= NS_CLIENTSTATE_READY); 383 if (client->nreads > 0) 384 dns_tcpmsg_cancelread(&client->tcpmsg); 385 if (! client->nreads == 0) { 386 /* Still waiting for read cancel completion. */ 387 return (ISC_TRUE); 388 } 389 390 if (client->tcpmsg_valid) { 391 dns_tcpmsg_invalidate(&client->tcpmsg); 392 client->tcpmsg_valid = ISC_FALSE; 393 } 394 if (client->tcpsocket != NULL) { 395 CTRACE("closetcp"); 396 isc_socket_detach(&client->tcpsocket); 397 } 398 399 if (client->tcpquota != NULL) 400 isc_quota_detach(&client->tcpquota); 401 402 if (client->timerset) { 403 (void)isc_timer_reset(client->timer, 404 isc_timertype_inactive, 405 NULL, NULL, ISC_TRUE); 406 client->timerset = ISC_FALSE; 407 } 408 409 client->peeraddr_valid = ISC_FALSE; 410 411 client->state = NS_CLIENTSTATE_READY; 412 INSIST(client->recursionquota == NULL); 413 414 /* 415 * Now the client is ready to accept a new TCP connection 416 * or UDP request, but we may have enough clients doing 417 * that already. Check whether this client needs to remain 418 * active and force it to go inactive if not. 419 * 420 * UDP clients go inactive at this point, but TCP clients 421 * may remain active if we have fewer active TCP client 422 * objects than desired due to an earlier quota exhaustion. 423 */ 424 if (client->mortal && TCP_CLIENT(client) && !ns_g_clienttest) { 425 LOCK(&client->interface->lock); 426 if (client->interface->ntcpcurrent < 427 client->interface->ntcptarget) 428 client->mortal = ISC_FALSE; 429 UNLOCK(&client->interface->lock); 430 } 431 432 /* 433 * We don't need the client; send it to the inactive 434 * queue for recycling. 435 */ 436 if (client->mortal) { 437 if (client->newstate > NS_CLIENTSTATE_INACTIVE) 438 client->newstate = NS_CLIENTSTATE_INACTIVE; 439 } 440 441 if (NS_CLIENTSTATE_READY == client->newstate) { 442 if (TCP_CLIENT(client)) { 443 client_accept(client); 444 } else 445 client_udprecv(client); 446 client->newstate = NS_CLIENTSTATE_MAX; 447 return (ISC_TRUE); 448 } 449 } 450 451 if (client->state == NS_CLIENTSTATE_READY) { 452 INSIST(client->newstate <= NS_CLIENTSTATE_INACTIVE); 453 454 /* 455 * We are trying to enter the inactive state. 456 */ 457 if (client->naccepts > 0) 458 isc_socket_cancel(client->tcplistener, client->task, 459 ISC_SOCKCANCEL_ACCEPT); 460 461 /* Still waiting for accept cancel completion. */ 462 if (! (client->naccepts == 0)) 463 return (ISC_TRUE); 464 465 /* Accept cancel is complete. */ 466 if (client->nrecvs > 0) 467 isc_socket_cancel(client->udpsocket, client->task, 468 ISC_SOCKCANCEL_RECV); 469 470 /* Still waiting for recv cancel completion. */ 471 if (! (client->nrecvs == 0)) 472 return (ISC_TRUE); 473 474 /* Still waiting for control event to be delivered */ 475 if (client->nctls > 0) 476 return (ISC_TRUE); 477 478 /* Deactivate the client. */ 479 if (client->interface) 480 ns_interface_detach(&client->interface); 481 482 INSIST(client->naccepts == 0); 483 INSIST(client->recursionquota == NULL); 484 if (client->tcplistener != NULL) 485 isc_socket_detach(&client->tcplistener); 486 487 if (client->udpsocket != NULL) 488 isc_socket_detach(&client->udpsocket); 489 490 if (client->dispatch != NULL) 491 dns_dispatch_detach(&client->dispatch); 492 493 client->attributes = 0; 494 client->mortal = ISC_FALSE; 495 496 /* 497 * Put the client on the inactive list. If we are aiming for 498 * the "freed" state, it will be removed from the inactive 499 * list shortly, and we need to keep the manager locked until 500 * that has been done, lest the manager decide to reactivate 501 * the dying client inbetween. 502 */ 503 client->state = NS_CLIENTSTATE_INACTIVE; 504 INSIST(client->recursionquota == NULL); 505 506 if (client->state == client->newstate) { 507 client->newstate = NS_CLIENTSTATE_MAX; 508 if (!ns_g_clienttest && manager != NULL && 509 !manager->exiting) 510 ISC_QUEUE_PUSH(manager->inactive, client, 511 ilink); 512 if (client->needshutdown) 513 isc_task_shutdown(client->task); 514 return (ISC_TRUE); 515 } 516 } 517 518 if (client->state == NS_CLIENTSTATE_INACTIVE) { 519 INSIST(client->newstate == NS_CLIENTSTATE_FREED); 520 /* 521 * We are trying to free the client. 522 * 523 * When "shuttingdown" is true, either the task has received 524 * its shutdown event or no shutdown event has ever been 525 * set up. Thus, we have no outstanding shutdown 526 * event at this point. 527 */ 528 REQUIRE(client->state == NS_CLIENTSTATE_INACTIVE); 529 530 INSIST(client->recursionquota == NULL); 531 INSIST(!ISC_QLINK_LINKED(client, ilink)); 532 533 ns_query_free(client); 534 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); 535 isc_event_free((isc_event_t **)&client->sendevent); 536 isc_event_free((isc_event_t **)&client->recvevent); 537 isc_timer_detach(&client->timer); 538 539 if (client->tcpbuf != NULL) 540 isc_mem_put(client->mctx, client->tcpbuf, 541 TCP_BUFFER_SIZE); 542 if (client->opt != NULL) { 543 INSIST(dns_rdataset_isassociated(client->opt)); 544 dns_rdataset_disassociate(client->opt); 545 dns_message_puttemprdataset(client->message, 546 &client->opt); 547 } 548 549 dns_message_destroy(&client->message); 550 if (manager != NULL) { 551 LOCK(&manager->listlock); 552 ISC_LIST_UNLINK(manager->clients, client, link); 553 LOCK(&manager->lock); 554 if (manager->exiting && 555 ISC_LIST_EMPTY(manager->clients)) 556 destroy_manager = ISC_TRUE; 557 UNLOCK(&manager->lock); 558 UNLOCK(&manager->listlock); 559 } 560 561 /* 562 * Detaching the task must be done after unlinking from 563 * the manager's lists because the manager accesses 564 * client->task. 565 */ 566 if (client->task != NULL) 567 isc_task_detach(&client->task); 568 569 CTRACE("free"); 570 client->magic = 0; 571 572 /* 573 * Check that there are no other external references to 574 * the memory context. 575 */ 576 if (ns_g_clienttest && isc_mem_references(client->mctx) != 1) { 577 isc_mem_stats(client->mctx, stderr); 578 INSIST(0); 579 } 580 isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); 581 } 582 583 if (destroy_manager && manager != NULL) 584 clientmgr_destroy(manager); 585 586 return (ISC_TRUE); 587} 588 589/*% 590 * The client's task has received the client's control event 591 * as part of the startup process. 592 */ 593static void 594client_start(isc_task_t *task, isc_event_t *event) { 595 ns_client_t *client = (ns_client_t *) event->ev_arg; 596 597 INSIST(task == client->task); 598 599 UNUSED(task); 600 601 INSIST(client->nctls == 1); 602 client->nctls--; 603 604 if (exit_check(client)) 605 return; 606 607 if (TCP_CLIENT(client)) { 608 client_accept(client); 609 } else { 610 client_udprecv(client); 611 } 612} 613 614 615/*% 616 * The client's task has received a shutdown event. 617 */ 618static void 619client_shutdown(isc_task_t *task, isc_event_t *event) { 620 ns_client_t *client; 621 622 REQUIRE(event != NULL); 623 REQUIRE(event->ev_type == ISC_TASKEVENT_SHUTDOWN); 624 client = event->ev_arg; 625 REQUIRE(NS_CLIENT_VALID(client)); 626 REQUIRE(task == client->task); 627 628 UNUSED(task); 629 630 CTRACE("shutdown"); 631 632 isc_event_free(&event); 633 634 if (client->shutdown != NULL) { 635 (client->shutdown)(client->shutdown_arg, ISC_R_SHUTTINGDOWN); 636 client->shutdown = NULL; 637 client->shutdown_arg = NULL; 638 } 639 640 if (ISC_QLINK_LINKED(client, ilink)) 641 ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink); 642 643 client->newstate = NS_CLIENTSTATE_FREED; 644 client->needshutdown = ISC_FALSE; 645 (void)exit_check(client); 646} 647 648static void 649ns_client_endrequest(ns_client_t *client) { 650 INSIST(client->naccepts == 0); 651 INSIST(client->nreads == 0); 652 INSIST(client->nsends == 0); 653 INSIST(client->nrecvs == 0); 654 INSIST(client->nupdates == 0); 655 INSIST(client->state == NS_CLIENTSTATE_WORKING || 656 client->state == NS_CLIENTSTATE_RECURSING); 657 658 CTRACE("endrequest"); 659 660 if (client->next != NULL) { 661 (client->next)(client); 662 client->next = NULL; 663 } 664 665 if (client->view != NULL) 666 dns_view_detach(&client->view); 667 if (client->opt != NULL) { 668 INSIST(dns_rdataset_isassociated(client->opt)); 669 dns_rdataset_disassociate(client->opt); 670 dns_message_puttemprdataset(client->message, &client->opt); 671 } 672 673 client->signer = NULL; 674 client->udpsize = 512; 675 client->extflags = 0; 676 client->ednsversion = -1; 677 dns_message_reset(client->message, DNS_MESSAGE_INTENTPARSE); 678 679 if (client->recursionquota != NULL) 680 isc_quota_detach(&client->recursionquota); 681 682 /* 683 * Clear all client attributes that are specific to 684 * the request; that's all except the TCP flag. 685 */ 686 client->attributes &= NS_CLIENTATTR_TCP; 687} 688 689void 690ns_client_next(ns_client_t *client, isc_result_t result) { 691 int newstate; 692 693 REQUIRE(NS_CLIENT_VALID(client)); 694 REQUIRE(client->state == NS_CLIENTSTATE_WORKING || 695 client->state == NS_CLIENTSTATE_RECURSING || 696 client->state == NS_CLIENTSTATE_READING); 697 698 CTRACE("next"); 699 700 if (result != ISC_R_SUCCESS) 701 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 702 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 703 "request failed: %s", isc_result_totext(result)); 704 705 /* 706 * An error processing a TCP request may have left 707 * the connection out of sync. To be safe, we always 708 * sever the connection when result != ISC_R_SUCCESS. 709 */ 710 if (result == ISC_R_SUCCESS && TCP_CLIENT(client)) 711 newstate = NS_CLIENTSTATE_READING; 712 else 713 newstate = NS_CLIENTSTATE_READY; 714 715 if (client->newstate > newstate) 716 client->newstate = newstate; 717 (void)exit_check(client); 718} 719 720 721static void 722client_senddone(isc_task_t *task, isc_event_t *event) { 723 ns_client_t *client; 724 isc_socketevent_t *sevent = (isc_socketevent_t *) event; 725 726 REQUIRE(sevent != NULL); 727 REQUIRE(sevent->ev_type == ISC_SOCKEVENT_SENDDONE); 728 client = sevent->ev_arg; 729 REQUIRE(NS_CLIENT_VALID(client)); 730 REQUIRE(task == client->task); 731 REQUIRE(sevent == client->sendevent); 732 733 UNUSED(task); 734 735 CTRACE("senddone"); 736 737 if (sevent->result != ISC_R_SUCCESS) 738 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 739 NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, 740 "error sending response: %s", 741 isc_result_totext(sevent->result)); 742 743 INSIST(client->nsends > 0); 744 client->nsends--; 745 746 if (client->tcpbuf != NULL) { 747 INSIST(TCP_CLIENT(client)); 748 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); 749 client->tcpbuf = NULL; 750 } 751 752 ns_client_next(client, ISC_R_SUCCESS); 753} 754 755/*% 756 * We only want to fail with ISC_R_NOSPACE when called from 757 * ns_client_sendraw() and not when called from ns_client_send(), 758 * tcpbuffer is NULL when called from ns_client_sendraw() and 759 * length != 0. tcpbuffer != NULL when called from ns_client_send() 760 * and length == 0. 761 */ 762 763static isc_result_t 764client_allocsendbuf(ns_client_t *client, isc_buffer_t *buffer, 765 isc_buffer_t *tcpbuffer, isc_uint32_t length, 766 unsigned char *sendbuf, unsigned char **datap) 767{ 768 unsigned char *data; 769 isc_uint32_t bufsize; 770 isc_result_t result; 771 772 INSIST(datap != NULL); 773 INSIST((tcpbuffer == NULL && length != 0) || 774 (tcpbuffer != NULL && length == 0)); 775 776 if (TCP_CLIENT(client)) { 777 INSIST(client->tcpbuf == NULL); 778 if (length + 2 > TCP_BUFFER_SIZE) { 779 result = ISC_R_NOSPACE; 780 goto done; 781 } 782 client->tcpbuf = isc_mem_get(client->mctx, TCP_BUFFER_SIZE); 783 if (client->tcpbuf == NULL) { 784 result = ISC_R_NOMEMORY; 785 goto done; 786 } 787 data = client->tcpbuf; 788 if (tcpbuffer != NULL) { 789 isc_buffer_init(tcpbuffer, data, TCP_BUFFER_SIZE); 790 isc_buffer_init(buffer, data + 2, TCP_BUFFER_SIZE - 2); 791 } else { 792 isc_buffer_init(buffer, data, TCP_BUFFER_SIZE); 793 INSIST(length <= 0xffff); 794 isc_buffer_putuint16(buffer, (isc_uint16_t)length); 795 } 796 } else { 797 data = sendbuf; 798 if (client->udpsize < SEND_BUFFER_SIZE) 799 bufsize = client->udpsize; 800 else 801 bufsize = SEND_BUFFER_SIZE; 802 if (length > bufsize) { 803 result = ISC_R_NOSPACE; 804 goto done; 805 } 806 isc_buffer_init(buffer, data, bufsize); 807 } 808 *datap = data; 809 result = ISC_R_SUCCESS; 810 811 done: 812 return (result); 813} 814 815static isc_result_t 816client_sendpkg(ns_client_t *client, isc_buffer_t *buffer) { 817 struct in6_pktinfo *pktinfo; 818 isc_result_t result; 819 isc_region_t r; 820 isc_sockaddr_t *address; 821 isc_socket_t *socket; 822 isc_netaddr_t netaddr; 823 int match; 824 unsigned int sockflags = ISC_SOCKFLAG_IMMEDIATE; 825 826 if (TCP_CLIENT(client)) { 827 socket = client->tcpsocket; 828 address = NULL; 829 } else { 830 socket = client->udpsocket; 831 address = &client->peeraddr; 832 833 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 834 if (ns_g_server->blackholeacl != NULL && 835 dns_acl_match(&netaddr, NULL, 836 ns_g_server->blackholeacl, 837 &ns_g_server->aclenv, 838 &match, NULL) == ISC_R_SUCCESS && 839 match > 0) 840 return (DNS_R_BLACKHOLED); 841 sockflags |= ISC_SOCKFLAG_NORETRY; 842 } 843 844 if ((client->attributes & NS_CLIENTATTR_PKTINFO) != 0 && 845 (client->attributes & NS_CLIENTATTR_MULTICAST) == 0) 846 pktinfo = &client->pktinfo; 847 else 848 pktinfo = NULL; 849 850 isc_buffer_usedregion(buffer, &r); 851 852 CTRACE("sendto"); 853 854 result = isc_socket_sendto2(socket, &r, client->task, 855 address, pktinfo, 856 client->sendevent, sockflags); 857 if (result == ISC_R_SUCCESS || result == ISC_R_INPROGRESS) { 858 client->nsends++; 859 if (result == ISC_R_SUCCESS) 860 client_senddone(client->task, 861 (isc_event_t *)client->sendevent); 862 result = ISC_R_SUCCESS; 863 } 864 return (result); 865} 866 867void 868ns_client_sendraw(ns_client_t *client, dns_message_t *message) { 869 isc_result_t result; 870 unsigned char *data; 871 isc_buffer_t buffer; 872 isc_region_t r; 873 isc_region_t *mr; 874 unsigned char sendbuf[SEND_BUFFER_SIZE]; 875 876 REQUIRE(NS_CLIENT_VALID(client)); 877 878 CTRACE("sendraw"); 879 880 mr = dns_message_getrawmessage(message); 881 if (mr == NULL) { 882 result = ISC_R_UNEXPECTEDEND; 883 goto done; 884 } 885 886 result = client_allocsendbuf(client, &buffer, NULL, mr->length, 887 sendbuf, &data); 888 if (result != ISC_R_SUCCESS) 889 goto done; 890 891 /* 892 * Copy message to buffer and fixup id. 893 */ 894 isc_buffer_availableregion(&buffer, &r); 895 result = isc_buffer_copyregion(&buffer, mr); 896 if (result != ISC_R_SUCCESS) 897 goto done; 898 r.base[0] = (client->message->id >> 8) & 0xff; 899 r.base[1] = client->message->id & 0xff; 900 901 result = client_sendpkg(client, &buffer); 902 if (result == ISC_R_SUCCESS) 903 return; 904 905 done: 906 if (client->tcpbuf != NULL) { 907 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); 908 client->tcpbuf = NULL; 909 } 910 ns_client_next(client, result); 911} 912 913void 914ns_client_send(ns_client_t *client) { 915 isc_result_t result; 916 unsigned char *data; 917 isc_buffer_t buffer; 918 isc_buffer_t tcpbuffer; 919 isc_region_t r; 920 dns_compress_t cctx; 921 isc_boolean_t cleanup_cctx = ISC_FALSE; 922 unsigned char sendbuf[SEND_BUFFER_SIZE]; 923 unsigned int render_opts; 924 unsigned int preferred_glue; 925 isc_boolean_t opt_included = ISC_FALSE; 926 927 REQUIRE(NS_CLIENT_VALID(client)); 928 929 CTRACE("send"); 930 931 if ((client->attributes & NS_CLIENTATTR_RA) != 0) 932 client->message->flags |= DNS_MESSAGEFLAG_RA; 933 934 if ((client->attributes & NS_CLIENTATTR_WANTDNSSEC) != 0) 935 render_opts = 0; 936 else 937 render_opts = DNS_MESSAGERENDER_OMITDNSSEC; 938 939 preferred_glue = 0; 940 if (client->view != NULL) { 941 if (client->view->preferred_glue == dns_rdatatype_a) 942 preferred_glue = DNS_MESSAGERENDER_PREFER_A; 943 else if (client->view->preferred_glue == dns_rdatatype_aaaa) 944 preferred_glue = DNS_MESSAGERENDER_PREFER_AAAA; 945 } 946 947#ifdef ALLOW_FILTER_AAAA_ON_V4 948 /* 949 * filter-aaaa-on-v4 yes or break-dnssec option to suppress 950 * AAAA records 951 * We already know that request came via IPv4, 952 * that we have both AAAA and A records, 953 * and that we either have no signatures that the client wants 954 * or we are supposed to break DNSSEC. 955 * 956 * Override preferred glue if necessary. 957 */ 958 if ((client->attributes & NS_CLIENTATTR_FILTER_AAAA) != 0) { 959 render_opts |= DNS_MESSAGERENDER_FILTER_AAAA; 960 if (preferred_glue == DNS_MESSAGERENDER_PREFER_AAAA) 961 preferred_glue = DNS_MESSAGERENDER_PREFER_A; 962 } 963#endif 964 965 /* 966 * XXXRTH The following doesn't deal with TCP buffer resizing. 967 */ 968 result = client_allocsendbuf(client, &buffer, &tcpbuffer, 0, 969 sendbuf, &data); 970 if (result != ISC_R_SUCCESS) 971 goto done; 972 973 result = dns_compress_init(&cctx, -1, client->mctx); 974 if (result != ISC_R_SUCCESS) 975 goto done; 976 dns_compress_setsensitive(&cctx, ISC_TRUE); 977 cleanup_cctx = ISC_TRUE; 978 979 result = dns_message_renderbegin(client->message, &cctx, &buffer); 980 if (result != ISC_R_SUCCESS) 981 goto done; 982 983 if (client->opt != NULL) { 984 result = dns_message_setopt(client->message, client->opt); 985 opt_included = ISC_TRUE; 986 client->opt = NULL; 987 if (result != ISC_R_SUCCESS) 988 goto done; 989 } 990 result = dns_message_rendersection(client->message, 991 DNS_SECTION_QUESTION, 0); 992 if (result == ISC_R_NOSPACE) { 993 client->message->flags |= DNS_MESSAGEFLAG_TC; 994 goto renderend; 995 } 996 if (result != ISC_R_SUCCESS) 997 goto done; 998#ifdef USE_RRL 999 /* 1000 * Stop after the question if TC was set for rate limiting. 1001 */ 1002 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) 1003 goto renderend; 1004#endif /* USE_RRL */ 1005 result = dns_message_rendersection(client->message, 1006 DNS_SECTION_ANSWER, 1007 DNS_MESSAGERENDER_PARTIAL | 1008 render_opts); 1009 if (result == ISC_R_NOSPACE) { 1010 client->message->flags |= DNS_MESSAGEFLAG_TC; 1011 goto renderend; 1012 } 1013 if (result != ISC_R_SUCCESS) 1014 goto done; 1015 result = dns_message_rendersection(client->message, 1016 DNS_SECTION_AUTHORITY, 1017 DNS_MESSAGERENDER_PARTIAL | 1018 render_opts); 1019 if (result == ISC_R_NOSPACE) { 1020 client->message->flags |= DNS_MESSAGEFLAG_TC; 1021 goto renderend; 1022 } 1023 if (result != ISC_R_SUCCESS) 1024 goto done; 1025 result = dns_message_rendersection(client->message, 1026 DNS_SECTION_ADDITIONAL, 1027 preferred_glue | render_opts); 1028 if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE) 1029 goto done; 1030 renderend: 1031 result = dns_message_renderend(client->message); 1032 1033 if (result != ISC_R_SUCCESS) 1034 goto done; 1035 1036 if (cleanup_cctx) { 1037 dns_compress_invalidate(&cctx); 1038 cleanup_cctx = ISC_FALSE; 1039 } 1040 1041 if (TCP_CLIENT(client)) { 1042 isc_buffer_usedregion(&buffer, &r); 1043 isc_buffer_putuint16(&tcpbuffer, (isc_uint16_t) r.length); 1044 isc_buffer_add(&tcpbuffer, r.length); 1045 result = client_sendpkg(client, &tcpbuffer); 1046 } else 1047 result = client_sendpkg(client, &buffer); 1048 1049 /* update statistics (XXXJT: is it okay to access message->xxxkey?) */ 1050 isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_response); 1051 if (opt_included) { 1052 isc_stats_increment(ns_g_server->nsstats, 1053 dns_nsstatscounter_edns0out); 1054 } 1055 if (client->message->tsigkey != NULL) { 1056 isc_stats_increment(ns_g_server->nsstats, 1057 dns_nsstatscounter_tsigout); 1058 } 1059 if (client->message->sig0key != NULL) { 1060 isc_stats_increment(ns_g_server->nsstats, 1061 dns_nsstatscounter_sig0out); 1062 } 1063 if ((client->message->flags & DNS_MESSAGEFLAG_TC) != 0) 1064 isc_stats_increment(ns_g_server->nsstats, 1065 dns_nsstatscounter_truncatedresp); 1066 1067 if (result == ISC_R_SUCCESS) 1068 return; 1069 1070 done: 1071 if (client->tcpbuf != NULL) { 1072 isc_mem_put(client->mctx, client->tcpbuf, TCP_BUFFER_SIZE); 1073 client->tcpbuf = NULL; 1074 } 1075 1076 if (cleanup_cctx) 1077 dns_compress_invalidate(&cctx); 1078 1079 ns_client_next(client, result); 1080} 1081 1082#if NS_CLIENT_DROPPORT 1083#define DROPPORT_NO 0 1084#define DROPPORT_REQUEST 1 1085#define DROPPORT_RESPONSE 2 1086/*% 1087 * ns_client_dropport determines if certain requests / responses 1088 * should be dropped based on the port number. 1089 * 1090 * Returns: 1091 * \li 0: Don't drop. 1092 * \li 1: Drop request. 1093 * \li 2: Drop (error) response. 1094 */ 1095static int 1096ns_client_dropport(in_port_t port) { 1097 switch (port) { 1098 case 7: /* echo */ 1099 case 13: /* daytime */ 1100 case 19: /* chargen */ 1101 case 37: /* time */ 1102 return (DROPPORT_REQUEST); 1103 case 464: /* kpasswd */ 1104 return (DROPPORT_RESPONSE); 1105 } 1106 return (DROPPORT_NO); 1107} 1108#endif 1109 1110void 1111ns_client_error(ns_client_t *client, isc_result_t result) { 1112 dns_rcode_t rcode; 1113 dns_message_t *message; 1114 1115 REQUIRE(NS_CLIENT_VALID(client)); 1116 1117 CTRACE("error"); 1118 1119 message = client->message; 1120 rcode = dns_result_torcode(result); 1121 1122#if NS_CLIENT_DROPPORT 1123 /* 1124 * Don't send FORMERR to ports on the drop port list. 1125 */ 1126 if (rcode == dns_rcode_formerr && 1127 ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) != 1128 DROPPORT_NO) { 1129 char buf[64]; 1130 isc_buffer_t b; 1131 1132 isc_buffer_init(&b, buf, sizeof(buf) - 1); 1133 if (dns_rcode_totext(rcode, &b) != ISC_R_SUCCESS) 1134 isc_buffer_putstr(&b, "UNKNOWN RCODE"); 1135 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1136 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 1137 "dropped error (%.*s) response: suspicious port", 1138 (int)isc_buffer_usedlength(&b), buf); 1139 ns_client_next(client, ISC_R_SUCCESS); 1140 return; 1141 } 1142#endif 1143 1144#ifdef USE_RRL 1145 /* 1146 * Try to rate limit error responses. 1147 */ 1148 if (client->view != NULL && client->view->rrl != NULL) { 1149 isc_boolean_t wouldlog; 1150 char log_buf[DNS_RRL_LOG_BUF_LEN]; 1151 dns_rrl_result_t rrl_result; 1152 1153 INSIST(rcode != dns_rcode_noerror && 1154 rcode != dns_rcode_nxdomain); 1155 wouldlog = isc_log_wouldlog(ns_g_lctx, DNS_RRL_LOG_DROP); 1156 rrl_result = dns_rrl(client->view, &client->peeraddr, 1157 TCP_CLIENT(client), 1158 dns_rdataclass_in, dns_rdatatype_none, 1159 NULL, result, client->now, 1160 wouldlog, log_buf, sizeof(log_buf)); 1161 if (rrl_result != DNS_RRL_RESULT_OK) { 1162 /* 1163 * Log dropped errors in the query category 1164 * so that they are not lost in silence. 1165 * Starts of rate-limited bursts are logged in 1166 * NS_LOGCATEGORY_RRL. 1167 */ 1168 if (wouldlog) { 1169 ns_client_log(client, 1170 NS_LOGCATEGORY_QUERY_EERRORS, 1171 NS_LOGMODULE_CLIENT, 1172 DNS_RRL_LOG_DROP, 1173 "%s", log_buf); 1174 } 1175 /* 1176 * Some error responses cannot be 'slipped', 1177 * so don't try to slip any error responses. 1178 */ 1179 if (!client->view->rrl->log_only) { 1180 isc_stats_increment(ns_g_server->nsstats, 1181 dns_nsstatscounter_ratedropped); 1182 isc_stats_increment(ns_g_server->nsstats, 1183 dns_nsstatscounter_dropped); 1184 ns_client_next(client, DNS_R_DROP); 1185 return; 1186 } 1187 } 1188 } 1189#endif /* USE_RRL */ 1190 1191 /* 1192 * Message may be an in-progress reply that we had trouble 1193 * with, in which case QR will be set. We need to clear QR before 1194 * calling dns_message_reply() to avoid triggering an assertion. 1195 */ 1196 message->flags &= ~DNS_MESSAGEFLAG_QR; 1197 /* 1198 * AA and AD shouldn't be set. 1199 */ 1200 message->flags &= ~(DNS_MESSAGEFLAG_AA | DNS_MESSAGEFLAG_AD); 1201 result = dns_message_reply(message, ISC_TRUE); 1202 if (result != ISC_R_SUCCESS) { 1203 /* 1204 * It could be that we've got a query with a good header, 1205 * but a bad question section, so we try again with 1206 * want_question_section set to ISC_FALSE. 1207 */ 1208 result = dns_message_reply(message, ISC_FALSE); 1209 if (result != ISC_R_SUCCESS) { 1210 ns_client_next(client, result); 1211 return; 1212 } 1213 } 1214 message->rcode = rcode; 1215 1216 /* 1217 * FORMERR loop avoidance: If we sent a FORMERR message 1218 * with the same ID to the same client less than two 1219 * seconds ago, assume that we are in an infinite error 1220 * packet dialog with a server for some protocol whose 1221 * error responses look enough like DNS queries to 1222 * elicit a FORMERR response. Drop a packet to break 1223 * the loop. 1224 */ 1225 if (rcode == dns_rcode_formerr) { 1226 if (isc_sockaddr_equal(&client->peeraddr, 1227 &client->formerrcache.addr) && 1228 message->id == client->formerrcache.id && 1229 client->requesttime - client->formerrcache.time < 2) { 1230 /* Drop packet. */ 1231 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1232 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), 1233 "possible error packet loop, " 1234 "FORMERR dropped"); 1235 ns_client_next(client, result); 1236 return; 1237 } 1238 client->formerrcache.addr = client->peeraddr; 1239 client->formerrcache.time = client->requesttime; 1240 client->formerrcache.id = message->id; 1241 } 1242 ns_client_send(client); 1243} 1244 1245static inline isc_result_t 1246client_addopt(ns_client_t *client) { 1247 char nsid[BUFSIZ], *nsidp; 1248 isc_result_t result; 1249 dns_view_t *view; 1250 dns_resolver_t *resolver; 1251 isc_uint16_t udpsize; 1252 dns_ednsopt_t ednsopts[2]; 1253 int count = 0; 1254 unsigned int flags; 1255 1256 REQUIRE(client->opt == NULL); /* XXXRTH free old. */ 1257 1258 view = client->view; 1259 resolver = (view != NULL) ? view->resolver : NULL; 1260 if (resolver != NULL) 1261 udpsize = dns_resolver_getudpsize(resolver); 1262 else 1263 udpsize = ns_g_udpsize; 1264 1265 flags = client->extflags & DNS_MESSAGEEXTFLAG_REPLYPRESERVE; 1266 1267 /* Set EDNS options if applicable */ 1268 if ((client->attributes & NS_CLIENTATTR_WANTNSID) != 0 && 1269 (ns_g_server->server_id != NULL || 1270 ns_g_server->server_usehostname)) { 1271 if (ns_g_server->server_usehostname) { 1272 isc_result_t result; 1273 result = ns_os_gethostname(nsid, sizeof(nsid)); 1274 if (result != ISC_R_SUCCESS) { 1275 goto no_nsid; 1276 } 1277 nsidp = nsid; 1278 } else 1279 nsidp = ns_g_server->server_id; 1280 1281 ednsopts[count].code = DNS_OPT_NSID; 1282 ednsopts[count].length = strlen(nsidp); 1283 ednsopts[count].value = (unsigned char *)nsidp; 1284 count++; 1285 } 1286 no_nsid: 1287 result = dns_message_buildopt(client->message, &client->opt, 0, 1288 udpsize, flags, ednsopts, count); 1289 return (result); 1290} 1291 1292static inline isc_boolean_t 1293allowed(isc_netaddr_t *addr, dns_name_t *signer, dns_acl_t *acl) { 1294 int match; 1295 isc_result_t result; 1296 1297 if (acl == NULL) 1298 return (ISC_TRUE); 1299 result = dns_acl_match(addr, signer, acl, &ns_g_server->aclenv, 1300 &match, NULL); 1301 if (result == ISC_R_SUCCESS && match > 0) 1302 return (ISC_TRUE); 1303 return (ISC_FALSE); 1304} 1305 1306/* 1307 * Callback to see if a non-recursive query coming from 'srcaddr' to 1308 * 'destaddr', with optional key 'mykey' for class 'rdclass' would be 1309 * delivered to 'myview'. 1310 * 1311 * We run this unlocked as both the view list and the interface list 1312 * are updated when the appropriate task has exclusivity. 1313 */ 1314isc_boolean_t 1315ns_client_isself(dns_view_t *myview, dns_tsigkey_t *mykey, 1316 isc_sockaddr_t *srcaddr, isc_sockaddr_t *dstaddr, 1317 dns_rdataclass_t rdclass, void *arg) 1318{ 1319 dns_view_t *view; 1320 dns_tsigkey_t *key = NULL; 1321 dns_name_t *tsig = NULL; 1322 isc_netaddr_t netsrc; 1323 isc_netaddr_t netdst; 1324 1325 UNUSED(arg); 1326 1327 /* 1328 * ns_g_server->interfacemgr is task exclusive locked. 1329 */ 1330 if (ns_g_server->interfacemgr == NULL) 1331 return (ISC_TRUE); 1332 1333 if (!ns_interfacemgr_listeningon(ns_g_server->interfacemgr, dstaddr)) 1334 return (ISC_FALSE); 1335 1336 isc_netaddr_fromsockaddr(&netsrc, srcaddr); 1337 isc_netaddr_fromsockaddr(&netdst, dstaddr); 1338 1339 for (view = ISC_LIST_HEAD(ns_g_server->viewlist); 1340 view != NULL; 1341 view = ISC_LIST_NEXT(view, link)) { 1342 1343 if (view->matchrecursiveonly) 1344 continue; 1345 1346 if (rdclass != view->rdclass) 1347 continue; 1348 1349 if (mykey != NULL) { 1350 isc_boolean_t match; 1351 isc_result_t result; 1352 1353 result = dns_view_gettsig(view, &mykey->name, &key); 1354 if (result != ISC_R_SUCCESS) 1355 continue; 1356 match = dst_key_compare(mykey->key, key->key); 1357 dns_tsigkey_detach(&key); 1358 if (!match) 1359 continue; 1360 tsig = dns_tsigkey_identity(mykey); 1361 } 1362 1363 if (allowed(&netsrc, tsig, view->matchclients) && 1364 allowed(&netdst, tsig, view->matchdestinations)) 1365 break; 1366 } 1367 return (ISC_TF(view == myview)); 1368} 1369 1370static isc_result_t 1371process_opt(ns_client_t *client, dns_rdataset_t *opt) { 1372 dns_rdata_t rdata; 1373 isc_buffer_t optbuf; 1374 isc_result_t result; 1375 isc_uint16_t optcode; 1376 isc_uint16_t optlen; 1377 1378 /* 1379 * Set the client's UDP buffer size. 1380 */ 1381 client->udpsize = opt->rdclass; 1382 1383 /* 1384 * If the requested UDP buffer size is less than 512, 1385 * ignore it and use 512. 1386 */ 1387 if (client->udpsize < 512) 1388 client->udpsize = 512; 1389 1390 /* 1391 * Get the flags out of the OPT record. 1392 */ 1393 client->extflags = (isc_uint16_t)(opt->ttl & 0xFFFF); 1394 1395 /* 1396 * Do we understand this version of EDNS? 1397 * 1398 * XXXRTH need library support for this! 1399 */ 1400 client->ednsversion = (opt->ttl & 0x00FF0000) >> 16; 1401 if (client->ednsversion > 0) { 1402 isc_stats_increment(ns_g_server->nsstats, 1403 dns_nsstatscounter_badednsver); 1404 result = client_addopt(client); 1405 if (result == ISC_R_SUCCESS) 1406 result = DNS_R_BADVERS; 1407 ns_client_error(client, result); 1408 goto cleanup; 1409 } 1410 1411 /* Check for NSID request */ 1412 result = dns_rdataset_first(opt); 1413 if (result == ISC_R_SUCCESS) { 1414 dns_rdata_init(&rdata); 1415 dns_rdataset_current(opt, &rdata); 1416 isc_buffer_init(&optbuf, rdata.data, rdata.length); 1417 isc_buffer_add(&optbuf, rdata.length); 1418 while (isc_buffer_remaininglength(&optbuf) >= 4) { 1419 optcode = isc_buffer_getuint16(&optbuf); 1420 optlen = isc_buffer_getuint16(&optbuf); 1421 switch (optcode) { 1422 case DNS_OPT_NSID: 1423 client->attributes |= NS_CLIENTATTR_WANTNSID; 1424 isc_buffer_forward(&optbuf, optlen); 1425 break; 1426 default: 1427 isc_buffer_forward(&optbuf, optlen); 1428 break; 1429 } 1430 } 1431 } 1432 1433 isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_edns0in); 1434 1435 /* 1436 * Create an OPT for our reply. 1437 */ 1438 result = client_addopt(client); 1439 if (result != ISC_R_SUCCESS) { 1440 ns_client_error(client, result); 1441 goto cleanup; 1442 } 1443 cleanup: 1444 return (result); 1445} 1446 1447/* 1448 * Handle an incoming request event from the socket (UDP case) 1449 * or tcpmsg (TCP case). 1450 */ 1451static void 1452client_request(isc_task_t *task, isc_event_t *event) { 1453 ns_client_t *client; 1454 isc_socketevent_t *sevent; 1455 isc_result_t result; 1456 isc_result_t sigresult = ISC_R_SUCCESS; 1457 isc_buffer_t *buffer; 1458 isc_buffer_t tbuffer; 1459 dns_view_t *view; 1460 dns_rdataset_t *opt; 1461 dns_name_t *signame; 1462 isc_boolean_t ra; /* Recursion available. */ 1463 isc_netaddr_t netaddr; 1464 int match; 1465 dns_messageid_t id; 1466 unsigned int flags; 1467 isc_boolean_t notimp; 1468 1469 REQUIRE(event != NULL); 1470 client = event->ev_arg; 1471 REQUIRE(NS_CLIENT_VALID(client)); 1472 REQUIRE(task == client->task); 1473 1474 INSIST(client->recursionquota == NULL); 1475 1476 INSIST(client->state == (TCP_CLIENT(client) ? 1477 NS_CLIENTSTATE_READING : 1478 NS_CLIENTSTATE_READY)); 1479 1480 ns_client_requests++; 1481 1482 if (event->ev_type == ISC_SOCKEVENT_RECVDONE) { 1483 INSIST(!TCP_CLIENT(client)); 1484 sevent = (isc_socketevent_t *)event; 1485 REQUIRE(sevent == client->recvevent); 1486 isc_buffer_init(&tbuffer, sevent->region.base, sevent->n); 1487 isc_buffer_add(&tbuffer, sevent->n); 1488 buffer = &tbuffer; 1489 result = sevent->result; 1490 if (result == ISC_R_SUCCESS) { 1491 client->peeraddr = sevent->address; 1492 client->peeraddr_valid = ISC_TRUE; 1493 } 1494 if ((sevent->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0) { 1495 client->attributes |= NS_CLIENTATTR_PKTINFO; 1496 client->pktinfo = sevent->pktinfo; 1497 } 1498 if ((sevent->attributes & ISC_SOCKEVENTATTR_MULTICAST) != 0) 1499 client->attributes |= NS_CLIENTATTR_MULTICAST; 1500 client->nrecvs--; 1501 } else { 1502 INSIST(TCP_CLIENT(client)); 1503 REQUIRE(event->ev_type == DNS_EVENT_TCPMSG); 1504 REQUIRE(event->ev_sender == &client->tcpmsg); 1505 buffer = &client->tcpmsg.buffer; 1506 result = client->tcpmsg.result; 1507 INSIST(client->nreads == 1); 1508 /* 1509 * client->peeraddr was set when the connection was accepted. 1510 */ 1511 client->nreads--; 1512 } 1513 1514 if (exit_check(client)) 1515 goto cleanup; 1516 client->state = client->newstate = NS_CLIENTSTATE_WORKING; 1517 1518 isc_task_getcurrenttime(task, &client->requesttime); 1519 client->now = client->requesttime; 1520 1521 if (result != ISC_R_SUCCESS) { 1522 if (TCP_CLIENT(client)) { 1523 ns_client_next(client, result); 1524 } else { 1525 if (result != ISC_R_CANCELED) 1526 isc_log_write(ns_g_lctx, NS_LOGCATEGORY_CLIENT, 1527 NS_LOGMODULE_CLIENT, 1528 ISC_LOG_ERROR, 1529 "UDP client handler shutting " 1530 "down due to fatal receive " 1531 "error: %s", 1532 isc_result_totext(result)); 1533 isc_task_shutdown(client->task); 1534 } 1535 goto cleanup; 1536 } 1537 1538 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 1539 1540#if NS_CLIENT_DROPPORT 1541 if (ns_client_dropport(isc_sockaddr_getport(&client->peeraddr)) == 1542 DROPPORT_REQUEST) { 1543 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1544 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 1545 "dropped request: suspicious port"); 1546 ns_client_next(client, ISC_R_SUCCESS); 1547 goto cleanup; 1548 } 1549#endif 1550 1551 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1552 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 1553 "%s request", 1554 TCP_CLIENT(client) ? "TCP" : "UDP"); 1555 1556 /* 1557 * Check the blackhole ACL for UDP only, since TCP is done in 1558 * client_newconn. 1559 */ 1560 if (!TCP_CLIENT(client)) { 1561 1562 if (ns_g_server->blackholeacl != NULL && 1563 dns_acl_match(&netaddr, NULL, ns_g_server->blackholeacl, 1564 &ns_g_server->aclenv, 1565 &match, NULL) == ISC_R_SUCCESS && 1566 match > 0) 1567 { 1568 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1569 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 1570 "blackholed UDP datagram"); 1571 ns_client_next(client, ISC_R_SUCCESS); 1572 goto cleanup; 1573 } 1574 } 1575 1576 /* 1577 * Silently drop multicast requests for the present. 1578 * XXXMPA revisit this as mDNS spec was published. 1579 */ 1580 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) { 1581 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1582 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(2), 1583 "dropping multicast request"); 1584 ns_client_next(client, DNS_R_REFUSED); 1585 goto cleanup; 1586 } 1587 1588 result = dns_message_peekheader(buffer, &id, &flags); 1589 if (result != ISC_R_SUCCESS) { 1590 /* 1591 * There isn't enough header to determine whether 1592 * this was a request or a response. Drop it. 1593 */ 1594 ns_client_next(client, result); 1595 goto cleanup; 1596 } 1597 1598 /* 1599 * The client object handles requests, not responses. 1600 * If this is a UDP response, forward it to the dispatcher. 1601 * If it's a TCP response, discard it here. 1602 */ 1603 if ((flags & DNS_MESSAGEFLAG_QR) != 0) { 1604 if (TCP_CLIENT(client)) { 1605 CTRACE("unexpected response"); 1606 ns_client_next(client, DNS_R_FORMERR); 1607 goto cleanup; 1608 } else { 1609 dns_dispatch_importrecv(client->dispatch, event); 1610 ns_client_next(client, ISC_R_SUCCESS); 1611 goto cleanup; 1612 } 1613 } 1614 1615 /* 1616 * Update some statistics counters. Don't count responses. 1617 */ 1618 if (isc_sockaddr_pf(&client->peeraddr) == PF_INET) { 1619 isc_stats_increment(ns_g_server->nsstats, 1620 dns_nsstatscounter_requestv4); 1621 } else { 1622 isc_stats_increment(ns_g_server->nsstats, 1623 dns_nsstatscounter_requestv6); 1624 } 1625 if (TCP_CLIENT(client)) 1626 isc_stats_increment(ns_g_server->nsstats, 1627 dns_nsstatscounter_tcp); 1628 1629 /* 1630 * It's a request. Parse it. 1631 */ 1632 result = dns_message_parse(client->message, buffer, 0); 1633 if (result != ISC_R_SUCCESS) { 1634 /* 1635 * Parsing the request failed. Send a response 1636 * (typically FORMERR or SERVFAIL). 1637 */ 1638 ns_client_error(client, result); 1639 goto cleanup; 1640 } 1641 1642 dns_opcodestats_increment(ns_g_server->opcodestats, 1643 client->message->opcode); 1644 switch (client->message->opcode) { 1645 case dns_opcode_query: 1646 case dns_opcode_update: 1647 case dns_opcode_notify: 1648 notimp = ISC_FALSE; 1649 break; 1650 case dns_opcode_iquery: 1651 default: 1652 notimp = ISC_TRUE; 1653 break; 1654 } 1655 1656 client->message->rcode = dns_rcode_noerror; 1657 1658 /* RFC1123 section 6.1.3.2 */ 1659 if ((client->attributes & NS_CLIENTATTR_MULTICAST) != 0) 1660 client->message->flags &= ~DNS_MESSAGEFLAG_RD; 1661 1662 /* 1663 * Deal with EDNS. 1664 */ 1665 opt = dns_message_getopt(client->message); 1666 if (opt != NULL) { 1667 result = process_opt(client, opt); 1668 if (result != ISC_R_SUCCESS) 1669 goto cleanup; 1670 } 1671 1672 if (client->message->rdclass == 0) { 1673 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1674 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), 1675 "message class could not be determined"); 1676 ns_client_dumpmessage(client, 1677 "message class could not be determined"); 1678 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR); 1679 goto cleanup; 1680 } 1681 1682 /* 1683 * Determine the destination address. If the receiving interface is 1684 * bound to a specific address, we simply use it regardless of the 1685 * address family. All IPv4 queries should fall into this case. 1686 * Otherwise, if this is a TCP query, get the address from the 1687 * receiving socket (this needs a system call and can be heavy). 1688 * For IPv6 UDP queries, we get this from the pktinfo structure (if 1689 * supported). 1690 * If all the attempts fail (this can happen due to memory shortage, 1691 * etc), we regard this as an error for safety. 1692 */ 1693 if ((client->interface->flags & NS_INTERFACEFLAG_ANYADDR) == 0) 1694 isc_netaddr_fromsockaddr(&client->destaddr, 1695 &client->interface->addr); 1696 else { 1697 isc_sockaddr_t sockaddr; 1698 result = ISC_R_FAILURE; 1699 1700 if (TCP_CLIENT(client)) 1701 result = isc_socket_getsockname(client->tcpsocket, 1702 &sockaddr); 1703 if (result == ISC_R_SUCCESS) 1704 isc_netaddr_fromsockaddr(&client->destaddr, &sockaddr); 1705 if (result != ISC_R_SUCCESS && 1706 client->interface->addr.type.sa.sa_family == AF_INET6 && 1707 (client->attributes & NS_CLIENTATTR_PKTINFO) != 0) { 1708 /* 1709 * XXXJT technically, we should convert the receiving 1710 * interface ID to a proper scope zone ID. However, 1711 * due to the fact there is no standard API for this, 1712 * we only handle link-local addresses and use the 1713 * interface index as link ID. Despite the assumption, 1714 * it should cover most typical cases. 1715 */ 1716 isc_netaddr_fromin6(&client->destaddr, 1717 &client->pktinfo.ipi6_addr); 1718 if (IN6_IS_ADDR_LINKLOCAL(&client->pktinfo.ipi6_addr)) 1719 isc_netaddr_setzone(&client->destaddr, 1720 client->pktinfo.ipi6_ifindex); 1721 result = ISC_R_SUCCESS; 1722 } 1723 if (result != ISC_R_SUCCESS) { 1724 UNEXPECTED_ERROR(__FILE__, __LINE__, 1725 "failed to get request's " 1726 "destination: %s", 1727 isc_result_totext(result)); 1728 ns_client_next(client, ISC_R_SUCCESS); 1729 goto cleanup; 1730 } 1731 } 1732 1733 /* 1734 * Find a view that matches the client's source address. 1735 */ 1736 for (view = ISC_LIST_HEAD(ns_g_server->viewlist); 1737 view != NULL; 1738 view = ISC_LIST_NEXT(view, link)) { 1739 if (client->message->rdclass == view->rdclass || 1740 client->message->rdclass == dns_rdataclass_any) 1741 { 1742 dns_name_t *tsig = NULL; 1743 1744 sigresult = dns_message_rechecksig(client->message, 1745 view); 1746 if (sigresult == ISC_R_SUCCESS) 1747 tsig = dns_tsigkey_identity(client->message->tsigkey); 1748 1749 if (allowed(&netaddr, tsig, view->matchclients) && 1750 allowed(&client->destaddr, tsig, 1751 view->matchdestinations) && 1752 !((client->message->flags & DNS_MESSAGEFLAG_RD) 1753 == 0 && view->matchrecursiveonly)) 1754 { 1755 dns_view_attach(view, &client->view); 1756 break; 1757 } 1758 } 1759 } 1760 1761 if (view == NULL) { 1762 char classname[DNS_RDATACLASS_FORMATSIZE]; 1763 1764 /* 1765 * Do a dummy TSIG verification attempt so that the 1766 * response will have a TSIG if the query did, as 1767 * required by RFC2845. 1768 */ 1769 isc_buffer_t b; 1770 isc_region_t *r; 1771 1772 dns_message_resetsig(client->message); 1773 1774 r = dns_message_getrawmessage(client->message); 1775 isc_buffer_init(&b, r->base, r->length); 1776 isc_buffer_add(&b, r->length); 1777 (void)dns_tsig_verify(&b, client->message, NULL, NULL); 1778 1779 dns_rdataclass_format(client->message->rdclass, classname, 1780 sizeof(classname)); 1781 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1782 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), 1783 "no matching view in class '%s'", classname); 1784 ns_client_dumpmessage(client, "no matching view in class"); 1785 ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED); 1786 goto cleanup; 1787 } 1788 1789 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 1790 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(5), 1791 "using view '%s'", view->name); 1792 1793 /* 1794 * Check for a signature. We log bad signatures regardless of 1795 * whether they ultimately cause the request to be rejected or 1796 * not. We do not log the lack of a signature unless we are 1797 * debugging. 1798 */ 1799 client->signer = NULL; 1800 dns_name_init(&client->signername, NULL); 1801 result = dns_message_signer(client->message, &client->signername); 1802 if (result != ISC_R_NOTFOUND) { 1803 signame = NULL; 1804 if (dns_message_gettsig(client->message, &signame) != NULL) { 1805 isc_stats_increment(ns_g_server->nsstats, 1806 dns_nsstatscounter_tsigin); 1807 } else { 1808 isc_stats_increment(ns_g_server->nsstats, 1809 dns_nsstatscounter_sig0in); 1810 } 1811 1812 } 1813 if (result == ISC_R_SUCCESS) { 1814 char namebuf[DNS_NAME_FORMATSIZE]; 1815 dns_name_format(&client->signername, namebuf, sizeof(namebuf)); 1816 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1817 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 1818 "request has valid signature: %s", namebuf); 1819 client->signer = &client->signername; 1820 } else if (result == ISC_R_NOTFOUND) { 1821 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1822 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 1823 "request is not signed"); 1824 } else if (result == DNS_R_NOIDENTITY) { 1825 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1826 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 1827 "request is signed by a nonauthoritative key"); 1828 } else { 1829 char tsigrcode[64]; 1830 isc_buffer_t b; 1831 dns_rcode_t status; 1832 isc_result_t tresult; 1833 1834 /* There is a signature, but it is bad. */ 1835 isc_stats_increment(ns_g_server->nsstats, 1836 dns_nsstatscounter_invalidsig); 1837 signame = NULL; 1838 if (dns_message_gettsig(client->message, &signame) != NULL) { 1839 char namebuf[DNS_NAME_FORMATSIZE]; 1840 char cnamebuf[DNS_NAME_FORMATSIZE]; 1841 dns_name_format(signame, namebuf, sizeof(namebuf)); 1842 status = client->message->tsigstatus; 1843 isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); 1844 tresult = dns_tsigrcode_totext(status, &b); 1845 INSIST(tresult == ISC_R_SUCCESS); 1846 tsigrcode[isc_buffer_usedlength(&b)] = '\0'; 1847 if (client->message->tsigkey->generated) { 1848 dns_name_format(client->message->tsigkey->creator, 1849 cnamebuf, sizeof(cnamebuf)); 1850 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1851 NS_LOGMODULE_CLIENT, 1852 ISC_LOG_ERROR, 1853 "request has invalid signature: " 1854 "TSIG %s (%s): %s (%s)", namebuf, 1855 cnamebuf, 1856 isc_result_totext(result), 1857 tsigrcode); 1858 } else { 1859 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1860 NS_LOGMODULE_CLIENT, 1861 ISC_LOG_ERROR, 1862 "request has invalid signature: " 1863 "TSIG %s: %s (%s)", namebuf, 1864 isc_result_totext(result), 1865 tsigrcode); 1866 } 1867 } else { 1868 status = client->message->sig0status; 1869 isc_buffer_init(&b, tsigrcode, sizeof(tsigrcode) - 1); 1870 tresult = dns_tsigrcode_totext(status, &b); 1871 INSIST(tresult == ISC_R_SUCCESS); 1872 tsigrcode[isc_buffer_usedlength(&b)] = '\0'; 1873 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 1874 NS_LOGMODULE_CLIENT, ISC_LOG_ERROR, 1875 "request has invalid signature: %s (%s)", 1876 isc_result_totext(result), tsigrcode); 1877 } 1878 /* 1879 * Accept update messages signed by unknown keys so that 1880 * update forwarding works transparently through slaves 1881 * that don't have all the same keys as the master. 1882 */ 1883 if (!(client->message->tsigstatus == dns_tsigerror_badkey && 1884 client->message->opcode == dns_opcode_update)) { 1885 ns_client_error(client, sigresult); 1886 goto cleanup; 1887 } 1888 } 1889 1890 /* 1891 * Decide whether recursive service is available to this client. 1892 * We do this here rather than in the query code so that we can 1893 * set the RA bit correctly on all kinds of responses, not just 1894 * responses to ordinary queries. Note if you can't query the 1895 * cache there is no point in setting RA. 1896 */ 1897 ra = ISC_FALSE; 1898 if (client->view->resolver != NULL && 1899 client->view->recursion == ISC_TRUE && 1900 ns_client_checkaclsilent(client, NULL, 1901 client->view->recursionacl, 1902 ISC_TRUE) == ISC_R_SUCCESS && 1903 ns_client_checkaclsilent(client, NULL, 1904 client->view->cacheacl, 1905 ISC_TRUE) == ISC_R_SUCCESS && 1906 ns_client_checkaclsilent(client, &client->destaddr, 1907 client->view->recursiononacl, 1908 ISC_TRUE) == ISC_R_SUCCESS && 1909 ns_client_checkaclsilent(client, &client->destaddr, 1910 client->view->cacheonacl, 1911 ISC_TRUE) == ISC_R_SUCCESS) 1912 ra = ISC_TRUE; 1913 1914 if (ra == ISC_TRUE) 1915 client->attributes |= NS_CLIENTATTR_RA; 1916 1917 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, NS_LOGMODULE_CLIENT, 1918 ISC_LOG_DEBUG(3), ra ? "recursion available" : 1919 "recursion not available"); 1920 1921 /* 1922 * Adjust maximum UDP response size for this client. 1923 */ 1924 if (client->udpsize > 512) { 1925 dns_peer_t *peer = NULL; 1926 isc_uint16_t udpsize = view->maxudp; 1927 (void) dns_peerlist_peerbyaddr(view->peers, &netaddr, &peer); 1928 if (peer != NULL) 1929 dns_peer_getmaxudp(peer, &udpsize); 1930 if (client->udpsize > udpsize) 1931 client->udpsize = udpsize; 1932 } 1933 1934 /* 1935 * Dispatch the request. 1936 */ 1937 switch (client->message->opcode) { 1938 case dns_opcode_query: 1939 CTRACE("query"); 1940 ns_query_start(client); 1941 break; 1942 case dns_opcode_update: 1943 CTRACE("update"); 1944 ns_client_settimeout(client, 60); 1945 ns_update_start(client, sigresult); 1946 break; 1947 case dns_opcode_notify: 1948 CTRACE("notify"); 1949 ns_client_settimeout(client, 60); 1950 ns_notify_start(client); 1951 break; 1952 case dns_opcode_iquery: 1953 CTRACE("iquery"); 1954 ns_client_error(client, DNS_R_NOTIMP); 1955 break; 1956 default: 1957 CTRACE("unknown opcode"); 1958 ns_client_error(client, DNS_R_NOTIMP); 1959 } 1960 1961 cleanup: 1962 return; 1963} 1964 1965static void 1966client_timeout(isc_task_t *task, isc_event_t *event) { 1967 ns_client_t *client; 1968 1969 REQUIRE(event != NULL); 1970 REQUIRE(event->ev_type == ISC_TIMEREVENT_LIFE || 1971 event->ev_type == ISC_TIMEREVENT_IDLE); 1972 client = event->ev_arg; 1973 REQUIRE(NS_CLIENT_VALID(client)); 1974 REQUIRE(task == client->task); 1975 REQUIRE(client->timer != NULL); 1976 1977 UNUSED(task); 1978 1979 CTRACE("timeout"); 1980 1981 isc_event_free(&event); 1982 1983 if (client->shutdown != NULL) { 1984 (client->shutdown)(client->shutdown_arg, ISC_R_TIMEDOUT); 1985 client->shutdown = NULL; 1986 client->shutdown_arg = NULL; 1987 } 1988 1989 if (client->newstate > NS_CLIENTSTATE_READY) 1990 client->newstate = NS_CLIENTSTATE_READY; 1991 (void)exit_check(client); 1992} 1993 1994static isc_result_t 1995get_clientmctx(ns_clientmgr_t *manager, isc_mem_t **mctxp) { 1996 isc_mem_t *clientmctx; 1997 isc_result_t result; 1998#if NMCTXS > 0 1999 unsigned int nextmctx; 2000#endif 2001 2002 MTRACE("clientmctx"); 2003 2004 /* 2005 * Caller must be holding the manager lock. 2006 */ 2007 if (ns_g_clienttest) { 2008 result = isc_mem_create(0, 0, mctxp); 2009 if (result == ISC_R_SUCCESS) 2010 isc_mem_setname(*mctxp, "client", NULL); 2011 return (result); 2012 } 2013#if NMCTXS > 0 2014 nextmctx = manager->nextmctx++; 2015 if (manager->nextmctx == NMCTXS) 2016 manager->nextmctx = 0; 2017 2018 INSIST(nextmctx < NMCTXS); 2019 2020 clientmctx = manager->mctxpool[nextmctx]; 2021 if (clientmctx == NULL) { 2022 result = isc_mem_create(0, 0, &clientmctx); 2023 if (result != ISC_R_SUCCESS) 2024 return (result); 2025 isc_mem_setname(clientmctx, "client", NULL); 2026 2027 manager->mctxpool[nextmctx] = clientmctx; 2028 } 2029#else 2030 clientmctx = manager->mctx; 2031#endif 2032 2033 isc_mem_attach(clientmctx, mctxp); 2034 2035 return (ISC_R_SUCCESS); 2036} 2037 2038static isc_result_t 2039client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { 2040 ns_client_t *client; 2041 isc_result_t result; 2042 isc_mem_t *mctx = NULL; 2043 2044 /* 2045 * Caller must be holding the manager lock. 2046 * 2047 * Note: creating a client does not add the client to the 2048 * manager's client list or set the client's manager pointer. 2049 * The caller is responsible for that. 2050 */ 2051 2052 REQUIRE(clientp != NULL && *clientp == NULL); 2053 2054 result = get_clientmctx(manager, &mctx); 2055 if (result != ISC_R_SUCCESS) 2056 return (result); 2057 2058 client = isc_mem_get(mctx, sizeof(*client)); 2059 if (client == NULL) { 2060 isc_mem_detach(&mctx); 2061 return (ISC_R_NOMEMORY); 2062 } 2063 client->mctx = mctx; 2064 2065 client->task = NULL; 2066 result = isc_task_create(manager->taskmgr, 0, &client->task); 2067 if (result != ISC_R_SUCCESS) 2068 goto cleanup_client; 2069 isc_task_setname(client->task, "client", client); 2070 2071 client->timer = NULL; 2072 result = isc_timer_create(manager->timermgr, isc_timertype_inactive, 2073 NULL, NULL, client->task, client_timeout, 2074 client, &client->timer); 2075 if (result != ISC_R_SUCCESS) 2076 goto cleanup_task; 2077 client->timerset = ISC_FALSE; 2078 2079 client->message = NULL; 2080 result = dns_message_create(client->mctx, DNS_MESSAGE_INTENTPARSE, 2081 &client->message); 2082 if (result != ISC_R_SUCCESS) 2083 goto cleanup_timer; 2084 2085 /* XXXRTH Hardwired constants */ 2086 2087 client->sendevent = (isc_socketevent_t *) 2088 isc_event_allocate(client->mctx, client, 2089 ISC_SOCKEVENT_SENDDONE, 2090 client_senddone, client, 2091 sizeof(isc_socketevent_t)); 2092 if (client->sendevent == NULL) { 2093 result = ISC_R_NOMEMORY; 2094 goto cleanup_message; 2095 } 2096 2097 client->recvbuf = isc_mem_get(client->mctx, RECV_BUFFER_SIZE); 2098 if (client->recvbuf == NULL) { 2099 result = ISC_R_NOMEMORY; 2100 goto cleanup_sendevent; 2101 } 2102 2103 client->recvevent = (isc_socketevent_t *) 2104 isc_event_allocate(client->mctx, client, 2105 ISC_SOCKEVENT_RECVDONE, 2106 client_request, client, 2107 sizeof(isc_socketevent_t)); 2108 if (client->recvevent == NULL) { 2109 result = ISC_R_NOMEMORY; 2110 goto cleanup_recvbuf; 2111 } 2112 2113 client->magic = NS_CLIENT_MAGIC; 2114 client->manager = NULL; 2115 client->state = NS_CLIENTSTATE_INACTIVE; 2116 client->newstate = NS_CLIENTSTATE_MAX; 2117 client->naccepts = 0; 2118 client->nreads = 0; 2119 client->nsends = 0; 2120 client->nrecvs = 0; 2121 client->nupdates = 0; 2122 client->nctls = 0; 2123 client->references = 0; 2124 client->attributes = 0; 2125 client->view = NULL; 2126 client->dispatch = NULL; 2127 client->udpsocket = NULL; 2128 client->tcplistener = NULL; 2129 client->tcpsocket = NULL; 2130 client->tcpmsg_valid = ISC_FALSE; 2131 client->tcpbuf = NULL; 2132 client->opt = NULL; 2133 client->udpsize = 512; 2134 client->extflags = 0; 2135 client->ednsversion = -1; 2136 client->next = NULL; 2137 client->shutdown = NULL; 2138 client->shutdown_arg = NULL; 2139 client->signer = NULL; 2140 dns_name_init(&client->signername, NULL); 2141 client->mortal = ISC_FALSE; 2142 client->tcpquota = NULL; 2143 client->recursionquota = NULL; 2144 client->interface = NULL; 2145 client->peeraddr_valid = ISC_FALSE; 2146#ifdef ALLOW_FILTER_AAAA_ON_V4 2147 client->filter_aaaa = dns_v4_aaaa_ok; 2148#endif 2149 client->needshutdown = ns_g_clienttest; 2150 2151 ISC_EVENT_INIT(&client->ctlevent, sizeof(client->ctlevent), 0, NULL, 2152 NS_EVENT_CLIENTCONTROL, client_start, client, client, 2153 NULL, NULL); 2154 /* 2155 * Initialize FORMERR cache to sentinel value that will not match 2156 * any actual FORMERR response. 2157 */ 2158 isc_sockaddr_any(&client->formerrcache.addr); 2159 client->formerrcache.time = 0; 2160 client->formerrcache.id = 0; 2161 ISC_LINK_INIT(client, link); 2162 ISC_LINK_INIT(client, rlink); 2163 ISC_QLINK_INIT(client, ilink); 2164 2165 /* 2166 * We call the init routines for the various kinds of client here, 2167 * after we have created an otherwise valid client, because some 2168 * of them call routines that REQUIRE(NS_CLIENT_VALID(client)). 2169 */ 2170 result = ns_query_init(client); 2171 if (result != ISC_R_SUCCESS) 2172 goto cleanup_recvevent; 2173 2174 result = isc_task_onshutdown(client->task, client_shutdown, client); 2175 if (result != ISC_R_SUCCESS) 2176 goto cleanup_query; 2177 2178 CTRACE("create"); 2179 2180 *clientp = client; 2181 2182 return (ISC_R_SUCCESS); 2183 2184 cleanup_query: 2185 ns_query_free(client); 2186 2187 cleanup_recvevent: 2188 isc_event_free((isc_event_t **)&client->recvevent); 2189 2190 cleanup_recvbuf: 2191 isc_mem_put(client->mctx, client->recvbuf, RECV_BUFFER_SIZE); 2192 2193 cleanup_sendevent: 2194 isc_event_free((isc_event_t **)&client->sendevent); 2195 2196 client->magic = 0; 2197 2198 cleanup_message: 2199 dns_message_destroy(&client->message); 2200 2201 cleanup_timer: 2202 isc_timer_detach(&client->timer); 2203 2204 cleanup_task: 2205 isc_task_detach(&client->task); 2206 2207 cleanup_client: 2208 isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); 2209 2210 return (result); 2211} 2212 2213static void 2214client_read(ns_client_t *client) { 2215 isc_result_t result; 2216 2217 CTRACE("read"); 2218 2219 result = dns_tcpmsg_readmessage(&client->tcpmsg, client->task, 2220 client_request, client); 2221 if (result != ISC_R_SUCCESS) 2222 goto fail; 2223 2224 /* 2225 * Set a timeout to limit the amount of time we will wait 2226 * for a request on this TCP connection. 2227 */ 2228 ns_client_settimeout(client, 30); 2229 2230 client->state = client->newstate = NS_CLIENTSTATE_READING; 2231 INSIST(client->nreads == 0); 2232 INSIST(client->recursionquota == NULL); 2233 client->nreads++; 2234 2235 return; 2236 fail: 2237 ns_client_next(client, result); 2238} 2239 2240static void 2241client_newconn(isc_task_t *task, isc_event_t *event) { 2242 ns_client_t *client = event->ev_arg; 2243 isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event; 2244 isc_result_t result; 2245 2246 REQUIRE(event->ev_type == ISC_SOCKEVENT_NEWCONN); 2247 REQUIRE(NS_CLIENT_VALID(client)); 2248 REQUIRE(client->task == task); 2249 2250 UNUSED(task); 2251 2252 INSIST(client->state == NS_CLIENTSTATE_READY); 2253 2254 INSIST(client->naccepts == 1); 2255 client->naccepts--; 2256 2257 LOCK(&client->interface->lock); 2258 INSIST(client->interface->ntcpcurrent > 0); 2259 client->interface->ntcpcurrent--; 2260 UNLOCK(&client->interface->lock); 2261 2262 /* 2263 * We must take ownership of the new socket before the exit 2264 * check to make sure it gets destroyed if we decide to exit. 2265 */ 2266 if (nevent->result == ISC_R_SUCCESS) { 2267 client->tcpsocket = nevent->newsocket; 2268 isc_socket_setname(client->tcpsocket, "client-tcp", NULL); 2269 client->state = NS_CLIENTSTATE_READING; 2270 INSIST(client->recursionquota == NULL); 2271 2272 (void)isc_socket_getpeername(client->tcpsocket, 2273 &client->peeraddr); 2274 client->peeraddr_valid = ISC_TRUE; 2275 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 2276 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 2277 "new TCP connection"); 2278 } else { 2279 /* 2280 * XXXRTH What should we do? We're trying to accept but 2281 * it didn't work. If we just give up, then TCP 2282 * service may eventually stop. 2283 * 2284 * For now, we just go idle. 2285 * 2286 * Going idle is probably the right thing if the 2287 * I/O was canceled. 2288 */ 2289 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 2290 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 2291 "accept failed: %s", 2292 isc_result_totext(nevent->result)); 2293 } 2294 2295 if (exit_check(client)) 2296 goto freeevent; 2297 2298 if (nevent->result == ISC_R_SUCCESS) { 2299 int match; 2300 isc_netaddr_t netaddr; 2301 2302 isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr); 2303 2304 if (ns_g_server->blackholeacl != NULL && 2305 dns_acl_match(&netaddr, NULL, 2306 ns_g_server->blackholeacl, 2307 &ns_g_server->aclenv, 2308 &match, NULL) == ISC_R_SUCCESS && 2309 match > 0) 2310 { 2311 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 2312 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 2313 "blackholed connection attempt"); 2314 client->newstate = NS_CLIENTSTATE_READY; 2315 (void)exit_check(client); 2316 goto freeevent; 2317 } 2318 2319 INSIST(client->tcpmsg_valid == ISC_FALSE); 2320 dns_tcpmsg_init(client->mctx, client->tcpsocket, 2321 &client->tcpmsg); 2322 client->tcpmsg_valid = ISC_TRUE; 2323 2324 /* 2325 * Let a new client take our place immediately, before 2326 * we wait for a request packet. If we don't, 2327 * telnetting to port 53 (once per CPU) will 2328 * deny service to legitimate TCP clients. 2329 */ 2330 result = isc_quota_attach(&ns_g_server->tcpquota, 2331 &client->tcpquota); 2332 if (result == ISC_R_SUCCESS) 2333 result = ns_client_replace(client); 2334 if (result != ISC_R_SUCCESS) { 2335 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 2336 NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, 2337 "no more TCP clients: %s", 2338 isc_result_totext(result)); 2339 } 2340 2341 client_read(client); 2342 } 2343 2344 freeevent: 2345 isc_event_free(&event); 2346} 2347 2348static void 2349client_accept(ns_client_t *client) { 2350 isc_result_t result; 2351 2352 CTRACE("accept"); 2353 2354 result = isc_socket_accept(client->tcplistener, client->task, 2355 client_newconn, client); 2356 if (result != ISC_R_SUCCESS) { 2357 UNEXPECTED_ERROR(__FILE__, __LINE__, 2358 "isc_socket_accept() failed: %s", 2359 isc_result_totext(result)); 2360 /* 2361 * XXXRTH What should we do? We're trying to accept but 2362 * it didn't work. If we just give up, then TCP 2363 * service may eventually stop. 2364 * 2365 * For now, we just go idle. 2366 */ 2367 return; 2368 } 2369 INSIST(client->naccepts == 0); 2370 client->naccepts++; 2371 LOCK(&client->interface->lock); 2372 client->interface->ntcpcurrent++; 2373 UNLOCK(&client->interface->lock); 2374} 2375 2376static void 2377client_udprecv(ns_client_t *client) { 2378 isc_result_t result; 2379 isc_region_t r; 2380 2381 CTRACE("udprecv"); 2382 2383 r.base = client->recvbuf; 2384 r.length = RECV_BUFFER_SIZE; 2385 result = isc_socket_recv2(client->udpsocket, &r, 1, 2386 client->task, client->recvevent, 0); 2387 if (result != ISC_R_SUCCESS) { 2388 UNEXPECTED_ERROR(__FILE__, __LINE__, 2389 "isc_socket_recv2() failed: %s", 2390 isc_result_totext(result)); 2391 /* 2392 * This cannot happen in the current implementation, since 2393 * isc_socket_recv2() cannot fail if flags == 0. 2394 * 2395 * If this does fail, we just go idle. 2396 */ 2397 return; 2398 } 2399 INSIST(client->nrecvs == 0); 2400 client->nrecvs++; 2401} 2402 2403void 2404ns_client_attach(ns_client_t *source, ns_client_t **targetp) { 2405 REQUIRE(NS_CLIENT_VALID(source)); 2406 REQUIRE(targetp != NULL && *targetp == NULL); 2407 2408 source->references++; 2409 ns_client_log(source, NS_LOGCATEGORY_CLIENT, 2410 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 2411 "ns_client_attach: ref = %d", source->references); 2412 *targetp = source; 2413} 2414 2415void 2416ns_client_detach(ns_client_t **clientp) { 2417 ns_client_t *client = *clientp; 2418 2419 client->references--; 2420 INSIST(client->references >= 0); 2421 *clientp = NULL; 2422 ns_client_log(client, NS_LOGCATEGORY_CLIENT, 2423 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10), 2424 "ns_client_detach: ref = %d", client->references); 2425 (void)exit_check(client); 2426} 2427 2428isc_boolean_t 2429ns_client_shuttingdown(ns_client_t *client) { 2430 return (ISC_TF(client->newstate == NS_CLIENTSTATE_FREED)); 2431} 2432 2433isc_result_t 2434ns_client_replace(ns_client_t *client) { 2435 isc_result_t result; 2436 2437 CTRACE("replace"); 2438 2439 REQUIRE(client != NULL); 2440 REQUIRE(client->manager != NULL); 2441 2442 result = get_client(client->manager, client->interface, 2443 client->dispatch, TCP_CLIENT(client)); 2444 if (result != ISC_R_SUCCESS) 2445 return (result); 2446 2447 /* 2448 * The responsibility for listening for new requests is hereby 2449 * transferred to the new client. Therefore, the old client 2450 * should refrain from listening for any more requests. 2451 */ 2452 client->mortal = ISC_TRUE; 2453 2454 return (ISC_R_SUCCESS); 2455} 2456 2457/*** 2458 *** Client Manager 2459 ***/ 2460 2461static void 2462clientmgr_destroy(ns_clientmgr_t *manager) { 2463#if NMCTXS > 0 2464 int i; 2465#endif 2466 2467 REQUIRE(ISC_LIST_EMPTY(manager->clients)); 2468 2469 MTRACE("clientmgr_destroy"); 2470 2471#if NMCTXS > 0 2472 for (i = 0; i < NMCTXS; i++) { 2473 if (manager->mctxpool[i] != NULL) 2474 isc_mem_detach(&manager->mctxpool[i]); 2475 } 2476#endif 2477 2478 ISC_QUEUE_DESTROY(manager->inactive); 2479 DESTROYLOCK(&manager->lock); 2480 DESTROYLOCK(&manager->listlock); 2481 DESTROYLOCK(&manager->reclock); 2482 manager->magic = 0; 2483 isc_mem_put(manager->mctx, manager, sizeof(*manager)); 2484} 2485 2486isc_result_t 2487ns_clientmgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, 2488 isc_timermgr_t *timermgr, ns_clientmgr_t **managerp) 2489{ 2490 ns_clientmgr_t *manager; 2491 isc_result_t result; 2492#if NMCTXS > 0 2493 int i; 2494#endif 2495 2496 manager = isc_mem_get(mctx, sizeof(*manager)); 2497 if (manager == NULL) 2498 return (ISC_R_NOMEMORY); 2499 2500 result = isc_mutex_init(&manager->lock); 2501 if (result != ISC_R_SUCCESS) 2502 goto cleanup_manager; 2503 2504 result = isc_mutex_init(&manager->listlock); 2505 if (result != ISC_R_SUCCESS) 2506 goto cleanup_lock; 2507 2508 result = isc_mutex_init(&manager->reclock); 2509 if (result != ISC_R_SUCCESS) 2510 goto cleanup_listlock; 2511 2512 manager->mctx = mctx; 2513 manager->taskmgr = taskmgr; 2514 manager->timermgr = timermgr; 2515 manager->exiting = ISC_FALSE; 2516 ISC_LIST_INIT(manager->clients); 2517 ISC_LIST_INIT(manager->recursing); 2518 ISC_QUEUE_INIT(manager->inactive, ilink); 2519#if NMCTXS > 0 2520 manager->nextmctx = 0; 2521 for (i = 0; i < NMCTXS; i++) 2522 manager->mctxpool[i] = NULL; /* will be created on-demand */ 2523#endif 2524 manager->magic = MANAGER_MAGIC; 2525 2526 MTRACE("create"); 2527 2528 *managerp = manager; 2529 2530 return (ISC_R_SUCCESS); 2531 2532 cleanup_listlock: 2533 (void) isc_mutex_destroy(&manager->listlock); 2534 2535 cleanup_lock: 2536 (void) isc_mutex_destroy(&manager->lock); 2537 2538 cleanup_manager: 2539 isc_mem_put(manager->mctx, manager, sizeof(*manager)); 2540 2541 return (result); 2542} 2543 2544void 2545ns_clientmgr_destroy(ns_clientmgr_t **managerp) { 2546 isc_result_t result; 2547 ns_clientmgr_t *manager; 2548 ns_client_t *client; 2549 isc_boolean_t need_destroy = ISC_FALSE, unlock = ISC_FALSE; 2550 2551 REQUIRE(managerp != NULL); 2552 manager = *managerp; 2553 REQUIRE(VALID_MANAGER(manager)); 2554 2555 MTRACE("destroy"); 2556 2557 /* 2558 * Check for success because we may already be task-exclusive 2559 * at this point. Only if we succeed at obtaining an exclusive 2560 * lock now will we need to relinquish it later. 2561 */ 2562 result = isc_task_beginexclusive(ns_g_server->task); 2563 if (result == ISC_R_SUCCESS) 2564 unlock = ISC_TRUE; 2565 2566 manager->exiting = ISC_TRUE; 2567 2568 for (client = ISC_LIST_HEAD(manager->clients); 2569 client != NULL; 2570 client = ISC_LIST_NEXT(client, link)) 2571 isc_task_shutdown(client->task); 2572 2573 if (ISC_LIST_EMPTY(manager->clients)) 2574 need_destroy = ISC_TRUE; 2575 2576 if (unlock) 2577 isc_task_endexclusive(ns_g_server->task); 2578 2579 if (need_destroy) 2580 clientmgr_destroy(manager); 2581 2582 *managerp = NULL; 2583} 2584 2585static isc_result_t 2586get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, 2587 dns_dispatch_t *disp, isc_boolean_t tcp) 2588{ 2589 isc_result_t result = ISC_R_SUCCESS; 2590 isc_event_t *ev; 2591 ns_client_t *client; 2592 MTRACE("get client"); 2593 2594 REQUIRE(manager != NULL); 2595 2596 if (manager->exiting) 2597 return (ISC_R_SHUTTINGDOWN); 2598 2599 /* 2600 * Allocate a client. First try to get a recycled one; 2601 * if that fails, make a new one. 2602 */ 2603 client = NULL; 2604 if (!ns_g_clienttest) 2605 ISC_QUEUE_POP(manager->inactive, ilink, client); 2606 2607 if (client != NULL) 2608 MTRACE("recycle"); 2609 else { 2610 MTRACE("create new"); 2611 2612 LOCK(&manager->lock); 2613 result = client_create(manager, &client); 2614 UNLOCK(&manager->lock); 2615 if (result != ISC_R_SUCCESS) 2616 return (result); 2617 2618 LOCK(&manager->listlock); 2619 ISC_LIST_APPEND(manager->clients, client, link); 2620 UNLOCK(&manager->listlock); 2621 } 2622 2623 client->manager = manager; 2624 ns_interface_attach(ifp, &client->interface); 2625 client->state = NS_CLIENTSTATE_READY; 2626 INSIST(client->recursionquota == NULL); 2627 2628 if (tcp) { 2629 client->attributes |= NS_CLIENTATTR_TCP; 2630 isc_socket_attach(ifp->tcpsocket, 2631 &client->tcplistener); 2632 } else { 2633 isc_socket_t *sock; 2634 2635 dns_dispatch_attach(disp, &client->dispatch); 2636 sock = dns_dispatch_getsocket(client->dispatch); 2637 isc_socket_attach(sock, &client->udpsocket); 2638 } 2639 2640 INSIST(client->nctls == 0); 2641 client->nctls++; 2642 ev = &client->ctlevent; 2643 isc_task_send(client->task, &ev); 2644 2645 return (ISC_R_SUCCESS); 2646} 2647 2648isc_result_t 2649ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, 2650 ns_interface_t *ifp, isc_boolean_t tcp) 2651{ 2652 isc_result_t result = ISC_R_SUCCESS; 2653 unsigned int disp; 2654 2655 REQUIRE(VALID_MANAGER(manager)); 2656 REQUIRE(n > 0); 2657 2658 MTRACE("createclients"); 2659 2660 for (disp = 0; disp < n; disp++) { 2661 result = get_client(manager, ifp, ifp->udpdispatch[disp], tcp); 2662 if (result != ISC_R_SUCCESS) 2663 break; 2664 } 2665 2666 return (result); 2667} 2668 2669isc_sockaddr_t * 2670ns_client_getsockaddr(ns_client_t *client) { 2671 return (&client->peeraddr); 2672} 2673 2674isc_result_t 2675ns_client_checkaclsilent(ns_client_t *client, isc_netaddr_t *netaddr, 2676 dns_acl_t *acl, isc_boolean_t default_allow) 2677{ 2678 isc_result_t result; 2679 isc_netaddr_t tmpnetaddr; 2680 int match; 2681 2682 if (acl == NULL) { 2683 if (default_allow) 2684 goto allow; 2685 else 2686 goto deny; 2687 } 2688 2689 if (netaddr == NULL) { 2690 isc_netaddr_fromsockaddr(&tmpnetaddr, &client->peeraddr); 2691 netaddr = &tmpnetaddr; 2692 } 2693 2694 result = dns_acl_match(netaddr, client->signer, acl, 2695 &ns_g_server->aclenv, &match, NULL); 2696 2697 if (result != ISC_R_SUCCESS) 2698 goto deny; /* Internal error, already logged. */ 2699 if (match > 0) 2700 goto allow; 2701 goto deny; /* Negative match or no match. */ 2702 2703 allow: 2704 return (ISC_R_SUCCESS); 2705 2706 deny: 2707 return (DNS_R_REFUSED); 2708} 2709 2710isc_result_t 2711ns_client_checkacl(ns_client_t *client, isc_sockaddr_t *sockaddr, 2712 const char *opname, dns_acl_t *acl, 2713 isc_boolean_t default_allow, int log_level) 2714{ 2715 isc_result_t result; 2716 isc_netaddr_t netaddr; 2717 2718 if (sockaddr != NULL) 2719 isc_netaddr_fromsockaddr(&netaddr, sockaddr); 2720 2721 result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL, 2722 acl, default_allow); 2723 2724 if (result == ISC_R_SUCCESS) 2725 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 2726 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), 2727 "%s approved", opname); 2728 else 2729 ns_client_log(client, DNS_LOGCATEGORY_SECURITY, 2730 NS_LOGMODULE_CLIENT, 2731 log_level, "%s denied", opname); 2732 return (result); 2733} 2734 2735static void 2736ns_client_name(ns_client_t *client, char *peerbuf, size_t len) { 2737 if (client->peeraddr_valid) 2738 isc_sockaddr_format(&client->peeraddr, peerbuf, 2739 (unsigned int)len); 2740 else 2741 snprintf(peerbuf, len, "@%p", client); 2742} 2743 2744void 2745ns_client_logv(ns_client_t *client, isc_logcategory_t *category, 2746 isc_logmodule_t *module, int level, const char *fmt, va_list ap) 2747{ 2748 char msgbuf[2048]; 2749 char peerbuf[ISC_SOCKADDR_FORMATSIZE]; 2750 char signerbuf[DNS_NAME_FORMATSIZE], qnamebuf[DNS_NAME_FORMATSIZE]; 2751 const char *viewname = ""; 2752 const char *sep1 = "", *sep2 = "", *sep3 = "", *sep4 = ""; 2753 const char *signer = "", *qname = ""; 2754 dns_name_t *q = NULL; 2755 2756 vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); 2757 2758 ns_client_name(client, peerbuf, sizeof(peerbuf)); 2759 2760 if (client->signer != NULL) { 2761 dns_name_format(client->signer, signerbuf, sizeof(signerbuf)); 2762 sep1 = "/key "; 2763 signer = signerbuf; 2764 } 2765 2766 q = client->query.origqname != NULL 2767 ? client->query.origqname : client->query.qname; 2768 if (q != NULL) { 2769 dns_name_format(q, qnamebuf, sizeof(qnamebuf)); 2770 sep2 = " ("; 2771 sep3 = ")"; 2772 qname = qnamebuf; 2773 } 2774 2775 if (client->view != NULL && strcmp(client->view->name, "_bind") != 0 && 2776 strcmp(client->view->name, "_default") != 0) { 2777 sep4 = ": view "; 2778 viewname = client->view->name; 2779 } 2780 2781 isc_log_write(ns_g_lctx, category, module, level, 2782 "client %s%s%s%s%s%s%s%s: %s", 2783 peerbuf, sep1, signer, sep2, qname, sep3, 2784 sep4, viewname, msgbuf); 2785} 2786 2787void 2788ns_client_log(ns_client_t *client, isc_logcategory_t *category, 2789 isc_logmodule_t *module, int level, const char *fmt, ...) 2790{ 2791 va_list ap; 2792 2793 if (! isc_log_wouldlog(ns_g_lctx, level)) 2794 return; 2795 2796 va_start(ap, fmt); 2797 ns_client_logv(client, category, module, level, fmt, ap); 2798 va_end(ap); 2799} 2800 2801void 2802ns_client_aclmsg(const char *msg, dns_name_t *name, dns_rdatatype_t type, 2803 dns_rdataclass_t rdclass, char *buf, size_t len) 2804{ 2805 char namebuf[DNS_NAME_FORMATSIZE]; 2806 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2807 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 2808 2809 dns_name_format(name, namebuf, sizeof(namebuf)); 2810 dns_rdatatype_format(type, typebuf, sizeof(typebuf)); 2811 dns_rdataclass_format(rdclass, classbuf, sizeof(classbuf)); 2812 (void)snprintf(buf, len, "%s '%s/%s/%s'", msg, namebuf, typebuf, 2813 classbuf); 2814} 2815 2816static void 2817ns_client_dumpmessage(ns_client_t *client, const char *reason) { 2818 isc_buffer_t buffer; 2819 char *buf = NULL; 2820 int len = 1024; 2821 isc_result_t result; 2822 2823 /* 2824 * Note that these are multiline debug messages. We want a newline 2825 * to appear in the log after each message. 2826 */ 2827 2828 do { 2829 buf = isc_mem_get(client->mctx, len); 2830 if (buf == NULL) 2831 break; 2832 isc_buffer_init(&buffer, buf, len); 2833 result = dns_message_totext(client->message, 2834 &dns_master_style_debug, 2835 0, &buffer); 2836 if (result == ISC_R_NOSPACE) { 2837 isc_mem_put(client->mctx, buf, len); 2838 len += 1024; 2839 } else if (result == ISC_R_SUCCESS) 2840 ns_client_log(client, NS_LOGCATEGORY_UNMATCHED, 2841 NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1), 2842 "%s\n%.*s", reason, 2843 (int)isc_buffer_usedlength(&buffer), 2844 buf); 2845 } while (result == ISC_R_NOSPACE); 2846 2847 if (buf != NULL) 2848 isc_mem_put(client->mctx, buf, len); 2849} 2850 2851void 2852ns_client_dumprecursing(FILE *f, ns_clientmgr_t *manager) { 2853 ns_client_t *client; 2854 char namebuf[DNS_NAME_FORMATSIZE]; 2855 char original[DNS_NAME_FORMATSIZE]; 2856 char peerbuf[ISC_SOCKADDR_FORMATSIZE]; 2857 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 2858 char classbuf[DNS_RDATACLASS_FORMATSIZE]; 2859 const char *name; 2860 const char *sep; 2861 const char *origfor; 2862 dns_rdataset_t *rdataset; 2863 2864 REQUIRE(VALID_MANAGER(manager)); 2865 2866 LOCK(&manager->reclock); 2867 client = ISC_LIST_HEAD(manager->recursing); 2868 while (client != NULL) { 2869 INSIST(client->state == NS_CLIENTSTATE_RECURSING); 2870 2871 ns_client_name(client, peerbuf, sizeof(peerbuf)); 2872 if (client->view != NULL && 2873 strcmp(client->view->name, "_bind") != 0 && 2874 strcmp(client->view->name, "_default") != 0) { 2875 name = client->view->name; 2876 sep = ": view "; 2877 } else { 2878 name = ""; 2879 sep = ""; 2880 } 2881 2882 LOCK(&client->query.fetchlock); 2883 INSIST(client->query.qname != NULL); 2884 dns_name_format(client->query.qname, namebuf, sizeof(namebuf)); 2885 if (client->query.qname != client->query.origqname && 2886 client->query.origqname != NULL) { 2887 origfor = " for "; 2888 dns_name_format(client->query.origqname, original, 2889 sizeof(original)); 2890 } else { 2891 origfor = ""; 2892 original[0] = '\0'; 2893 } 2894 rdataset = ISC_LIST_HEAD(client->query.qname->list); 2895 if (rdataset == NULL && client->query.origqname != NULL) 2896 rdataset = ISC_LIST_HEAD(client->query.origqname->list); 2897 if (rdataset != NULL) { 2898 dns_rdatatype_format(rdataset->type, typebuf, 2899 sizeof(typebuf)); 2900 dns_rdataclass_format(rdataset->rdclass, classbuf, 2901 sizeof(classbuf)); 2902 } else { 2903 strcpy(typebuf, "-"); 2904 strcpy(classbuf, "-"); 2905 } 2906 UNLOCK(&client->query.fetchlock); 2907 fprintf(f, "; client %s%s%s: id %u '%s/%s/%s'%s%s " 2908 "requesttime %d\n", peerbuf, sep, name, 2909 client->message->id, namebuf, typebuf, classbuf, 2910 origfor, original, client->requesttime); 2911 client = ISC_LIST_NEXT(client, rlink); 2912 } 2913 UNLOCK(&manager->reclock); 2914} 2915 2916void 2917ns_client_qnamereplace(ns_client_t *client, dns_name_t *name) { 2918 LOCK(&client->query.fetchlock); 2919 if (client->query.restarts > 0) { 2920 /* 2921 * client->query.qname was dynamically allocated. 2922 */ 2923 dns_message_puttempname(client->message, 2924 &client->query.qname); 2925 } 2926 client->query.qname = name; 2927 UNLOCK(&client->query.fetchlock); 2928} 2929 2930isc_result_t 2931ns_client_sourceip(dns_clientinfo_t *ci, isc_sockaddr_t **addrp) { 2932 ns_client_t *client = (ns_client_t *) ci->data; 2933 2934 REQUIRE(NS_CLIENT_VALID(client)); 2935 REQUIRE(addrp != NULL); 2936 2937 *addrp = &client->peeraddr; 2938 return (ISC_R_SUCCESS); 2939} 2940